Interactors package common patterns of user interaction into reusable objects. They are a mechanism originally developed in Brad Meyer's Garnet system. The Slate's interactors are much smaller, lighter, and more numerous than the interactors in Garnet. They are also known as "manipulators" in other systems (and this would perhaps be a better name, since the Slate's interactors are much less general than Garnet's and apply only to graphical items on the Slate). The Slate's interactors are designed to be easy to combine to create complex patterns of interaction from simpler ones. Interactors are built on top of Tk's event-handling mechanism.
Each sub-class of Interactor implements a particular kind of user interaction. Most interactors are based on the observation that user interactions can be broken into a sequence: a click, some number of drags, and a release. (These are abstract operations, and do not necessarily correspond to physical mouse clicks, drags, and releases.)
When an interactor is first created, it can do absolutely nothing.
To enable it to do something, the creator "binds" the interactor to an
object or tag on the Slate. Usually (depending on the interactor
class), this creates a single event binding on the slate that calls the
interactor's activate
method when the mouse button is
pressed on the item.
When invoked by a mouse click (or some other such action), the
activate
method adds some more bindings to the Slate, for
mouse motion and mouse release. It then calls its own
click
method: in this method, the interactor takes whatever
action it thinks is appropriate -- this usually involves at least
remembering the starting coordinates of the interaction sequence, and
forwarding those coordinates onto the interactors target (more
about targets below).
When the mouse is moved, the interactor's drag
method
is called (by the binding set up by activate
).
drag
computes new coordinates, and then forwards them onto
the target. At the termination of the interaction sequence, the user
releases the mouse, which causes the release
and
deactivate
methods to be called. The first performs any
actions needed (usually, not much), while the second restores the Slate
bindings to how they were before the interaction started.
When interaction with an item or st of items is no longer needed,
the interaction bindings can be removed with the unbind
method. There are many more complex variations on this basic sequence
of events, and we are still discovering ways in which interaction can be
characterized and re-used.
An interactor has a "target," which is a Slate item ID, and may have
a "proxy," which is another interactor. If an interactor has a proxy,
then it forwards each interaction event (click, drag, or release) to its
proxy (after calculating and modifying coordinates.) If not, then it
forwards the coordinates to the Slate's interact
method, with
a flag indicating which phase of the interaction it is in. Proxies are
set with the cascade
and uncascade
methods.
The behavior of interactors can be parameterized in two ways:. The first is with configuration options:
apply
procedure) which is
applied to four arguments when the interactor is activated: the
interactor, the target, and the current x and y
coordinates. This is used to customize the behavior of the interactor
depending on information that is not known until activation.
drag
method.
bind
method. Currently, bind
accepts these options: