.. This file is auto-generated by the Sphinx pre-build hook in
   ``documentation/source/conf.py`` from
   ``documentation/source/_data/patcher_objects.json`` and the notes in
   ``documentation/source/_data/patcher_notes/``.
   Do not edit by hand — re-run ``python yse.py dump-patcher-meta`` to
   refresh the JSON, then ``make html`` to re-render this page.

GUI controls
============

User-facing controls and message boxes, driven by the GUI value protocol.

25 objects. Every entry is
pulled directly from the engine source via the ``ADD_DESCRIPTION`` /
``INLET_DOC`` / ``OUTLET_DOC`` / ``PARAM_DOC`` macros (see
:file:`YseEngine/patcher/pObject.h`). The ``~`` prefix marks DSP /
audio-rate objects; ``.`` marks control-rate objects.

.. contents::
   :local:
   :depth: 1

``.b``
------

A button. Any bang or number sends a bang and lights the button until the host next reads it.

:Kind: Control-rate

Every bang, int or float sends a bang, whatever the number.

The GUI value is ``on`` once after a press and ``off`` otherwise. Reading it
clears the press, so poll it from one place only, or presses get lost. The
value cannot be written back, and ``.preset`` skips the button. For a
momentary control whose value can be saved, use ``.led momentary`` or
``.textbutton momentary``. See :doc:`/patcher/gui`.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - trigger
     - FLOAT, INT, BANG
     - —
     - A bang, int or float presses the button.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - BANG
     - —
     - A bang for every press.



``.dial``
---------

A knob with its own output range. It takes a position from 0 to 1 and sends it mapped onto minimum-maximum, optionally bent into a curve by an exponent and rounded to an int.

:Kind: Control-rate

The inlet takes the knob position from 0 to 1, as ``.slider`` does, and the
outlet sends that position mapped onto the range:

.. code-block:: text

   out = minimum + (maximum - minimum) * position ^ exponent

.. code-block:: text

   [.dial 20 20000 3]   0.5  =>  2517.5

An exponent above 1 gives finer control at the bottom of the range, which
suits a frequency or a gain; one below 1 does the opposite. The range may run
from high to low. When ``minimum`` equals ``maximum`` the dial sends
``minimum``, and a result that is not a finite number sends 0. With
``intMode`` set to 1 the result is rounded to the nearest whole number (a
half rounds away from 0) and sent as an int.

With the default arguments (0, 1, exponent 1, float) the dial behaves exactly
like ``.slider``.

The GUI value is the position, not the mapped value, so a host that displays
"440 Hz" needs the arguments as well. Restoring the value works as described
under ``.slider``.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - position
     - FLOAT, INT, BANG, LIST
     - 0.0-1.0
     - A number sets the knob position, clamped to 0-1, and sends the mapped value; a bang sends it again. Also takes its GUI value back, as a one-number list or 'set 0 <value>'.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - ANY
     - minimum-maximum
     - The position mapped onto the range.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - minimum
     - 0
     - any float
     - The value sent at position 0.
   * - maximum
     - 1
     - any float
     - The value sent at position 1.
   * - exponent
     - 1
     - any float
     - Curve of the mapping; 1 is a straight line.
   * - intMode
     - 0
     - 0 or 1
     - 1 rounds the result and sends an int; 0 sends a float.


``.f``
------

A float number box. A number on the left inlet stores it and sends it, a bang sends it again, and the right inlet stores a number without sending it.

:Kind: Control-rate

The right inlet stores a number without sending it; send a bang to the left
inlet to send it later. An int becomes a float. Restoring the value works as
described under ``.slider``.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - set/bang
     - FLOAT, INT, BANG, LIST
     - any float
     - A number sets the value and sends it; a bang sends it again. Also takes its GUI value back, as a one-number list or 'set 0 <value>'.
   * - 1
     - silent set
     - FLOAT, INT
     - any float
     - Stores a number without sending it.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - FLOAT
     - any float
     - The value.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - value
     - 0
     - any float
     - The value the box starts with.


``.function``
-------------

A breakpoint function, for drawing envelopes and curves. It stores sorted (x, y, curve) points, answers an x with the y between them, and on a bang sends the whole shape as a ramp for .line or .bline. Its points are saved with the patch.

:Kind: Control-rate

A function holds up to ``points`` breakpoints. Each point has an x, a y and a
curve. The points are kept sorted by x, and there is one point per x.

- x is never below 0: a negative x is stored as 0.
- y is clamped to the range set by the arguments, 0 to 1 by default.
- The curve is clamped to -1 to 1.

**Messages**

- a number: the x to look up. The y at that x leaves the left outlet. Below
  the first point the first y is sent, past the last point the last y. An
  empty function sends nothing.
- bang: send the whole function from the middle outlet (see below).
- ``<x> <y>``: add a point with curve 0. A point already at that x is
  replaced.
- three numbers per point, ``<x> <y> <curve> ...``: replace every point.
- ``set <index> <x> <y> [<curve>]``: rewrite the point at that position,
  counted from 0 in x order. Without a curve it keeps its curve. The point
  moves to its new place in the order.
