Common Widgets : Creating and using widgets : Event handlers

Event handlers
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:
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.
C:\Users\documentation\Documents\vastePublisher\stable\VAS Documentation Word\images\tips.gif
On some platforms it is possible for a button release event to be delivered without a corresponding button press event. Applications should be prepared to ignore such spurious button release events by only processing a button release event that is received after a matching button press event.
Registering an Event
Register event handlers using the addEventHandler:receiver:selector:clientData: method.
C:\Users\documentation\Documents\vastePublisher\stable\VAS Documentation Word\images\tips.gif
The argBlock argument of a widget-creation message can only be used to set widget resources. The addEventHandler: message cannot be used within the create argBlock. Event handlers are usually registered immediately after the widget has been created, and before it is realized.
The addEventHandler:receiver:selector:clientData: method takes four parameters:
eventMask
A bit mask specifying which events to notify the receiver of
receiver
The object that receives the event handler message
selector
The 3-parameter event handler message selector
clientData
Optional data that is passed to the event handler when it is run
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
Running an Event
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
Tip icon
An expose event handler cannot be explicitly added to a widget. A CwExposeEvent object is passed to an application as part of the call data for an exposeCallback.
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:
The type of event that occurred. This has one of the following values: ButtonPress, ButtonRelease, Expose, KeyPress, KeyRelease, and MotionNotify.
The CgWindow associated with the widget for which the event was generated.
The CgDisplay associated with the event.
For expose events (CwExposeEvent), the method include the following:
The number of expose events which remain for the affected CgWindow. A simple application might want to ignore all expose events with a nonzero count, and perform a full redisplay if the count is zero.
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:
The Character describing the keyboard key that was pressed or released, or nil if it does not represent a valid character.
Example
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: labels.
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."
 
| labels |
labels := clientData.
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].