Event bindings provide the functionality of binding code to specific event types. The bound code is called a callback. In loon
, we distinguish between four classes of events: state change events, item events, canvas events and content events. Examples of each type of event (in the same order as mentioned before) include: a selected state modification of a plot, moving the mouse cursor over a point glyph, re-sizing the plot window and adding a layer.
For example, a state binding is triggered on particular state changes
set p [plot -x {1 2 3} -y {3 2 1}]
$p bind state add {selected active xTemp} {puts "%W had events: %e"}
The above code creates a plot with three points and adds a state binding that evaluates the callback code puts "%W had event %e"
if any of the states selected
, active
or xTemp
get changed of p
. The %W
and %e
get substituted with the widget path name and a list of the events that were responsible for the code to be evaluated, respectively.
There are also a number of other bindings:
Besides the bind
subcommand we also provide the systembind
subcommand. bind
and systembind
can be used interchangeably. systembind
is used for loon
's own use and no error catching is performed when evaluating system binding code.
State bindings get triggered when widget states change. For more information on widget states see the states documentation.
A configure
call that changes multiple states will collect which states have changed and only evaluate the change bindings once. For example
set p [plot -x {1 2 3} -y {3 2 1}]
$p bind state add {selected active xTemp} {puts "%W had events: %e"}
$p configure -selected {T F F} -size {1 4 3}
#% .l0.plot had events: selected size
$p configure -xTemp {1 1 1}
#% .l0.plot had events: xTemp
A couple of notes:
{selected active xTemp}
in the binding creation specify that any of these events trigger the code evaluation. Or in other words, at least one of the selected
, active
, or xTemp
states must be changed to trigger the code evaluation.%e
substitution is a list with every state that got changed in the particular configure
evaluation.all
for events indicates that every state change should trigger a callback evaluation.destroy
is thrown when a plot gets closed (destroyed).A state binding gets thrown only if at least one state is really changed. Suppose at least one point is not selected, then
$p configure -selected 1
#% .l0.plot had events selected
$p configure -selected TRUE
The above code will only throw one event for the first expression and no event for the second expression, as the selected
state does not change (1
and TRUE
both represent the same logical value).
The current substitutions for state bindings are
string | substituted value |
---|---|
%W |
widget path name |
%e |
states that got changed |
%b |
binding id |
%O |
object path, useful for debugging |
Assume the following plot and bindings
set p [plot -x {1 2 3} -y {1 2 3}]
$p bind state add all {puts A}
$p bind state add {selected active} {puts B}
$p bind state add {showAxes selected} {puts C}
$p bind state add {zoomX panX selected} {puts D}
To list the bindings use
$p bind state ids
#% stateBinding0 stateBinding1 stateBinding2 stateBinding3
To get the binding events and callback say for stateBinding0
use
$p bind state get stateBinding0
#% all {puts A}
The order of binding evaluation is as returned by bind state ids for those bindings that are triggered by a particular state change. For the above example all bindings are triggered by a selected
state change, hence, changing the selected state of p
would print A
, B
, C
and D
. The evaluation can be reversed/changed as follows
$p bind state reorder [lreverse [$p bind state ids]]
Now a change of the selected
state of p
would cause to print the letters D
,. C
, B
, A
.
Finally, to delete a binding use
$p bind state delete stateBinding0
Next to a loon
's displays the layers, glyphs, navigators and contexts support state bindings too. We now demonstrate this with a layer state binding (note that this it will work with all the other types the same).
set p [plot -x {1 2 3} -y {1 2 3}]
set l [$p layer rectangle -x {1 3} -y {1 3} -color blue]
$p layer use $l bind state add color {puts "layer color has changed"}
$p layer use $l configure -color green
#% layer color has changed
Item bindings are triggered by a mouse/keyboard gesture over a visual item in a plot. Visual items include point glyphs, layers, axes and labels. Every visual item has a set of tags as outlined in the Visual Item Tags section. In addition, displays and layers have a tag
state for user specified tags.
Note that item bindings are Tk
canvas bindings with one level of indirection in order to support loon's context specific substitutions instead of the standard Tk
substitutions.
Valid event patterns for mouse/keyboard gestures are taken from the Tk
bindings. The tag specification for item bindings allow for logical expressions of Visual Item Tags using the operators &&
, ||
, ^
,!
, and parenthesized subexpressions (see the Tk
canvas manual).
To get the tags for the item that lies below the mouse cursor use the currenttags
subcommand. To get the index (in relation to the abstract dimension) of the visual item below the mouse cursor (if there is an index) use the currentindex
subcommand.
For example, say we wish to print out the point number in a scatterplot on leaving and entering the point
set p [plot -x {1 2 3} -y {1 2 3}]
$p bind item add "model&&point" <Enter> {puts "Entered point [%W currentindex]"}
$p bind item add "model&&point" <Leave> {puts "Left point [%W currentindex]"}
The item binding API also support List, Reorder & Delete Bindings, but the item binding order has currently no effect.
The current substitutions for item bindings are
string | substituted value |
---|---|
%W |
widget path name |
%b |
binding id |
%O |
canvas path, useful for debugging |
%x |
x coordinate |
%y |
y coordinate |
Visual items have tags. It is possible to add user defined tags with the tag
state for the relative object (i.e. plot and layer). There are, however, also tags that we use which are listed in the table below.
It is possible to query the item tags interactively with a mouse button press on an item as follows
set p [plot -x {1 2 3} -y {1 2 3} -xlabel xlab\
-ylabel ylab -title "Query Visual Item Tags"]
$p bind item add all <Enter> {puts "[%W currenttags]"}
all
, current
and selected
are reserved tags used by Tk
The current tagging scheme for the histogram, scatterplot and graph displays is
Canvas bindings are in contrast to the item bindings triggered by a mouse/keyboard gesture over the plot as a whole. Canvas bindings are for example useful if one wants to capture plot resize events or a mouse moving events.
As for item bindings the valid event patterns for mouse/keyboard gestures are taken from the Tk
bindings.
For the first example, we print the size of the plot when it gets resized.
set p [plot -x {1 2 3} -y {1 2 3}]
proc printSize {widget width height} {
puts [format "Size of widget %s is %sx%s pixels" $widget $width $height]
}
$p bind canvas add <Configure> {printSize %W %w %h}
Or, say, we want to track the mouse and print out its location in data coordinates
set p [plot -x {1 2 3} -y {1 2 3}]
proc printLocation {widget x y} {
puts [format "In widget %s the location of the mouse cursor is at: %s and %s"\
$widget $x $y]
}
$p bind canvas add <Motion> {printLocation %W %x %y}
The current substitutions for canvas bindings are
string | substituted value |
---|---|
%W |
widget path name |
%b |
binding id |
%O |
canvas path, useful for debugging |
%x |
x coordinate |
%y |
y coordinate |
%w |
plot width in pixel |
%h |
plot height in pixel |
There are also layer, glyph, navigator and context bindings. These bindings get evaluated if the collection of one of those changes. For example
set p [plot -x {1 2 3} -y {1 2 3}]
$p bind layer add {add delete} {puts "Widget %W had event %e for layer: %l"}
$p layer texts -x {2 2} -y {1.5 2.5} -text {A B}
#% Widget .l0.plot had event add for layer layer1
Valid events for the different types are
all
, add
, delete
, move
, relabel
, hide
, show
all
, add
, delete
, relabel
all
, add
, delete
, relabel
all
, add
, delete
, relabel