[PREVIOUS] [NEXT] [UP]

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).


    [PREVIOUS] [NEXT] [UP]