- ``setcurve <index> <curve>``: change one point's curve.
- ``nth <index>``: send that point's y from the left outlet.
- ``clear``: remove every point. ``clear <index>``: remove one.
- ``dump``: send every point from the right outlet as
  ``<index> <x> <y> <curve>``, in x order.

Edits send nothing, so drawing into a function that feeds a ``.line`` does
not restart the ramp. A list of any other length is ignored. When the
function is full, a new point is ignored.

**Curves**

A segment is shaped by the curve of the point at its right end; the first
point's curve is not used. Between two points, at a fraction ``t`` of the way
along, the y moves by ``t ^ ((1 + c) / (1 - c))`` of the distance. A curve of
0 is a straight line. A positive curve leaves the first value slowly and
moves late; a negative one moves early and arrives slowly. A curve of 1
holds the first value until the end of the segment, and -1 jumps at once.

**The ramp**

A bang sends the function as ``<y> <time>`` pairs, the form ``.line`` and
``.bline`` read. The first time is 0, so the ramp jumps to the first y; each
later time is the distance in x from the point before.

.. code-block:: text

   [.function]   0 0,  100 1,  300 0.5,  bang  =>  0. 0. 1. 100. 0.5 200.
                 50  =>  0.5

The ramp is made of straight segments: curves only shape the values sent for
a looked-up x.

**Saving**

The points are saved with the patch and come back when it loads (see
:ref:`gui-saved`). The GUI value has one cell per point, ``<x> <y> <curve>``;
an empty function reports the word ``clear``. Writing that value back to the
inlet restores the points and sends nothing.

A message that arrives while another thread is changing the points is
ignored, and a GUI read at that moment comes back empty (see
:doc:`/patcher/gui`).

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - function
     - FLOAT, INT, BANG, LIST
     - x >= 0, y in minimum-maximum, curve -1 to 1
     - A number is an x and sends its y; a bang sends the ramp; '<x> <y>' adds a point; 3 numbers per point replace them all; 'set', 'setcurve', 'nth', 'clear' and 'dump' edit and query points. Edits send nothing.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - y
     - FLOAT
     - minimum-maximum
     - The y for an x arriving on the inlet, or for 'nth <index>'. Always a float.
   * - 1
     - ramp
     - LIST
     - target time pairs
     - On a bang, the whole function as '<y> <time>' pairs for .line or .bline: the first time is 0, each later one the distance in x from the point before.
   * - 2
     - dump
     - LIST
     - index x y curve
     - On 'dump', every point as '<index> <x> <y> <curve>', in x order.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - points
     - 128
     - 2-1024, optional minimum, optional maximum
     - How many points the function can hold, then optionally the lowest and highest y (default 0 and 1).


``.i``
------

An integer number box. A number on the left inlet stores it and sends it, a bang sends it again, and the right inlet stores a number without sending it. Floats are truncated.

:Kind: Control-rate

The right inlet stores a number without sending it; send a bang to the left
inlet to send it later. A float is truncated toward 0, so 2.9 is stored as 2.
Restoring the value works as described under ``.slider``.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - set/bang
     - FLOAT, INT, BANG, LIST
     - any int
     - A number sets the value and sends it; a bang sends it again. Also takes its GUI value back, as a one-number list or 'set 0 <value>'.
   * - 1
     - silent set
     - FLOAT, INT
     - any int
     - Stores a number without sending it.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - INT
     - any int
     - The value.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - value
     - 0
     - any int
     - The value the box starts with.


``.incdec``
-----------

A stepper over a whole number. 'inc' and 'dec', or a signed step count on the middle inlet, move the value inside a range that clamps or wraps; a number sets it without sending and a bang sends it.

:Kind: Control-rate

**Messages**

On the left inlet:

- bang: send the value without moving it.
- a number, or ``set <n>``: set the value without sending it. A float is
  truncated.
- ``inc`` / ``dec``: move one step up or down and send the result.

The middle inlet moves several steps at once: an int ``n`` moves ``n`` steps,
down when it is negative, and sends the result. A MIDI encoder that sends +1
and -1 can drive it directly. 0 moves nothing and just sends the value.

The right inlet sets the step size. A negative step makes ``inc`` go down, and
a step of 0 never moves the value.

**The range**

The value always stays between ``minimum`` and ``maximum``, given in either
order. With ``wrap`` 0 it stops at the ends. With ``wrap`` 1 it carries round
to the other end, and both ends are reachable, so one step past the maximum
is the minimum:

.. code-block:: text

   [.incdec 1 0 11 1]   at 11, inc  =>  0

Without arguments the range is the whole int range, and the value stops at
its ends instead of overflowing.

The value is kept inside the range even before anything moves it: an
``.incdec 1 60 72`` starts at 60. With ``wrap`` on, an untouched stepper
starts wherever 0 wraps to (65 for 60-72), so send ``set`` first when the
starting point matters.

