Events Dispatch, event-to-code binding Review: Events Defined 1. An observable occurrence, phenomenon, or an extraordinary occurrence. 2. A message to notify an application that something happened. Examples: Keyboard (key press, key release) Pointer events (button press, button release, motion) Window crossing (mouse enters, leaves) Input focus (gained, lost) Window events (exposure, destroy, minimize) Timer events 2 1
Review: Event Dispatch Which part of the interface should receive the event? How do we get the correct code to execute in response to an event? Questions: - Which window? Which widget? Positional dispatch Bottom-up dispatch Top-down dispatch Focus dispatch (and after dispatch, how do we bind the event with code?) 4 Lightweight vs. Heavyweight Widgets Lightweight widgets - BWS/OS provides a top-level window - Widget toolkit draws its own widgets and is responsible for mapping events to their corresponding widgets - Examples: Java Swing, JQuery UI, Windows WPF, WatGUI Heavyweight widgets - Each widget is its own window (where window is not just what we typically call a window every control is a window) - OS provides a hierarchical windowing system for all widgets - Widget toolkit wraps OS widgets for programming language - BWS can dispatch events to a specific widget - Examples: nested X Windows, Java s AWT, OS X Cocoa, standard HTML form widgets, Windows MFC 5 CS 349 S13 - Widgets 2
Window Dispatch with BWS 6 Positional Dispatch Strategy: send input to widget under mouse cursor Issue: many widgets can overlap, which one should receive the event? Two methods: - Bottom-up - Top-down 7 3
Bottom-up Positional Dispatch Event is first routed to leaf node widget in the interactor tree corresponding to location of mouse cursor Leaf node has first opportunity to act on that event The leaf node widget can either: 1. process the event itself 2. pass the event to its parent (who can process it or send to its parent...) 8 Passing to Parent Why would a widget pass an event to its parent? - Example: A palette of colour swatches may implement the colours as buttons. But palette needs to track the currently selected colour. Easiest if the palette deals with the events. 9 4
Top-down Positional Dispatch Event is routed to widget in the highest-level node in the interactor tree that contains the mouse cursor - Can process the event itself - Can pass it on to a child component Key idea is that highest-level node has first chance at acting on the event Uses: - Can create policies that are enforced by parent For example, stopping events if all children are disabled - Supports relatively easy logging of events for later replay 10 Top-down vs. Bottom-up Dispatch To end-user, no difference in how interface behaves Just slightly different implementations disabled container widget policy 11 5
Positional Dispatch Limitations Positional dispatch can lead to odd behaviour: - Send keystrokes to scrollbar if mouse over the scrollbar? - Mouse drag starts in a scrollbar, but then moves outside the scrollbar: send the events to the adjacent widget? - Mouse press event in one button widget but release is in another: each button gets one of the events? Sometimes position isn t enough, also need to consider which widget is in focus 12 Focus Dispatch Events dispatched to widget that has focus, regardless of mouse cursor position Needed for all keyboard and some mouse events: - Click on text field, move cursor off, start typing (keyboard focus) - Mouse down on button, move off, mouse up (mouse focus) also called mouse capture Maximum one keyboard focus and one mouse focus Need to gain and lose focus at appropriate times - Transfer focus on mouse down - Transfer focus on a tab 13 6
Focus Dispatch Needs Positional Dispatch If a widget has focus, it should not receive every event: - mouse down on another suitable widget should change focus Often helpful to have an explicit focus manager in a container widget to manage which widget has the focus. 14 Accelerator Key Dispatch Keyboard events dispatched based on which keys are pressed Register special keyboard accelerators with specific commands - commands are often the target of menu item events The GUI toolkit intercepts accelerators and forwards to the appropriate command handler 15 7
Dispatch Summary Mouse-down events are almost always positional: dispatched to widget under cursor (top-down or bottom-up) Other mouse and keyboard events go to widget in focus 16 Event-to-Code Binding BWS and widget toolkit decide which widget event should be dispatched to Once the event arrives at the widget, the next step is to have application logic interpret the event Key question: How do we design our GUI architecture to enable application logic to interpret events once they ve arrived at the widget? Desiderata for design: - Easy to understand (clear connection between events and code) - Easy to implement (using a binding paradigm or API) - Easy to debug (how did this event get to this piece of code?) - Good performance 17 8
Event Loop and Switch Statement Binding (X11) All application events are consumed in one event loop Outer switch statement selects window and inner switch selects code to handle the event Used in Xlib, Apple System 7, and, until recently, Blender while( true ) { XNextEvent(display, &event); // wait for next event switch(event.type) { case Expose: //... handle expose event... cout << event.xexpose.count << endl; break; case ButtonPress: //... handle button press event... cout << event.xbutton.x << endl; break; 18... WinowProc Binding (MS Windows) Each window registers a WindowProc function (Window Procedure) which is called each time an event is dispatched The WindowProc uses a switch statement to identify each event that it needs to handle. - There are over 100 standard events LRESULT CALLBACK WindowProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { switch (umsg) { case WM_SIZE: { int width = LOWORD(lParam); // low- order word. int height = HIWORD(lParam); // high- order word. // Respond to the message: OnSize(hwnd, (UINT)wParam, width, height); break; 19 9
Inheritance Binding (Java 1.0, NeXT, OSX) Event is dispatched to an Object-Oriented (OO) widget OO widget inherits from a base widget class with all event handling methods defined a priori - onmousepress, onmousemove, onkeypress, etc The widget overrides methods for events it wishes to handle e.g. Java 1.0, NeXT, OSX 23 public class MyMarvelousPanel extends JPanel { protected void processmousemotionevent(mouseevent e) { // only detects button state WHILE moving! if (e.getid() == MouseEvent.MOUSE_DRAGGED) colour = Color.RED; else colour = Color.GRAY; x = e.getx(); y = e.gety(); repaint(); 24 10
Inheritance Problems 1. Each widget handles its own events, or widget container has to check what widget the event is meant for 2. Multiple event types are processed through each event method: complex and error-prone (just a switch again) 3. No filtering of events: performance issues (e.g. with frequent events, like mouse move events) 4. It doesn t scale well: How to add new events? - e.g. penbuttonpress, touchgesture,. 5. Muddies separation between GUI and application logic: event handling application code is in inherited widget Take-home point: Use inheritance for extending class functionality, not for binding events 27 Event Interfaces Rather than subclass widget, define an interface for event handling Here, an interface refers to a set of function or method signatures for handling specific types of events For example, in Java, can define an interface for handling mouse events Can then create a class that implements that interface by implementing methods for handling these mouse events 28 11
Listener Interface Binding (Java) Widget object implements event listener interfaces - e.g. MouseListener, MouseMotionListener, KeyListener, When event is dispatched to widget, the relevant listener method is called - mousepressed, mousemoved, 29 public class MyAwesomePanel extends JPanel implements MouseMotionListener { MyAwesomePanel() { this.addmousemotionlistener(this); // add listener public void mousedragged(mouseevent e) { x = e.getx(); y = e.gety(); // Change state of app in some meaningful way repaint(); public void mousemoved(mouseevent e) { /* no- op */ 30 12
Interface Better, But Still Problems Improvements: - Each event types assigned to an event method - Events are filtered: only sent to object which implements interface - Easy to scale to new events, just add new interfaces e.g. PenInputListener, TouchGestureListener,. Problems: 1. Each widget handles its own events, or widget container has to check what widget the event is meant for 2. Muddies separation between GUI and application logic: event handling application code is in inherited widget 31 Listener Object Binding (Java 1.1) Widget object is associated with one or more event listener objects (which implement an event binding interface) - e.g. MouseListener, MouseMotionListener, KeyListener, When event is dispatched to a widget, the relevant listener object processes the event with implemented method: mousepressed, mousereleased, application logic and event handling are decoupled 32 13
MouseListener public class MyImportantPanel extends JPanel { ListenerEvents() { this.addmousemotionlistener(new MyPanelListener()); // inner class listener class MyPanelListener implements MouseMotionListener { public void mousedragged(mouseevent e) { x = e.getx(); y = e.gety(); // Make some meaningful change to app repaint(); public void mousemoved(mouseevent e) { /* no- op */ 33 Listener Adapter Pattern Many listener interfaces have only a single method - e.g. ActionListener has only actionperformed Other listener interfaces have several methods - e.g. WindowListener has 7 methods, including windowactivated, windowclosed, windowclosing, Typically interested in only a few of these methods. Leads to lots of boilerplate code with no-op methods, e.g. void windowclosed(windowevent e) { Each listener with multiple methods has an Adapter class with no-op methods. Simply extend the adapter, overriding only the methods of interest. 34 14
MouseMotionAdapter public class AdapterEvents extends JPanel { AdapterEvents() { this.addmousemotionlistener(new MyListener()); class MyListener extends MouseMotionAdapter { public void mousedragged(mouseevent e) { x = e.getx(); y = e.gety(); // Do something meaningful here repaint(); 35 WatGUI Toolkit WatGUI s Timer class has hooks for a TimerListener object TimerListener is equivalent to an interface: Defines an interface for a class, but doesn t implement anything meaningful Any object derived from TimerListener will be notified whenever the Timer s predesignated time has elapsed StopWatch derived from TimerListener 36 15
Delegate Binding (.NET) Interface architecture can be a bit heavyweight Can instead have something closer to a simple function callback (a function called when a specific event occurs) Delegates in Microsoft s.net are like a C/C++ function pointer for methods, but they: - Are object oriented - Are completely type checked - Are more secure - Support multicasting (able to point to more than one method) Using delegates is a way to broadcast and subscribe to events.net has special delegates called events 37 Using Delegates 1. Declare a delegate using a method signature public delegate void Del(string message); 2. Declare a delegate object Del handler; 3. Instantiate the delegate with a method // method to delegate (in MyClass) public static void MyMethod(string message) { System.Console.WriteLine(message); handler = myclassobject.mymethod; 4. Invoke the delegate handler( Hello World ); 38 16
Multicasting Instantiate more than one method for a delegate object handler = MyMethod1 + MyMethod2; handler += MyMethod3; Invoke the delegate, calling all the methods handler( Hello World ); Remove method from a delegate object handler - = MyMethod1; What about this? handler = MyMethod4; 39 Events in.net Events are a delegate with restricted access - (or Events are implemented with a delegate) Declare an event object instead of a delegate object: public delegate void Del(string message); event Del handler; event keyword allows enclosing class to use delegate as normal, but outside code can only use the -= and += features of the delegate Gives enclosing class exclusive control over the delegate Outside code can t wipe out delegate list, can t do this: - handler = MyMethod4; 40 17
WatGUI Toolkit Has event types defined (e.g., MouseEvent), but method for responding to events is not defined in architecture For the curious: The Scheme interpreter actually supports a form of delegates for responding to - You register a Scheme function with a SchemeComponent to be notified when a particular event has occurred - But outside scope of this class (translation: You don t need to know this) - Talk to Professor Terry if interested in learning more 41 OS X Uses Inheritance and Delegate Binding Inheritance Binding - When an NSWindow object receives a mouse-down event, it asks the widget (an NSView object) under the event if it wants to handle the event (if that NSView s acceptsfirstresponder method returns YES). If so, it will call the method (a message ) from NSView for the event, such as mousedragged Delegate Binding 44 18
Events for High Frequency Input Pen and touch input can generate many events very quickly - pen motion input can be 125Hz - multitouch hardware can generate many simultaneous contactmove events for all fingers which are touching - pen sensor is much higher resolution than display Not all events guaranteed to be delivered individually - All pendown and penup, but may skip some penmove events - Event object includes array of skipped penmove positions - Android does this for touch input For things like pen input, will use other methods to grab these events because of their high rate of generation 49 19