10.1 Interaction Model

Bifrost abstracts input devices used in interaction in a general interaction model. The input device is typically a pointing device like a mouse. The model is defined in pattern InteractionHandler of the canvas. InteractionHandler defines a series of virtual attributes and a general interaction loop. The usage of the interaction handler is to execute an instance of a specialization of InteractionHandler with some of the virtual attributes further bound. The attributes are:

Specify what to do before the interaction loop starts. Also changes the canvas' drawing mode to be XOR, to allow for immediate feedback, see below.
Specify what to do when the user moves the pointer.
Specify what to do when the user presses a button of the pointer. ButtonInfo is a local attribute in ButtonPress that may contain device specific information, e.g. which button was pressed.
Specify what to do when the user releases a button of the pointer.
Specify what to do when the user presses a key on the keyboard.
Specify what to do when the user releases a key on the keyboard.
Specify a condition for ending the interaction handler. Default is when the rightmost button on the pointer is released.
Specify what to do when the user has terminated the interaction loop. Also changes the canvas' drawing mode back to normal

In addition to these attributes the handler provides three support functions:

Returns the current position of the pointer.
Returns True if the modifier entered was ON in last user action (Motion, ButtonPress, ButtonRelease, KeyPress or KeyRelease).
Returns True if the last button press was a double click.

The action part of an instance of the pattern InteractionHandler performs the following sequence of code:

do Initialize;
   Loop and call Motion, ButtonPress, ButtonRelease, KeyPress or
   KeyRelease, depending on user action, until 
   TerminateCondition returns True;

As the reader migth have noticed, the interaction handler, when excuted, temporarily replaces the event handler of the canvas and processes all events until terminated.

The InteractionHandler pattern is used to implement the interaction operations of the shapes. The following is an example of how the feedback for InteractiveCreate might be implemented for the predefined shape LineShape, using an InteractionHandler:

RubberLine: InteractionHandler
  (# mousePoint, anchorPoint: @Point; (* Device coords *)
     themodifier: @modifier; (* the modifier used for constrains *)
     stopinteraction: @boolean; (* stop when true *)
     x,y: @integer; (* temporary variables *)

       (# do (anchorpoint, mousePoint) -> immediateLine #);
       do (anchorpoint, mousePoint) -> immediateLine;
          GetPointerLocation -> mousePoint;
          (if themodifier -> isModifierOn then 
             (* constrain the angles *)
             (mousepoint.x-anchorpoint.x) -> abs -> x;
             (mousepoint.y-anchorpoint.y) -> abs -> y;
             (if y > x then (* constrain to vertical *) 
                 anchorpoint.x -> mousepoint.x
              else (* constrain to horizontal *) 
                 anchorpoint.y -> mousepoint.y
          (anchorpoint, mousePoint) -> immediateLine;
     ButtonPress:: (# do true -> stopinteraction #);
     TerminateCondition:: (# do stopinteraction -> res #);
       (# do (anchorpoint, mousePoint) -> immediateLine #);
enter (anchorpoint, mousepoint, themodifier)
exit  mousepoint

The interaction obtained by the above handler works as follows: a rubberband line is spanned between the anchorpoint point and the pointer location, following the pointer movements. In case the modifier is on (e.g. Shift is down) then the angle of the line is constrained to multiples of 90 degrees. The interaction terminates when the pointer button is pressed again.

The Bifrost Graphics System - Reference Manual
© 1991-2004 Mjølner Informatics
[Modified: Monday October 16th 2000 at 13:43]