The GUI value is the number. A one-number list or ``set 0 <value>`` sets it
without sending, so a restore is silent (see :doc:`/patcher/gui`).

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - value
     - FLOAT, INT, BANG, LIST
     - any int, 'inc', 'dec', 'set <n>'
     - A bang sends the value without moving it. A number, or 'set <n>', sets it without sending. 'inc' and 'dec' move one step up or down and send. Also takes its GUI value back, as a one-number list or 'set 0 <value>'.
   * - 1
     - nudge
     - FLOAT, INT, LIST
     - any int
     - An int n moves n steps (negative moves down) and sends the result; 0 just sends the value. A float is truncated.
   * - 2
     - step
     - FLOAT, INT, LIST
     - any int
     - Sets the step size. A negative step makes 'inc' go down. A float is truncated.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - INT
     - minimum-maximum
     - The value, whenever it moves or is read.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - step
     - 1
     - any int
     - How far one step moves the value; a negative step reverses 'inc' and 'dec'.
   * - minimum
     - -2147483648
     - any int
     - The bottom of the range.
   * - maximum
     - 2147483647
     - any int
     - The top of the range.
   * - wrap
     - 0
     - 0 or 1
     - 0 stops at the ends of the range; 1 wraps around to the other end.


``.kslider``
------------

A piano keyboard. A pitch on the left inlet presses that key at the stored velocity and sends velocity and pitch; velocity 0 releases it. The state is the velocity held on each of the 128 keys.

:Kind: Control-rate

The state is the keyboard: the velocity held on each of the 128 keys, with 0
for a key that is up.

**Messages**

On the left inlet:

- a pitch: press that key at the stored velocity.
- ``<pitch> <velocity>``: store the velocity, then play the pitch with it.
  Velocity 0 releases the key.
- ``set <pitch> <velocity>``: the same, but the stored velocity stays as it
  was.
- 128 numbers: set every key at once, and send a pair only for each key that
  changed.
- ``clear``: release every held key, sending velocity 0 for each.
- bang: send the pair for every held key, from low to high.

The right inlet stores the velocity for the pitches that follow. It sends
nothing.

A pitch outside 0-127 is ignored; a velocity is clamped to 0-127. A float is
truncated, and a list of any other length is ignored.

.. code-block:: text

   [.kslider]   60    =>  100, then 60
                60 0  =>  0, then 60

A single-key message sends even when the velocity has not changed, so playing
the same note twice sends two note-ons.

**Output**

The velocity is sent before the pitch, so the pair can be wired straight into
``.noteon``, ``.makenote`` or ``.flush``, which take the velocity on a cold
inlet. There is no mode that holds one note at a time.

The GUI value has 128 cells, one velocity per key. Held keys are not saved
with the patch; only the ``velocity`` argument is.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - pitch
     - FLOAT, INT, BANG, LIST
     - 0-127
     - A pitch presses that key at the stored velocity; '<pitch> <velocity>' plays it at that velocity, and velocity 0 releases it. Also 128 numbers (the whole keyboard), 'set <pitch> <velocity>', 'clear' and bang.
   * - 1
     - velocity
     - FLOAT, INT, LIST
     - 0-127
     - The velocity for pitches that arrive after it. Sends nothing. Clamped to 0-127; a float is truncated.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - pitch
     - INT
     - 0-127
     - The pitch of the key that moved. Sent after the velocity.
   * - 1
     - velocity
     - INT
     - 0-127
     - The key's new velocity: 0 for a release. Sent before the pitch, so it pairs with the pitch in the next object.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - velocity
     - 100
     - 0-127
     - The velocity a bare pitch is played at, until the right inlet or a '<pitch> <velocity>' list changes it.


``.l``
------

A list box. A bang sends the stored list; a list arriving on the inlet replaces it without sending it.

:Kind: Control-rate

Unlike ``.m``, the box always sends its text as a list, even when it is a
single number or starts with a word.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - trigger/set
     - BANG, LIST
     - —
     - A bang sends the stored list; a list replaces it silently.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - LIST
     - —
     - The stored list.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - message
     - —
     - any text
     - The list the box starts with.


``.led``
--------

A labelled on/off indicator. It latches by default (a number sets it, a bang flips it) or registers presses with the 'momentary' keyword, and sends its state and its label.

:Kind: Control-rate

``.led`` and ``.textbutton`` are the same object under two names. A host
draws ``.led`` as a lamp and ``.textbutton`` as a labelled button; they take
the same arguments and messages.

**Arguments**

An optional ``momentary`` keyword, then the label. The words of the label are
joined with single spaces, so ``.textbutton filter cutoff`` is one control
called "filter cutoff". A label cannot start with the word ``momentary``. The
label is fixed: changing the arguments replaces the object.

**Latching and momentary**

Without ``momentary`` the control latches: a number sets the state (0 off,
anything else on) and a bang flips it.

With ``momentary`` every number or bang is a press, whatever the number. The
state stays 1 until the host next reads the GUI value, which clears it. Poll
it from one place only.

In both modes, a one-number list or ``set 0 <value>`` sets the state
outright. In momentary mode that is the only way to clear a press without
reading it.

**Output**

