Input windows
This chapter will explain how to create windows for convenient data entry
through widgets. You will become acquainted with the important NST input_window
unit and its major widget types.
Overview
The specification of the layout of an input_window
follows the familiar printf function in C: the main text
layout is simply written as a "format string". Embedded special
tokens ("widget directives") indicate the positions where a widget
shall appear, together with its type (such as a button or a slider)
and optional further parameters, e.g., default settings and input range
limitations. Each widget directive is introduced with a '%'-character,
optionally followed by up to four colon-separated parameters and
ended by a type character that determines the type of the widget
to be inserted at this position.
Simple examples are integer (widget directive %i)
or float (%f) entry field, slider (%s),
button
(%b) or text string input (%t). A line
break requires the special directive %n. A %v
(for
"value")
after a slider will make a widget that displays the value of the preceding
slider. The values of widgets appear at the output pins of the input_window
unit (cf. below). Callbacks allow to execute named NST units whenever
a widget output has become changed. The first
example#1
illustrates the basic widget types (it contains also an example of the
output_window
unit,
which is specified in a similar way) The following sections give a more
detailed explanation.
Widget parameters
A single parameter between the % and the type character specifies
an initial default setting (e.g., %3.14f);
two parameters specify an allowed input range (e.g., %0:10i);
three parameters specify an input range and an initial default setting
(e.g. %0:10:3.14s).
In the case of the slider value display directive %v,
the parameters are interpreted as field width and precision. The widgets
%j
and
%g
are analogous to %i and
%f, but allow also
the absence of any numeric entry (i.e., a blank input field, which is mapped
to the reserved value NST_BLANK_ENTRY
(currently equal
to -99999999)). Experiment with the above example#1
to set limits and initial values for some widgets!
How to make text inputs
In the case of a text input the default setting is specified with a separate
format directive and the "range parameters" specify the width and the height
of the text field, e.g. %{hello world}%50:3t (for single
line text inputs, the second parameter can be omitted). A %2^ after
a text input will paste a vertical slider of 2 characters width to the
right of the text input field (try it out with the example#1).
How to make buttons
A %b makes a simple "on/off"-button with two settings
(off=0, on=1) that is initially "off" ("on", when
%1b
is specified instead). %-1.5:2:2b makes a button toggling
between the two values -1.5 and 2. The third parameter sets the button
initially to its "on" state. A label-directive %ltext,
when placed after the button widget directive, will label the button with
"text"
(use a tilde '~' for indicating a space within text) A label directive
such as "%lNo|Yes|Maybe" will make a button with three
settings and labels "No", "Yes", "Maybe" (if the button
widget comes without range specification parameters, the button settings
would correspond to 0,1 and 2; otherwise, the button settings divide the
range interval into the necessary number of equidistant portions, with
the interval end points corresponding to the first and last button setting).
Besides '|', the character '~' has a special role and indicates
a space in a button label. A %b button keeps its value
between invocations of a input_window unit. A variant is the %d
button:
it always returns to its default value when a new invocation of its input_window
is made. Finally, you can change the width (in characters) of a button
and all its successors by specifying a fourth parameter. E.g. %0:1:0:3b
will make this and all following buttons only three characters wide (the
initial default width is 10). Here is an
example#2
with a few different buttons.
How to define
an accelerator key for a button
The backward apostrophe "`" is a special character inside button
label that allows to assign an accelerator key to the button so
that it can be pressed from the keyboard. The effect of the apostrophe
(which itself will never appear printed on the button) is to mark the following
character as a command character that will then appear underlined.
When a button has an underlined character, say c, the button
can be pressed also from the keyboard by pressing the ALT key and
the key of the the underlined character c (case
is not distinguished) simultaneously. Example:
%b%l`Cancel
will make a button with label "Cancel" that can be toggled
with ALT-c. In addition, buttons with the special labels "Ok"
and "Cancel" can also be pressed with ALT-Return and ALT-Backspace,
resp.
How to make
"OK" buttons to wait for end of input
The directive %R makes a special "OK-button" with
default label "OK" (can be re-labelled with %ltext).
It reacts similar to a %d button, but its presence makes
the window wait for input until the %R button is pressed
(therefore, it serves only to acknowledge the end of input and its value
is not made accessible). The %X button is analogous, with
the only difference that it also closes the window when it is pressed.
Any window can contain at most one %R or %X button
(and never both).
How to access values
of numeric widgets
Each numeric widget (such as %i %f %b %s) is associated
with a scalar float pin in the input_window's first output connector
(the order of corresponding pins is the same as that of the numeric widgets).
For windows with many numeric widgets, the %a< directive
(where a is a non-negative integer) can be used to make all pins of the
following numeric widgets appended to output connector a (the
input_window
unit will make enough connectors to satisfy all occuring
%a<
directives,
even if some intermediate connectors should end up unused). See example#3
for
an illustration.
How to access values
of text widgets
Each text widget (such as %i, %f, %t) is associated with
a three-pin composite connector. The first two pins hold cursor and window
positioning information (see the manual page of the input_window unit).
The third pin contains the text string itself. The text widget connectors
come after the numeric widget connectors and in the same order as the subset
of associated text widgets. Note that widgets such as %i, %f are
text and numeric widgets simultaneously and thus make their input available
in numeric and string form, using two connectors simultaneously.
How to define callbacks
The %!name directive, when placed after a widget, binds
the execution of a named NST unit as a "callback" to the widget,
i.e., any change to the widget (or entering it it with the mouse pointer,
in the case of a named area) will update the associated output connector
and then will execute the named NST unit "name". After
that, control returns back to the input_window unit, i.e, further
input events can be processed. More than one named NST unit can be specified,
using the syntax %!name1,name2,name3 etc.( %!*
is a shorthand for the previous callback that is useful if the same group
of units shall be bound to a number of successive widgets). Look at example#4.
It is almost the same as example#1, but the output_window
now has become a callback for each widget (using the %!*
shorthand), causing its immediate update on any widget change in the input_window.
The %!!name directive is analogous, but here the named
NST unit(s) is (are) repeatedly called, as long as the preceding widget
has a non-zero value (if the widget is a named area, the condition instead
is that the mouse pointer must be inside it). Example#5
uses this technique to control two mini-subcircuits (each consisting of
two units) in an apparently time-sharing fashion.
Finally, %!!!name after a named area will trigger the
callback whenever the mouse pointer leaves the area. This callback is also
useful after a grouped button (cf. below). For all other widgets, there
will be no binding.
Callbacks are mainly useful in the presence of a %R or
%X
button. They are one of the most important ways to structure control flow
for interactive programs. The second example illustrates the use of callbacks
to make an interactive program. For the use of parameters with a callback,
see the input_window manual page.
How to define
"grouped
buttons" for selections
A special role is played by the %[...%] brackets. When
they enclose a group of buttons, they allow maximally one button of the
group to be "on". A %![...%] group is even
stricter: here exactly one button must be "on". Buttons in either type
of group allow a finer control of their callbacks: while for a normal button,
any
state change triggers all its %! -callbacks, for a button
in a group only the off-on transitions do so. The on-off
transitions can be bound to a separate callback, starting with three '!'-marks
(i.e., %!!!name ).
The on-off callbacks are not available for normal (non-grouped) buttons,
but since any button can be enclosed in %[..%] to form
a "singlet-group", this can be used to make the finer callback control
also available for a button that is not restricted by grouping.
Some further important
directives
The presence of the %H directive "hides"
the window until it becomes executed (at that moment, the window will open).
The %h is similar, but hides the window "more firmly":
even execution will not open it, only an explicit NST_W_OPEN
will cause the window
to open. The %# lets the rest of the line be ignored
as a comment The %0l fills the rest of the line with a
horizontal groove. A %3l lets the groove stop 3 character
widths before the right margin. Enclosing a set of (binary) buttons within
a %[...%] pair allows maximally one button in the set to
be "on". I.e., activating any button in the set will reset any other
"on" button(s) in the set. The %k collapses all text output
connectors into a single mult-pin connector (useful when there are too
many connectors to resolve them graphically in Neo).