USAGE:


   #import interactables2D

SYNOPSIS:

Offers in the prog_unit various interactable 2D graphics objects for display in 2D plot windows created by NST graphics units such as plot_vec, plot_xy and plot_series:
rectangle:
an editable rectangle shape
arrow_sym:
an editable 2D arrow
arrow_pair:
a pair of arrows from the same origin
marker_sym:
a single draggable marker symbol
marker_set:
a set of markers that include all of the previous
polynomial:
the graph of a polynomial
Main purpose is to simplify interactive programs: once an object is created, it becomes immediately visible and responsive to manipulation with the mouse pointer (most objects become selected with the left mouse button), even when the NST circuit is not running and without any need for extra programming in the #importing prog_unit (to suppress this "auto-show-up, cf. below). Callbacks can be attached to each object to trigger NST units, additionally the object state can be queried over its state variables. Available classes are derived from a common base class (from which no instances can be created) and share the following methods and variables:

VARIABLES:

readonly int but1,but2,but3:
the current mouse button states
readonly float mx,my:
the current mouse pointer coordinates (in data units relative to the coordinate frame of the chosen window)
float pos[]:
array holding the xy position(s) (in the order xyxy..xy if there are several items) associated with the interactable object (e.g., marker positions, rectangle center, arrow origin etc.)

METHODS:

void draw(void):
enforce update of drawing
void mode(int mode):
choose an interaction mode (cf. below).
void set_color(int color):
void set_size(int pixel_size):
void set_symbol(int symbol):
set attributes for displayed object(s).
void set_linewidth(float w1,w2=0):
set linewidth. A value of 0 yields a device-dependent finest line. Integral values are interpreted in pixels. The second value allows to set a separate linewidth value for the direction indicators. If 0, this means following w1.
void graphics(int enabled):
the call graphics(0) will disable any graphics output (this may be useful when graphics shall be fully controlled from the callback units, cf. below)

OPTIONS:

Most subclass constructors will accept an option string that permits to initialize some object properties. The following options are shared for all interactable objects in this package:
%w1:w2L
set linewidth (same as method set_linewidth(w1,w2))
%0G
disable any graphics output until method call graphics(1). In particular, this will suppress the automatic showing up of the object when it is constructed.

CONTROL MODES:

All interactable objects will respond (unless graphics operations have been disabled by option %0G or the method call graphics(0)) to the NST control call NST_INIT by redrawing themselves (this is how their auto-show-up is implemented).

LOAD AND SAVE:

Object variables that are declared with the keyword static will have their state saved to disk if Neo save mode is enabled. Their state will then be later restored upon load.

DEFINING CALLBACKS:

The method call

    void set_callbacks(char *list1, char *list2, char *list3)

allows to associate up to three comma-separated lists of callback units to events generated for an interactable object instance. I.e., each listi is of the form "name1,name2,...", where each namei specifies a named NST unit in the usual fashion. The units in list1 will be executed when on a button-down event, those in list2 for each pointer move event when at least one button is down at the same time ("dragging"), and those in list3 on a button-up event. Specifying any of listi as NULL or the empty string amounts to having no callbacks for the associated events. Details how to pass parameters here.

AVAILABLE CLASS CONSTRUCTORS:


   class marker_sym(char *window, float x,y, char *options, int mode=0)

Creates for window window a single marker symbol with initial interaction mode mode (default is MODE_MOVE, i.e., the symbol is draggable). String options permits the following initializations:
%c:t:sM
set marker color (c), type (t) and pixel size (s). Defaults are c=2 (red), t=8 (hollow circle) and s=11 pixels.
%aZ
enforce marker position to zoom grid, a=zoomfactor
These can later be changed with methods set_color/symbol/size(). Method mode() permits to choose among the two modes MODE_MOVE (symbol is draggable) and MODE_PASSIVE (symbol is fixed). Callbacks can be attached with set_callbacks().

   class arrow_sym(char *window, float vec, float origin=NULL,
                   char *options=NULL, int mode=0)

