Event handlers are another mechanism used to inform the application of input actions by the user. While callbacks notify the application of high level interactions such as the selection of items in a list widget, event handlers notify the application of low level interactions, including the following:
Register event handlers using theaddEventHandler:receiver:selector:clientData: method.
The addEventHandler:receiver:selector:clientData: method takes four parameters:
The eventMask is specified as the bitwise-OR of one
or more of the bit masks described in the following table.
Table 34. Common widgets event masks
Event masks | Description |
---|---|
KeyPressMask | Keyboard key down events |
KeyReleaseMask | Keyboard key up events |
ButtonPressMask | Mouse button down events |
ButtonReleaseMask | Mouse button up events |
PointerMotionMask | All pointer motion events |
Button1MotionMask | Pointer motion events while button 1 is down |
Button2MotionMask | Pointer motion events while button 2 is down |
Button3MotionMask | Pointer motion events while button 3 is down |
ButtonMotionMask | Pointer motion events while any button is down |
ButtonMenuMask | Button menu request events |
When an event handler method is run, it is passed three arguments:
The following table describes the class hierarchy for event objects.
Classes in italics are abstract classes.
Table 35. Event class hierarchy
Class hierarchy | Responsibility. |
---|---|
CwEvent | Defines common behavior for event data in event handlers. |
CwExposeEvent | Provides event data for expose events in expose callbacks (see Note below). |
CwInputEvent | Defines common behavior for button, key, and motion event objects. |
CwButtonEvent | Provides event data for mouse button-press/release events. |
CwKeyEvent | Provides event data for key-press/release events. |
CwMotionEvent | Provides event data for mouse motion events. |
The following messages can be sent to the event object to retrieve information about the event. The methods for all events (CwEvent) include the following:
For expose events (CwExposeEvent), the method include the following:
For input events (CwButtonEvent, CwKeyEvent, and CwMotionEvent), the methods are as follows:
For mouse button events (CwButtonEvent), the methods are as follows:
For key events (CwKeyEvent), the methods are as follows:
There are two common uses of event handlers. The first is for handling input in a drawing area widget. For example, in a graphical drawing application a drawing area widget would be used to display the drawing under construction. Event handlers would be registered to notify the application of pointer motion, mouse button, and key press events, allowing text strings to be edited and graphical objects to be positioned and changed using the mouse.
The second common use is for handling pop-up menus. An event handler is added for the ButtonMenuMask event. When the event handler is called, the application pops the menu up.
Mouse button 3 is used as the menu button. However, some platforms trigger the button menu event when the button is pressed, and others when the button is released. The ButtonMenuMask event hides this difference. It should be used, rather than the other button events, to support pop-up menus in a platform-independent manner.
In the following example, a drawing area is created, and an event handler is added to notify the application of mouse button presses, key presses, and pointer motion. Label widgets are used to display information about the events. The variable labels would be implemented as an instance variable for the class.
| shell rowColumn label labels drawing | shell := CwTopLevelShell createApplicationShell: 'shell' argBlock: [:w | w title: 'Event Handler Example'].
rowColumn := shell createRowColumn: 'rowColumn' argBlock: nil. rowColumn manageChild.
labels := Array new: 3. 1 to: 3 do: [:i | label := rowColumn createLabel: 'label' argBlock: nil. label manageChild. labels at: i put: label].
(labels at: 1) labelString: 'Position: '. (labels at: 2) labelString: 'Button pressed at position: '. (labels at: 3) labelString: 'Keysym of last pressed key: '.
drawing := rowColumn createDrawingArea: 'drawing' argBlock: [:w | w borderWidth: 1; width: 300; height: 300].
drawing addEventHandler: ButtonPressMask | KeyPressMask | PointerMotionMask receiver: self selector: #eventHandler:clientData:event: clientData: nil. drawing manageChild. shell realizeWidget
When an event occurs, the following method is run. Information about the event is determined from the event argument and is displayed in the label widgets.
eventHandler: widget clientData: clientData event: event "Handle an input event."
event type = MotionNotify ifTrue: [(labels at: 1) labelString: 'Position: ', event point printString].
event type = ButtonPress ifTrue: [(labels at: 2) labelString: 'Button ', event button printString, ' pressed at position: ', event point printString].
event type = KeyPress ifTrue: [(labels at: 3) labelString: 'Keysym of last pressed key: ', event keysym printString].