gfx/value_box.h
A readout you can type into.
#include <sonore/gfx/value_box.h>- 1type
- Guides: The native editor
On this page
Design notes
Why this is not a nicety
Every generated plugin's editor showed its parameter values in a Label, and a Label is not editable. So the only way to reach a value was to drag: fine for a filter sweep, useless for "set the output to exactly -6.0 dB", which is a thing engineers do constantly and check afterwards. A knob with a 66 dB range across 200 pixels cannot be dragged to a tenth of a decibel, and the number underneath it was there to be READ and not to be used.
The oldest trick in the book -- a slider's text box, editable on a double click. It is one of those features that is invisible until it is missing and then is the first complaint.
What it takes to get right
It has to accept what it PRINTS. A box that shows "2.30 kHz" and then refuses "2.30 kHz" back is worse than no box, because the user typed exactly what they were shown. parseParamValue already handles that -- the kHz suffix, and named steps by name -- because a host doing "enter a value" needs the same thing, and having one parser is the only way the two can agree.
It has to be ONE undo step. A typed value that arrives as a bare setParameter with no gesture around it is an automation write the host cannot group, so the DAW records a point rather than an edit and undo does not take it back.
And a value it cannot parse must NOT be silently thrown away. Reverting to the old number looks identical to the plugin ignoring the keyboard; staying in the field with the text selected says "that is not a number I can use" without a dialog. That is Return's answer. Clicking away from the field takes the keyboard with it, and a field left open without one is stuck -- so there the field closes on the old value, as the reference's does.
Types 1
class ValueBox : public Widget
A parameter's value as text, which a double click turns into a field to type a new value into. See the file comment for the three things it must get right.
The owner feeds it with setText() every UI tick -- a field being typed in is never overwritten -- and decides what typed text means in onTextEntered: return true once the value is applied (inside one gesture, so the host records one edit), false to refuse it. Return and focus loss both commit; Escape cancels. Refused on Return, the field stays open with the text selected; refused as the focus leaves, it closes as Escape closes it. Unset, onTextEntered refuses everything. Message thread only.