Creates for window window a single arrow emanating from origin origin ((0,0) if NULL) and pointing to the location orig+vec. Initial interaction mode is mode (default is MODE_ADJUST, i.e., the arrow tip can be dragged, but the arrow origin is fixed). String options permits the following initializations:
%R
make right mouse button toggle between interaction modes MODE_MOVE and MODE_ADJUST. Use %0R to disable explicitly
%pS
set scaling for arrow vector: p=0 (or absent): use coordinate scaling. Otherwise, if p>=1, set p screen pixels == 1.0, Otherwise, if 0<p<1, set fraction p of window width == 1.0.
%c1:c2C
set vector color for MODE_ADJUST (c2) and all other modes (c1). If only c1 is given, c2=c1 will be assumed. Should be used whenever mode toggling is on.
These can later be changed with methods set_color/symbol/size(). Method mode() permits to choose among the three modes
MODE_MOVE:
arrow is translatable
MODE_ADJUST:
arrow origin is fixed, but direction/length adjustable
MODE_PASSIVE:
interaction (and %R mode toggling) is disabled
The remaining methods: set_color() allows to change the color, set_symbol() allows to choose a special symbol for the arrow origin, set_size() will set its pixel size. Callbacks can be attachted with set_callbacks().

   class arrow_pair(char *window, float *vec1, *vec2,
                   float *origin=NULL, char *options, int mode=0)

Analogous to arrow_sym(), but for a pair of arrows vec1,vec2 from the same origin origin. Same methods, analogous semantics. Additional option %O (ooh, not Null) will force axes orthogonal.

   class rectangle(char *window, float *vec, *orig=NULL,
                   char *options=NULL, int mode=0)

Creates for window window an adjustable rectangle located at position orig and with side lengths initialized to vec[0],vec[1]. String options determines further properties:
%N
non-centered: origin is lower left corner (otherwise, origin is center)
%zA
constrain window to axis-parallel orientation, optionally fitting on pixel grid of zoom factor z. If origin is center, the pixel size of the rectangle will always be an odd number of (zoomed) pixels along each direction.
%R
make right mouse button toggle between interaction modes MODE_MOVE and MODE_ADJUST.
%pS
set scaling for rectangle sides: p=0 (or absent): use coordinate scaling. Otherwise, if p>=1, set p screen pixels == 1.0, Otherwise, if 0<p<1, set fraction p of window width == 1.0.
%cI
set color to a (for more details on this option, see below).
The state of the rectangle is available in two 2D arrays:
float pos[2]
locatation of rectangle origin (lower left corner or center, depending on option string).
float dir[2]
components of vector from rectangle origin to upper right corner (NOTE: origin can be rectangle center or lower left corner, depending on absence or presence of %N option).
A draw() will adjust the rectangle to the data written into these arrays.

Available modes:

MODE_MOVE:
rectangle is translatable
MODE_ADJUST:
rectangle is adjustable
MODE_PASSIVE:
interaction (and %R mode toggling) is disabled
Classes rectangle,arrow_sym and arrow_pair also admit further color customization with %I options as explained for marker_set below. Particularly when mode toggling ( %R option) has been activated, one should make modes distinguishable by assigning different colors.

CLASS marker_set:

