(i) bind the mouse_xy unit as a %!-callback to the embedded window. This triggers the mouse_xy unit whenever the pointer enters the embedded window (if there are several embedded windows, each of them must have its own mouse unit, since each mouse unit instance can only be made responsible for a single window).
(ii) Create the mouse_xy instance in autoloop mode, i.e., with option %L. Choosing %L makes the mouse unit keep control (after triggered from the input_window) while the mouse pointer is within the associated window. As soon as the pointer leaves the window, the autoloop terminates and controll automatically falls back to the caller, i.e., the input_window in the present case.
(iii) Choose "NoWait" in the mouse_xy parameter dialog window so that the unit does not wait for a button press before any other events, such as pointer motion in the window, are processed. The mouse unit callback options (as described in the previous chapter Using the mouse) can be used to trigger further actions from mouse pointer motion or button press events.
Example#1 illustrates this set-up: the %!mouse callback following the named area "plot" in the input_window unit triggers the named mouse unit when the pointer enters the plot area; the mouse unit in turn has (in addition to its %L autoloop option) three callbacks: %0!prog:left_but_down and %0!!!prog:left_but_up invoke two methods (implemented in a prog_unit) to print a corresponing message when the left button (which is button 0) is pressed or released, while %!!printvec is called after each pointer motion event to display the new mouse coordinates in a little window. Experiment with a few changes to explore how the behavior of the circuit changes, e.g., when you configure the mouse unit in WaitMode.
Example#2 illustrates
how the same control scheme can cope with a more complex situation: now
there are two embedded windows and the mouse unit is bound to the larger
one, named "pixel". Whenever the mouse pointer enters window
"pixel",
the mouse unit is triggered and will continuously read the pointer
coordinates. These are fed to an output_window unit, which is executed
as a callback of the mouse_xy unit and whose output appears
in a small named area (non-sunken mode) of the input window. Additionally,
mouse button 0 toggles a 0/1 counter that activates/deactivates the container
named "subrect".
When activated, the circuitry inside the container will display a zoomed
subrectangle of the original image into the second, smaller embedded area.
Additionally, the input window contains a "Load" button with a callback to a file read unit and the write_pix display unit for the loaded image data. The operation of these components is largely separate from the others. The no_op in front of most of the circuit ensures that a "Step" will only call the input_window unit, which then controls all the rest via its callbacks.
Unlike most other units, the view3d unit comes with a built-in cursor control loop (i.e., you can rotate the view directly with the left mouse pointer). Therefore, this time we don't need an extra mouse unit, however, it still is important to configure the view3d unit again such (choosing mode 3 in its parameter dialog window) that its cursor control loop exits when the mouse pointer leaves the view3d window (again to avoid blocking the surrounding input_window).
Everything else is analogous to the previous example. The mouse pointer can rotate the view when entering the embedded window (to rotate, you must hold the left mouse button down; this requirement is inherited from the view3d's cursor control loop).
Additionally, the robot will respond to changes in the slider settings, since the view3d unit is also bound as a callback to the sliders (you don't need to bind the make_puma unit itself; it is executed via the view3d unit, which here plays a similar role as the mouse unit before. The difference is that you don't need to specify any callbacks for it, since it accesses the to-be-executed units by virtue of being an operator unit).
Load and start the example#4. With the buttons you can select what the mouse pointer does (all mouse actions are carried out with the left mouse button 0). With "Exit" you will return to the Neo command level.
Open the creation dialog window of the input_window unit ('m')
to see the the by-now familiar control structure of the circuit: the embedded
window is followed by the callback %!sum_val,mouse which
triggers two named units when the mouse pointer enters window: sum_val
computes (for the subsequently executed mouse unit) a "context-index",
indicating which command button of the input_window unit is currently
"On". The command buttons form a group configured such that exactly one
button must always be "on" (this is achieved by enclosing the widget directives
by the "group directives" %![ and %]).
The context index computed by the sum_val unit is fed to the
mouse_xy
control input (the value is computed from summing the values of all command
buttons; since only one button is on, the result is the value of the active
button).
The mouse unit itself has several callbacks (open the mouse creation dialog window to see them). As explained in chapter "Using the mouse", the value ("context index") at the mouse control input can be used to bind different sets of callbacks to the same mouse button (here the left button 0).
The callbacks themselves are all implemented as public methods in the prog unit, operating on two shared data arrays that hold the positions of the graph nodes and node index pairs representing the edges. The node position array is made accessible as the first output connector and allows the plot_xy unit to draw the node circles. A second output connector encodes the edges in a way so that they can be easily drawn with the plot_xy unit: the edges are coded as a long array of pairs of markers; every marker is given as a quintuple of x,y,color,type and size ("xycts"). By specifying t=1 for all even, and t=-1 for all odd points, only the odd points are connected with a line segment to their predecessors, as required.
Typically, you will specify as the "activation window" the main GUI window of the autostarted unit. Usually, this window also will have a button to terminate execution of the unit. Pressing this button should then be the exit action that is specified for that window.
The necessary specifications are made with Neo's Define command, applied to the to-be-autostarted unit. The relevant entry field is labelled "Associated activation window (if any):" and expects the name of the activation window, optionally followed by the exit action. If the exit action is a button press in an input_window, the specification takes the form
windowname %f:p:v
where windowname is the name of the input_window, f and p are the field and pin numbers of the selected button, and v the value to which the button shall be set (defaults are f=0, p=0, v=1, if no values are specified). @i-Variables can be used within the above specification; in this case, however, @i refers to the i-th parameter in the Creation dialog window of the container unit for which the input_window is specified (and not to the i-th parameter slot of the creation dialog window of the enclosing container, as usual).
NOTE: for safety reasons, the autostart feature is disabled
for circuits pushed into Neo from the netscape browser. Therefore, to run
the following example, use the next example link in the example#4.
This will load example#5 from Neo and, therefore, have the autostart feature
enabled. Directly clicking Example#5 below would push the example from
the browser, and the autostart feature would then be disabled.
Example#5 is a demo-circuit with two containers demo0 and demo1. The left unit demo0 has as its autostart window the left input_window named demowindow0. The right unit demo1 has as its autostart window the right write_pix window named demowindow1. This illustrates a situation where the autostart window is not of type input_window and, therefore, has no buttons to specify an autoexit operation. In this case, the autoexit is achieved by querying the pointer position and executing a break_unit when the mouse pointer has left the window.
While this control scheme works fine, it has the drawback that the "busy loop" continuously executes CPU cycles and should, therefore, be avoided in new work. The %! and %!!! callbacks are without this drawback, as well as the "continuous" %!! callbacks of the mouse_xy unit and the widget managing operations of the input_window and output_window units. All these react only when a pointer motion or some button event occurs so that CPU usage falls to zero when no further user events occur. A notable exception are the continuous %!! callbacks of the input_window and output_window unit: they are provided to explicitly allow continuous repetition of callback unit(s) even when user events are absent , e.g., to run some operation while a button is "On" or the mouse pointer is inside a named area (note the differenct to the mouse_xy %!! callback, which is "continuous" only while pointer motion events occur!).