Every message sends: the label from the right outlet first, then the state
from the left outlet. A control without a label sends an empty list. Wire a
bank of labelled controls into one ``.route`` and the label says which one
fired:

.. code-block:: text

   [.textbutton mute]   bang  =>  right: mute,  left: 1

A message starting with any other word changes nothing, and the state is
still sent. There is no message to change the label, and no way to set the
state without sending it.

The GUI value is ``0`` or ``1``. A host or ``.preset`` can write it back; in
momentary mode, restoring a value taken during a press replays the press
(see :doc:`/patcher/gui`).

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - state
     - FLOAT, INT, BANG, LIST
     - 0 or 1
     - Latching: a number sets the state (0 off, anything else on) and a bang flips it. Momentary: any number or bang is a press. In both modes a one-number list or 'set 0 <value>' sets the state outright. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - state
     - INT
     - 0 or 1
     - The state. Sent last.
   * - 1
     - label
     - LIST
     - the label, or empty
     - The label, so a bank of controls wired into one object can say which one fired. Empty when the control has no label. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - label
     - —
     - optional 'momentary', then any text
     - An optional 'momentary' keyword, then the label. The words of the label are joined with single spaces.


``.m``
------

A message box. A bang sends the stored text as the message it spells: a number, a bang, a list or a command. A message arriving on the inlet replaces the text without sending it.

:Kind: Control-rate

The text is sent as the message it spells:

.. code-block:: text

   [.m 440]       =>  the int 440
   [.m 0.5]       =>  the float 0.5
   [.m 1 2 3]     =>  a list
   [.m stop]      =>  the command stop, to objects that take one

A list, or text starting with a word, that arrives on the inlet replaces the
stored text without sending it. ``.l`` always sends its text as a list.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - trigger/set
     - BANG, LIST
     - —
     - A bang sends the stored message; a list or a word message replaces it silently.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - ANY
     - —
     - The stored message, as the message it spells: one number is an int or a float, the word 'bang' is a bang, a list starting with a number is a list, and text starting with any other word is a command to objects that take one ('stop' to '~line', 'allnotesoff' to '.midiout') and a list to every other object.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - message
     - —
     - any text
     - The text the box starts with.


``.matrixctrl``
---------------

A grid of cells, columns by rows, such as a step pattern or a routing patchbay. '<column> <row> <value>' sets a cell, and every change is sent in that same form, so the grid can drive .matrix or .router directly.

:Kind: Control-rate

**Arguments**

``columns rows minimum maximum``: each axis 1-256, default 8, and a cell
range of 0 to 1 by default. A count outside 1-256 is clamped with a warning.
Changing the arguments replaces the object, and every cell starts at 0 again.

**Messages**

The inlet takes lists and bangs only:

- ``<column> <row> <value>``: set that cell.
- one number per cell, ``columns * rows`` of them: set the whole grid.
- ``set <index> <value>``: set one cell by index, where the index of
  ``(column, row)`` is ``column * rows + row``.
- ``clear``: set every cell to 0 (or to the bound nearest 0).
- ``getrow <row>`` / ``getcolumn <column>``: send that row's or column's
  values from the right outlet as one list.
- bang: send every cell.

A cell outside the grid, or a list of any other length, is ignored. Values
are clamped to the range. On a grid of exactly three cells, a three-number
list sets the whole grid; use ``set`` to address one cell.

**Output**

Every change is sent from the left outlet as ``<column> <row> <value>``: one
list for a one-cell change, and one per cell, column by column, for a whole
grid, a ``clear`` or a bang. That is the form the control inlets of
``.matrix`` and ``.router`` take, so the grid can drive either directly.

.. code-block:: text

   [.matrixctrl 4 4]   2 1 1     =>  2 1 1.
                       set 9 1   =>  2 1 1.

The GUI value has one cell per grid cell, in index order. There is no mode
that allows only one active cell per row or column.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - grid
     - BANG, LIST
     - minimum-maximum
     - '<column> <row> <value>' sets one cell; a list of every cell sets the whole grid; 'set <index> <value>' sets one cell by index; 'clear', 'getrow <row>', 'getcolumn <column>' and bang. Lists and bangs only.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - cell
     - LIST
     - column row value
     - Changed cells as '<column> <row> <value>': one list per cell, ready for the control inlet of .matrix or .router.
   * - 1
     - line
     - LIST
     - minimum-maximum
     - One row's or one column's values as a list, in answer to 'getrow' or 'getcolumn'.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - columns
     - 8
     - 1-256, optional rows 1-256, optional minimum, optional maximum
     - The number of columns, then optionally the number of rows (default 8) and the lowest and highest value a cell can hold (default 0 and 1).


``.multislider``
----------------

A bank of sliders, such as the steps of a sequencer or the bands of an equaliser. A list sets the cells and the bank size, 'set <index> <value>' sets one cell, and every message sends the whole bank as a list.

:Kind: Control-rate

**Messages**

- a list: set the cells from its numbers, and make the bank as long as the
  list (up to 1024 cells).
- a number: set every cell to it.
- ``set <index> <value>``: set one cell.
- ``fetch <index>``: send that cell's value from the right outlet.
- bang: send the bank again.