marker_set(char *window, char *options=NULL, mode=MARKER_CREATE)
Create an empty marker set of positional xy markers for window window with initial mode mode.
Provides an interactively editable set of 2D markers (comprises all previous classes as special cases). Markers can be created, deleted and moved. Optionally, each marker can have one or a pair of direction indicators (displayed as 2D line segments centered on the marker) which can be changed in direction and (optionally) in length. The direction indicators can either be directly associated with coordinate vectors (given by the difference between the two end points) or with independent parameter pairs. In the first case, scaling for the contents of the associated parameter array is according to the currently valid coordinate transform. In the second case, scaling is according to a fixed scaling ratio that maps a given pixel distance to value 1.0. String options can consist of zero or more of the following %-directives:
%zA
enforce axis-parallel orientation of direction indicators. In this case, the direction indicator settings will become representable by only two values, which then are in dir[0] and dir[1] ( dir2[] is not used in this case). If z>0 is present, restrict allowed positions also to pixel grid with zoom factor z. The chosen rectangle will then always have odd-valued side lengths of 2m+1 and 2n+1, with dir[i]=(m,0) and dir2[i]=(0,n). In this case, the enclosed area is also restricted to lie fully within the window.
%B:
if in mode %D (cf. below), enclose orthogonal direction indicators by rectangular bounding box of the color of the associated marker symbol.
%cB:
Analogous, but use separate color c for the bounding box. If two color parameters c1:c2 are specified, c1 will be for non-Edit mode, c2 for MODE_ADJUST.
%cC
set initial marker color to c
%c:t:sM
set color c, type t and size s of marker symbol
%t:sd
Enable direction indicators. If this options occurs twice, pairs of independent direction indicators are enabled. t and s are optional and set the direction indicator symbol t (a marker symbol number) and pixel size s. If no arguments or only a size parameter s is given, arrow symbols will be used as a default. The first set of direction indicators stores its 2n values in the public array dir[], the 2nd set in dir2[] (unless %A option was set, in which case dir[] alone can hold all values). Each successive pair (dir[2i], dir[2i+1]) is the direction vector associated with the first direction indicator of the i-th marker (at position (pos[2i],pos[2i+1]) ), analogously for dir2[].
%t:sD
%t1:t2:sD
same as %d%d, but directions are constrained to be orthogonal (in data coordinates). If both %D and %d%d (or %d) are present, %D will override the %d(s). Parameters t and s are optional and specify marker type and size for the direction indicator symbols. The 2nd form permits to assign two different marker symbols t1 and t2 (of same size s) to the 1st and 2nd direction indicator.
%N
non-centered direction indicators
%aR
set pick radius for direction indicators to a pixels.
%x:yP
position a marker at data coord (x,y). Any desired number of such tokens may be given in order to create and initialize an equivalent number of markers. Color and type can be switched with interspersed %C directives.
%x:y:u:vP
position a marker at data coord (x,y) and set 1st direction indicator to vector (u,v).
%pS
set scaling for direction indicators: p=0 (or absent): use coordinate scaling. Otherwise, if p>=1, set p screen pixels == 1.0, Otherwise, if 0<p<1, set fraction p of window width == 1.0.
%0G:
disable graphics output (can be re-enabled by calling graphics(1)).

Direction indicator colors:

If direction indicators are enabled, they usually follow the color of their marker symbol. This default behavior may be
modified to provide more information to the user:
%I : make direction indicators invisible in modes other than mode MODE_ADJUST, keeping any any previous color settings for this mode. %aI : choose independent color a for all direction indicators. %a1:a2I : dito, but with a separate color a2 to make 2nd direction indicator distinguishable from first. %a1:a2:b1:b2I : analogous, with separate colors b1,b2 for MODE_ADJUST.

Variables:

readonly int num
the number of markers currently held
readonly int but1,but2,but3:
the mouse button states
readonly float mx,my:
the mouse pointer coordinates (in data units)
readonly int index:
the index of the currently selected marker, or -1 if no marker is selected (e.g., after a DELETE has been carried out)
float pos[2*num]:
array holding marker xy positions
float dir[2*num]:
array holding direction parameters (NULL, if direction parameters are disabled)
float dir2[2*num]:
array holding 2nd set of direction parameters (NULL, if 2nd set of direction parameters is disabled or option %A has selected axis-parallel mode)
int color[num]:
array holding marker colors
int size[num]:
array holding marker pixel sizes
int symbol[num]:
array holding marker symbol types

Methods:

