Programmer's Reference

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:

Register event handlers using theaddEventHandler:receiver:selector:clientData: method.

Tip: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

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.
Tip: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:

type
The type of event that occurred. This has one of the following values: ButtonPress, ButtonRelease, Expose, KeyPress, KeyRelease, and MotionNotify.

window
The CgWindow associated with the widget for which the event was generated.

display
The CgDisplay associated with the event.

For expose events (CwExposeEvent), the method include the following:

count
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.

rectangle
A rectangle describing the damaged area, in the coordinate system of the affected CgWindow.

x
The x-coordinate of the origin of the damaged rectangle.

y
The y-coordinate of the origin of the damaged rectangle.

height
The height, in pixels, of the damaged rectangle.

width
The width, in pixels, of the damaged rectangle.

For input events (CwButtonEvent, CwKeyEvent, and CwMotionEvent), the methods are as follows:

state
A bit mask representing the logical state of modifier keys and pointer buttons just prior to the event. Possible bit masks include: ControlMask, ShiftMask, LockMask, Mod1Mask to Mod5Mask, and Button1Mask to Button3Mask.

x
The x-coordinate of the pointer, relative to the widget in which the event occurred.

y
The y-coordinate of the pointer, relative to the widget in which the event occurred.

point
x @ y

xRoot
A coordinate of the pointer, relative to the screen.

yRoot
A coordinate of the pointer, relative to the screen.

pointRoot
xRoot @ yRoot

time
The time, in milliseconds, at which the event occurred.

For mouse button events (CwButtonEvent), the methods are as follows:

button
The number of the button that was pressed or released (1, 2 or 3).

For key events (CwKeyEvent), the methods are as follows:

keysym
A constant describing the keyboard key that was pressed or released. These constants are found in the CwConstants pool dictionary, and are prefixed with 'XK.'

character
The Character describing the keyboard key that was pressed or released, or nil if it does not represent a valid character.

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.

Tip: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.

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].


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]