Every message sends the whole bank from the left outlet, after a ``fetch``
answer. An index outside the bank is ignored, and every value is clamped to
the range.

**Size**

The ``size`` argument sets the starting number of cells, 1 to 1024. A list
of another length changes it. Shrinking hides the cells at the end rather
than clearing them, so lengthening the bank again brings their values back.

Changing the range takes effect at once: an untouched
``.multislider 4 20 20000`` reads back as four 20s. The values and the live
size are not saved with the patch. To sum, sort or scale the bank, process
the list it sends with ``.zl``.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - bank
     - FLOAT, INT, BANG, LIST
     - minimum-maximum
     - A list sets the cells and the bank size; a number sets every cell; 'set <index> <value>' sets one cell; 'fetch <index>' asks for one cell; a bang sends again. Everything here sends the bank.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - bank
     - LIST
     - minimum-maximum
     - The whole bank as one list, after every message.
   * - 1
     - cell
     - FLOAT
     - minimum-maximum
     - One cell's value, in answer to 'fetch <index>'. Sent before the bank.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - size
     - 8
     - 1-1024
     - How many cells the bank starts with. A list of another length changes it later.
   * - minimum
     - 0
     - any float
     - The lowest value a cell can hold.
   * - maximum
     - 127
     - any float
     - The highest value a cell can hold.


``.nodes``
----------

Blends between circular nodes in a 2D field. Move a cursor with 'x y' and it sends each node's distance and a weight that falls from 1 at the node's centre to 0 at its edge, scaled so the weights add up to 1.

:Kind: Control-rate

The field holds up to 64 nodes, each a circle with an x, a y and a radius. A
new ``.nodes 4`` has four nodes at 0 0 with radius 1.

**Messages**

- ``<x> <y>``: move the cursor and send.
- three or more numbers, ``<x> <y> <radius> ...``: set every node, and make
  the field as long as the number of complete triples. A partial triple at
  the end is ignored.
- ``set <index> <x> <y> [<radius>]``: move one node; without a radius it
  keeps its radius.
- bang: send again.

There is no int or float message: build the cursor pair with ``.pack 0. 0.``,
or wire in the right outlet of ``.xyslider``, which sends ``x y``.

**Output**

The right outlet sends the distance from the cursor to each node, then the
left outlet sends one weight per node. A node's closeness is 1 at its centre,
falls in a straight line to 0 at its edge, and is 0 outside it. Each weight
is that closeness divided by the sum over all nodes:

- inside at least one node the weights add up to 1, so a crossfade built on
  them keeps its level as the cursor moves;
- outside every node all weights are 0. There is no fallback to the nearest
  node.

A node with a radius of 0 or less never gets any weight, which mutes it
without deleting it.

.. code-block:: text

   [.nodes 2]   0 0 1  1 0 1,  then 0.5 0  =>  right: 0.5 0.5,  left: 0.5 0.5

The GUI value has one cell per node, ``<x> <y> <radius>``. Writing the whole
value back restores the number of nodes as well. Positions are not saved with
the patch; only the ``count`` argument is.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - field
     - BANG, LIST
     - any float
     - 'x y' moves the cursor; three or more numbers set every node as 'x y radius' triples; 'set <index> <x> <y> [<radius>]' moves one node; a bang sends again. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - weights
     - LIST
     - 0.0-1.0, summing to 1 or all 0
     - One weight per node, as a list. The weights add up to 1 while the cursor is inside at least one node, and are all 0 outside every node. Sent last.
   * - 1
     - distances
     - LIST
     - 0 and up
     - The distance from the cursor to each node, as a list. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - count
     - 4
     - 1-64
     - How many nodes the field starts with. A field list of another length changes it later.


``.nslider``
------------

A note on a staff: a pitch and how it is spelled. It sends the pitch and its accidental (1 sharp, -1 flat, 0 natural); a black key follows the 'spelling' argument unless a message chooses otherwise.

:Kind: Control-rate

The state is a pitch and how it is spelled. MIDI pitch 61 can be written as
C sharp or as D flat; the accidental says which, so a host knows the sign to
draw and, from ``pitch - accidental``, the line or space to draw it on.

**Spelling**

A white key is always natural (0). A black key is spelled with the accidental
the last message chose, or else by the ``spelling`` argument: 0 or above for
a sharp, below 0 for a flat. Only the sign of an accidental counts.

**Messages**

- a number: a pitch, spelled the default way again.
- ``<pitch> <accidental>``: a pitch with its spelling.
- ``set 0 <pitch>``: move the note and keep the chosen spelling.
- ``set 1 <accidental>``: re-spell the note without moving it.
- bang: send again.

The pitch is clamped to ``minimum``-``maximum`` (given in either order,
within 0-127). Every message sends the accidental from the right outlet,
then the pitch from the left.

.. code-block:: text

   [.nslider 0 127 -1]   61    =>  -1, then 61    (D flat)
                         61 1  =>  1, then 61     (C sharp)