int mode(int mode):
return previous interaction mode and set new current mode. mode can be one of the following:
MODE_CREATE: left mouse button will create marker object MODE_DELETE: left mouse button will destroy marker object MODE_MOVE: left mouse button will select and drag marker object. MODE_ADJUST: left mouse button will select and drag direction indicator MODE_PASSIVE: all interactions disabled. (these are available as public constants).
void graphics(int enabled):
the call graphics(0) will disable any graphics output (this may be useful when graphics shall be fully controlled from the callback units, cf. below)
void draw(void):
enforce update of drawing
void set_color(int color):
void set_size(int pixel_size):
void set_symbol(int symbol):
set attributes for subsequently created markers
int set_markers(float *pos, float *dir=NULL, float *dir2=NULL):
specify a set of markers at positions pos (a vector of xy pairs in data coord). After this call, the marker set will consist of up to dimof(pos)/2 markers (all with the same attributes, as given by set_color()..set_symbol() below; markers with positions outside the currently specified area will not be created). Optionall, dir and dir2 (if non-NULL) specify the values for the direction indicators (if they are constrained to orthogonal, only the length of the direction pairs in dir2 will be evaluated). Returns the number of markers set.
int add_markers(float *pos, float *dir=NULL, float *dir2=NULL):
as before, but adding the specified markers. Returns the nr of markers added.
void clear(void):
clear all markers.
For MODE_DELETE there is a slight modification of the calling sequence: here, callbacks in list1 will be called before the requested deletion is actually carried out (but after the button press) (the selected index is set to the to-be-deleted marker), list2 is executed after the requested deletion has been carried out (but before the button-release), and list3 is executed at the button-up event(s), as before. Pointer motion events cause no callback triggering in this mode.

Passing callback parameters:

Optionally, each namei may be preceded by the character '>'. In this case, the callback-dispatcher will look for suitable input fields of unit namei to deposit the index i of the currently selected marker (-1 if no marker is selected), the current mouse pointer position (x,y) (in data coord), the button states (b1,b2,b3) and the current marker positions (a dynamic float vector). To this end, it will seek input fields of appropriate dimension (d=1 for the index, d=2 for the mouse position, d=3 for the button states and dynamic pins for marker positions) and use for each item the first suitable field that is detected (if a suitable field is absent, this will just cause that the associated item is not passed, no error or warning will occur).

USAGE:

As soon as a marker_set instance is created, its marker operations become immediately accessible through the associated window, with no extra coding required in the prog_unit. However, in most cases it will be necessary to define a few callback functions to permit using the different modes (not only the initial default mode) and to access the values about the stored markers in the public variables.

CLASS polynomial:

polynomial(char *window, int order, char *options=NULL)
Provides a polynomial graph of order order in window window. The polynomial can be interactively changed by dragging markers displayed along its graph. If the order of the polynomial is chosen as 1, the important special case of an interactively adjustable line is obtained. Parameter options can contain zero or more of the following tokens:
%a:bC
set color of markers (value a) and graph line (value b). If b is not specified, color a is taken for graph lines too.
%a:bM
set marker size a (in pixels) and type b. Defaults are a=11 and b=8 (open circle).
%a:bT:
enable display of an additional marker of type a and color b that permits to translate the entire marker configuration, keeping all relative distances intact (defaults are a=2 (Red) and b=2 (open square)).
%aR
set pick radius to a pixels.
%x:yP
position a marker at data coord (x,y). Up to order such tokens are accepted, all further ones will be ignored. An alternative was to position the markers is to directly set the values in element array pos[].
%x1L
set linewidth for markers and polynomial graph to x1.
%x1:x2L
set linewidth for markers to x1 and for polynomial graph to x2.
%x1:y1:x2:y2L
position all remaining markers linearly and equidistantly along the line segment (x1,y1)..(x2,y2).

Variables:

float coef[n]
array of dimension n=order+1 holding coefficients of polynomial. coef[k] holds the coefficient of k-th power of variable.
float mx,my
position of mouse pointer.
float but1..3
button states
float pos[2n]
array with x and y positions of markers that specify the graph of the polynomial (order is xyxy... ).

Methods:

float eval(float x)
evaluate polynomial at value x
void set_plot(float xmin,xmax, int steps=0)
specify range over which polynomial graph is plotted, using steps steps. If steps=0, a default number (currently 100) of steps is used. Choosing xmin=xmax activates an automatic range determination: in this case, the range will be delimited by the leftmost and rightmost marker position.
The remaining methods are analogous to class marker_set:
void set_color(int color)
void set_size(int size)
void set_symbol(int symbol)
set attributes of markers used.
void draw(void)
draw the polynomial graph
void set_callbacks(char *list1, char *list2=NULL, char *list3=NULL)
set callbacks for button down, marker move and button up events. Each callback can be a comma-separated list of names of named units. Analogous as for class marker_set, any suitable input fields of a callback unit will be used to transmit the values of mx,my,but1..3 and pos.

FILE

interactables2D.c