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