## 5.5 Events

binding to events

Button widgets allow to specify an action which is invoked when the button is pressed. This is only one particular example of attaching an action to an event. The Tk toolkit allows to attach actions to any widget with the method `tkBind`. To attach an action to an event we refer to as binding the action to the event. The action is invoked when some event occurs. Examples for events are to move the mouse pointer within a widget, or to press a mouse button when the mouse pointer is over a widget. Actions can be given arguments. The arguments depend on the type of the event, e. g., arguments can be the coordinates of the mouse pointer.

Let us look to the example from the previous section. There we created a menu widget `M1` and a toplevel widget `T`. Now we want that the menu widget is posted if the mouse button is pressed over the toplevel widget `T`. Additionally, we want the menu to get posted at the position of the mouse pointer when the mouse button was pressed.

event patterns

The program in Figure 5.5 does what we want: `'<Button-1>'` for the `event` option is the so-called event pattern. The value for the `args` option describes that the action should invoked with two arguments. The first (second) one should be an integer giving the x (y) coordinate of the mouse pointer within the widget when the mouse button has been pressed. The `action` procedure pops up the menu widget at exactly the screen coordinates. These are computed from the coordinates of the upper left edge of the toplevel widget and the event arguments.

### 5.5.1 Event Patterns

An event pattern is either a string consisting of a single character, where the character must be different from the space character and `<`. This event pattern matches a `KeyPress` event for that character.

Otherwise, an event pattern must be a string

> `'<'#``Modifier``#'-'#``Modifier``#'-'#``Type``#'-'#``Detail``#'>'`

where only one of either `Type` or `Detail` is mandatory. This means, for example that also

> `'<'#``Type``#'>'`

or

> `'<'#``Detail``#'>'`

are valid event patterns.

event modifiers and types

Figure 5.6 shows common event modifiers and event types. Multiple entries separated by commas can be used as synonyms. The full set of modifiers and types is described in `bind`.

Event Modifier
`Control` | `Shift` | `Lock` | `Meta` | `Alt`
`Button1`, `B1` | `Button2`, `B2` | `Button3`, `B3` | `Button4`, `B4` | `Button5`, `B5`
`Double` | `Triple` |  |  |

Event Type | Description
--- | ---
`Key`, `KeyPress` | key has been pressed
`KeyRelease` | key has been released
`Button`, `ButtonPress` | mouse button has been pressed
`ButtonRelease` | mouse button has been released
`Enter` | mouse pointer has entered a widget
`Leave` | mouse pointer has left a widget
`Motion` | mouse pointer has been moved within widget

Figure 5.6: Some event modifiers and types.

For example, the event pattern

> `'<Shift-Double-Button>'`

matches the event that a mouse button is double-clicked while the shift key is pressed.

If the event is `ButtonPress` or `ButtonRelease`, `Detail` may be the number of a mouse button. The number must be between `1` and `5`, where `1` is the leftmost button. The number as detail means that only events from pressing or releasing this particular button match. If no detail is given, pressing or releasing any button matches the event. If a number is given as detail, `ButtonPress` can be omitted, e. g., `<ButtonPress-1>` and `<1>` match the same events.

If the event is `KeyPress` or `KeyRelease`, `Detail` may be the specification of a key-symbol, e. g., `comma` for the , key. For more information please consult `bind`.

### 5.5.2 Event Arguments

The `args` option of the `tkBind` method takes a list of argument specifications. An argument specification describes the type of the argument and the argument itself. Figure 5.7 shows the valid types and some arguments. The types mean the same as the types for the different return methods as discussed in Section 5.3.

Argument Type
`string(``A``)`, `A` | `atom(``A``)` | `int(``A``)` | `float(``A``)`
`list(string(``A``))`, `list(``A``)` | `list(atom(``A``)` | `list(int(``A``)` | `list(float(``A``)`

Event Argument | Description
--- | ---
`x` | x coordinate
`y` | y coordinate
`K` | string describing the symbol of the key pressed
`A` | character describing the key pressed

Figure 5.7: Event arguments.

### 5.5.3 Invoking Actions

When an event matches an event pattern to which an action has been bound by `tkBind`, a new thread is created in which the action is executed. If the action is a procedure the arity of the procedure has to be equal to the length of the argument list specified in `tkBind`.

If the action is a pair of object and message, the object is applied to message with the arguments appended. For example, after creating an event binding by

> `{T tkBind(event: '<1>'
> args: [int(x)]
> action:` `O``# invoke(button))}`

pressing the leftmost button at x-coordinate 42 creates a thread that executes the statement

> `{``O` `invoke(button 42)}`

### 5.5.4 Appending and Deleting Event Bindings

If `tkBind` is used as before, any other existing binding for the event pattern specified is overwritten. If no action is specified any existing binding for the event pattern is deleted.

For a single event pattern there may be more than one binding. To create an event binding that does not overwrite already existing bindings, we can give the option `append` with value `true`. For instance, if we do not only want to popup the menu but also to display `pop` in the Browser, we can create an additional binding by

  `{W tkBind(event: '<1>'
  append: true
  action: proc {$} {Browse pop} end)}`