A patch in a flat key sets ``spelling`` to -1 once, and a single note
re-spelled as a sharp does not change it. There is no empty state and no
chords: the staff always shows one note.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - note
     - FLOAT, INT, BANG, LIST
     - minimum-maximum
     - A number is a pitch, spelled the default way; '<pitch> <accidental>' chooses the spelling; 'set 0 <pitch>' moves the note and 'set 1 <accidental>' re-spells it; a bang sends again. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - pitch
     - INT
     - minimum-maximum
     - The pitch. Sent after the accidental.
   * - 1
     - accidental
     - INT
     - -1, 0 or 1
     - How the pitch is spelled: 1 sharp, -1 flat, 0 natural (always 0 for a white key). Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - minimum
     - 0
     - 0-127
     - The lowest pitch the staff covers.
   * - maximum
     - 127
     - 0-127
     - The highest pitch the staff covers.
   * - spelling
     - 1
     - 1 for sharps, -1 for flats
     - How a black key is spelled when no message chooses: 0 or above for a sharp, below 0 for a flat.


``.preset``
-----------

Stores and recalls snapshots of the patch's controls. 'store <n>' captures every control whose value can be restored into slot n, and a number recalls that slot. The slots are saved with the patch.

:Kind: Control-rate

``store <n>`` captures every control whose GUI value can be written back, in
the whole patch including subpatchers, and a recall sends each one its value
again. :ref:`gui-preset` covers the messages, what a slot captures, and when
a recall runs. The slots are saved with the patch, but loading does not
recall one (see :ref:`gui-saved`).

.. code-block:: text

   [.preset 8]   store 0  ...  0  =>  every control back as it was, then 0

The GUI value is the active slot, or -1 when none is active. It is
read-only. A recall is instant: there is no blending between slots.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - control
     - FLOAT, INT, BANG, LIST
     - slot 0 to slots-1
     - A number, or 'recall <n>', recalls that slot; a bang recalls the active slot again; 'store <n>' captures the patch into slot n; 'clear <n>', 'clear' and 'clearall' empty slots.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - recalled
     - INT
     - 0 to slots-1
     - The slot just recalled, sent once every value is back in place. Nothing for an empty slot.
   * - 1
     - stored
     - INT
     - 0 to slots-1
     - The slot just stored.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - slots
     - 32
     - 1-1024
     - How many slots the bank holds. Changing it replaces the object, and the new one starts with empty slots.


``.radiogroup``
---------------

Radio buttons, or check boxes with 'multi', over named items. It works exactly like .umenu; a host draws it as a group of buttons.

:Kind: Control-rate

It works exactly like ``.umenu``; see there. A host draws radio buttons, or
check boxes with ``multi``: ``.radiogroup multi 8`` is eight check boxes. In
``multi`` mode a number toggles that box, and a list of one 0 or 1 per box
sets them all.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - selection
     - FLOAT, INT, BANG, LIST
     - 0 to item count - 1
     - A number selects that item (toggles it with 'multi'); an item name selects that item; a list of numbers sets the whole selection; 'set <index> <value>' writes one cell; a bang sends again. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - index
     - INT
     - 0 to item count - 1
     - The item number: the selection, or with 'multi' the item just changed. Sent last.
   * - 1
     - item
     - LIST
     - one item name
     - The name of that item.
   * - 2
     - state
     - LIST
     - the index, or one flag per item
     - The whole selection, as the GUI value spells it: the item number, or with 'multi' a 0 or 1 per item. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - items
     - —
     - optional 'multi', then either item names or a single item count 1-256
     - An optional 'multi' keyword, then the item names. A single number is a count of items named by their numbers; no items gives two.


``.rslider``
------------

A range control: two ends inside minimum-maximum, such as a key split or a velocity layer. It sends the lower end, the higher end and both as a list, whichever way round the ends were set.

:Kind: Control-rate

The two ends are set separately, and either may be the higher one: the
object always sends the lower end from the left outlet and the higher end
from the middle one, with the pair, lower first, from the right outlet. The
outlets fire right to left.

.. code-block:: text

   [.rslider]   20 -> right inlet, then 100 -> left inlet  =>  20. 100.,  100,  20

- a number on the left inlet sets that inlet's end and sends.
- a number on the right inlet sets the other end silently.
- a list sets both ends from its first two numbers; a single number sets the
  left inlet's end.
- ``set 0 <value>`` moves the current low end and ``set 1 <value>`` the high
  end.
- bang: send again.

Both ends are clamped to ``minimum``-``maximum``, which may be given in
either order. The GUI value has two cells, low end first.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - end/range
     - FLOAT, INT, BANG, LIST
     - minimum-maximum
     - A number sets one end; a list sets both ends; 'set <0|1> <value>' moves the low or the high end; a bang sends again. Everything here sends.
   * - 1
     - end
     - FLOAT, INT
     - minimum-maximum
     - Sets the other end without sending.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - low
     - FLOAT
     - minimum-maximum
     - The lower end. Sent last.
   * - 1
     - high
     - FLOAT
     - minimum-maximum
     - The higher end.
   * - 2
     - range
     - LIST
     - minimum-maximum
     - Both ends as a list, lower first. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - minimum
     - 0
     - any float
     - The lowest value either end can reach.
   * - maximum
     - 127
     - any float
     - The highest value either end can reach.


``.slider``
-----------

A slider holding a position from 0 to 1. A number sets the position, clamped to that range, and sends it; a bang sends it again.

:Kind: Control-rate

The position runs from 0 to 1. A number outside that range is clamped, so an
int sets 0 or 1. Every message sends the position. For another range, use
``.dial`` or put ``.scale`` after the slider.

**Restoring a value**

``.slider``, ``.dial``, ``.i``, ``.f`` and ``.t`` take their own GUI value
back on the left inlet, which is how a host or ``.preset`` restores them:

- a list holding one value sets it. That is exactly the string the host read.
- ``set 0 <value>`` sets it too. 0 is the cell number; any other cell number
  is ignored.

Both work like a number on the inlet: clamped the same way, and the value is
sent. Only the first number of a longer list is used. A list starting with
any other word changes nothing, and the value is sent again. See
:doc:`/patcher/gui` for the protocol as a whole.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - set/bang
     - FLOAT, INT, BANG, LIST
     - 0.0-1.0
     - A number sets the position and sends it; a bang sends it again. Also takes its GUI value back, as a one-number list or 'set 0 <value>'.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - FLOAT
     - 0.0-1.0
     - The position.



``.t``
------

An on/off toggle. An int sets it (0 is off, any other number on), a bang flips it, and every message sends the state as 0 or 1.

:Kind: Control-rate

An int sets the state: 0 is off, any other number is on. A bang flips it.
Every message sends the state as 0 or 1.

The GUI value is ``on`` or ``off``. The left inlet takes that word back, or a
number, alone or after ``set 0``, and sets the state without flipping it.
Restoring works as described under ``.slider``.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - set/toggle
     - INT, BANG, LIST
     - 0 or 1
     - An int sets the state (0 off, anything else on); a bang flips it. Also takes its GUI value back: 'on', 'off' or a number, alone or after 'set 0'.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - INT
     - 0 or 1
     - The state.



``.tab``
--------

A row of tabs over named items. It works exactly like .umenu; a host draws it as tabs.

:Kind: Control-rate

It works exactly like ``.umenu``; see there. A host draws a row of tabs.
Wire the name outlet into ``.route`` to switch between named pages of a
patch.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - selection
     - FLOAT, INT, BANG, LIST
     - 0 to item count - 1
     - A number selects that item (toggles it with 'multi'); an item name selects that item; a list of numbers sets the whole selection; 'set <index> <value>' writes one cell; a bang sends again. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - index
     - INT
     - 0 to item count - 1
     - The item number: the selection, or with 'multi' the item just changed. Sent last.
   * - 1
     - item
     - LIST
     - one item name
     - The name of that item.
   * - 2
     - state
     - LIST
     - the index, or one flag per item
     - The whole selection, as the GUI value spells it: the item number, or with 'multi' a 0 or 1 per item. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - items
     - —
     - optional 'multi', then either item names or a single item count 1-256
     - An optional 'multi' keyword, then the item names. A single number is a count of items named by their numbers; no items gives two.


``.text``
---------

A comment in the patch. It holds its text for a host to display and has no inlets or outlets.

:Kind: Control-rate



**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - text
     - —
     - any text
     - The text to display.


``.textbutton``
---------------

A button carrying a text label. It works exactly like .led; a host draws it as a labelled button instead of a lamp.

:Kind: Control-rate

It works exactly like ``.led``; see there. A host draws a button with the
label on it.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - state
     - FLOAT, INT, BANG, LIST
     - 0 or 1
     - Latching: a number sets the state (0 off, anything else on) and a bang flips it. Momentary: any number or bang is a press. In both modes a one-number list or 'set 0 <value>' sets the state outright. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - state
     - INT
     - 0 or 1
     - The state. Sent last.
   * - 1
     - label
     - LIST
     - the label, or empty
     - The label, so a bank of controls wired into one object can say which one fired. Empty when the control has no label. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - label
     - —
     - optional 'momentary', then any text
     - An optional 'momentary' keyword, then the label. The words of the label are joined with single spaces.


``.textedit``
-------------

An editable text field. Text arriving on the inlet replaces the stored text and is sent on; a bang sends it again. It holds up to 256 characters.

:Kind: Control-rate

Everything that arrives is text. A list is stored word for word: no word is
a command, so a field can hold ``set`` or ``clear`` like any other text. A
number is stored as the text that spells it, and an empty list clears the
field. Every message sends the text from the outlet, as a list.

The field holds at most 256 characters. Longer text is ignored and the
stored text is kept (and sent again). A starting text longer than that is
ignored with an error in the log.

The text is never turned back into a number: a field holding ``440`` sends
the text ``440``. Put ``.fromsymbol`` after it to read a number, or
``.tosymbol`` to join the words into one.

The GUI value is the text. It is written back as plain text, with no ``set``
form (see :doc:`/patcher/gui`). The live text is not saved with the patch;
the ``text`` argument is only the starting text.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - in
     - FLOAT, INT, BANG, LIST
     - any text up to 256 characters
     - A list becomes the text, word for word, and is sent on; a number becomes its text; a bang sends the text again. An empty list clears it.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - out
     - LIST
     - —
     - The text, as a list, after every message.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - text
     - —
     - any text up to 256 characters
     - The text the field starts with.


``.umenu``
----------

A menu of named items. A number or an item name selects an item, and it sends the item number, its name and the whole selection. With 'multi', several items can be selected at once.

:Kind: Control-rate

``.umenu``, ``.radiogroup`` and ``.tab`` are the same object under three
names. A host draws ``.umenu`` as a pop-up menu, ``.radiogroup`` as radio
buttons or check boxes and ``.tab`` as a row of tabs; they take the same
arguments and messages.

**Arguments**

An optional ``multi`` keyword, then the items:

- no items: two items, named ``0`` and ``1``.
- a single number of 1 or more: that many items, named by their numbers.
- anything else: one item per word, up to 256. A longer list is cut short
  with a warning.

With ``multi``, several items can be selected at once. The first item cannot
be named ``multi``, and an item named ``set`` cannot be selected by name. The
items are fixed: changing the arguments replaces the object. There are no
messages to add or remove items.

**Messages**

- a number: select that item. With ``multi`` it toggles the item instead. A
  number outside the list is ignored.
- an item name: select that item. An unknown name is ignored.
- a list of numbers: the whole selection, as the right outlet spells it.
  Without ``multi`` that is the item number; with ``multi`` it is one 0 or 1
  per item, and a shorter list leaves the remaining items as they are.
- ``set <index> <value>``: without ``multi``, ``set 0 <item>`` selects an
  item; with ``multi``, ``set <item> <0|1>`` sets one item.
- bang: send again.

**Output**

Every message sends, right to left: the whole selection, then the name of
the item, then its number. With ``multi`` the number is the item that just
changed, or after a whole-selection write the lowest selected item.

.. code-block:: text

   [.umenu sine square saw]   saw  =>  2,  saw,  2

The GUI value is the selection: one cell with the item number, or with
``multi`` one cell per item.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - selection
     - FLOAT, INT, BANG, LIST
     - 0 to item count - 1
     - A number selects that item (toggles it with 'multi'); an item name selects that item; a list of numbers sets the whole selection; 'set <index> <value>' writes one cell; a bang sends again. Everything here sends.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - index
     - INT
     - 0 to item count - 1
     - The item number: the selection, or with 'multi' the item just changed. Sent last.
   * - 1
     - item
     - LIST
     - one item name
     - The name of that item.
   * - 2
     - state
     - LIST
     - the index, or one flag per item
     - The whole selection, as the GUI value spells it: the item number, or with 'multi' a 0 or 1 per item. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - items
     - —
     - optional 'multi', then either item names or a single item count 1-256
     - An optional 'multi' keyword, then the item names. A single number is a count of items named by their numbers; no items gives two.


``.xyslider``
-------------

A two-dimensional pad holding an x and a y, each inside its own bounds, so two parameters move as one gesture. It sends x, y and the pair as a list.

:Kind: Control-rate

x and y are independent, each clamped to its own pair of arguments, which
may be given in either order. The position is never sorted: the first cell
is always x.

- a number on the left inlet sets x and sends.
- a number on the right inlet sets y silently.
- a list ``x y`` sets both; a single number sets x.
- ``set 0 <value>`` sets x and ``set 1 <value>`` sets y.
- bang: send again.

The outlets fire right to left: the pair, then y, then x. The pair is the
cursor message ``.nodes`` takes, so one cord turns the pad into a morph
control.

**Inlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Accepts
     - Range
     - Description
   * - 0
     - x/position
     - FLOAT, INT, BANG, LIST
     - xminimum-xmaximum
     - A number sets x; a list 'x y' sets both; 'set <0|1> <value>' sets x or y; a bang sends again. Everything here sends.
   * - 1
     - y
     - FLOAT, INT
     - yminimum-ymaximum
     - Sets y without sending.


**Outlets**

.. list-table::
   :header-rows: 1
   :widths: 6 18 18 18 40

   * - #
     - Label
     - Type
     - Range
     - Description
   * - 0
     - x
     - FLOAT
     - xminimum-xmaximum
     - The x value. Sent last.
   * - 1
     - y
     - FLOAT
     - yminimum-ymaximum
     - The y value.
   * - 2
     - position
     - LIST
     - per-axis bounds
     - Both values as the list 'x y'. Sent first.


**Parameters**

.. list-table::
   :header-rows: 1
   :widths: 22 18 18 42

   * - Name
     - Default
     - Range
     - Description
   * - xminimum
     - 0
     - any float
     - The lowest value of x.
   * - xmaximum
     - 127
     - any float
     - The highest value of x.
   * - yminimum
     - 0
     - any float
     - The lowest value of y.
   * - ymaximum
     - 127
     - any float
     - The highest value of y.


