Event Handling

GLAM's event handling architecture is built upon an essential dichotomy, namely the separation of user input from widget communication. Event handling in GLAM therefore consists of the following two different subsets: User Events and Widget Actions & Listeners.

Figure 2.3. Simple Diagram of GLAM Event Handling

Simple Diagram of GLAM Event Handling

User Events

In most windowing toolkits, there usually exists a master controller of some form or another. The UI toolkit assumes the responsibility of handling all user input. While this method provides a very straight-forward approach to application design, it does not fit well with most visualization-centric applications.

GLAM's event model utilizes a more free-form approach. It is up to the application to generate and send user events to the event distributor, which then sends them to the proper widget. The widget is then responsible for handling the event in an appropriate fashion. This approach allows for a much more flexible integration paradigm than the traditional "the application revolves around the UI toolkit". Rather, with GLAM "the UI toolkit revolves around the application".

There are several important user event classes that the developer should be aware of, namely:

Important event classes

GmEvent

The GmEvent class is the base class for all user events and encapsulates much of the information needed by events into a single object. Mouse and keyboard events are encapsulated into a single GmEvent object. These event objects are then passed around the GLAM architecture until they reach their destination. All events have a receiver ID to identify the target widget. If an event represents mouse input, the mouse's coordinates will be recorded in the event both as screen coordinates and as openGL units.

GmEventDistributor

The GmEventDistributor singleton is responsible for distributing all developer generated events to their target components. The GLAM event distribution model is completely open ended, in that a developer can decide when and how to create user events and to which target that event gets delivered.

Widget Actions & Listeners

The Actions and Listener interface provides a means for inter-widget communication. The event distribution architecture handles only external input events (directly from the user), so a robust internal action architecture was created. Widgets can implement certain types of listening interfaces. Using those interfaces, they can register with other widgets to recieve actions. This allows widgets to 'talk' to each other.

Another purpose for this architecture is highlighted through an understanding of the difference between, for example, a mouse button click (a user event) and a "button press." A button press is generally not as simple as a mouse click. A user may, for instance, click on a button, continue holding the mouse button, leave the button and return before releasing the mouse button again. This action is considered a "button press." Understanding who is responsible for handling this kind of behavior is where actions and listeners play their role.

As can be seen from our previous example, it is the button widget that actually determines its own function, not a mouse click. The same is true for all other widgets in GLAM. With this in mind, the architecture for widget "action" handling was devised.

In GLAM, user events are generated and assigned to certain widgets by the developer. The widget is then responsible for how it will handle the user event. In this manner, the function of a widget will determine what a widget is. For instance, the function of a button is the abstract "button press" action, as previously described. A button widget and how the user will interact with it is determined by its function. By virtue of this important design, the form of a widget follows its function.

As user events are translated by widgets into the appropriate behavior, a more abstract communication layer is developed. The actions that widgets perform in response to a user event can be "listened" to by other widgets or classes. This is accomplished through the implementation of various listener interfaces. For each type of abstract widget action, a widget listener interface is available. In keeping with the previous button examples, button actions can be listened to by implementing a button listener.

The developer is expected to extend the core set of action and listener classes provided in GLAM when necessary to accomplish the specific goals of his application. Below are the base action and listener classes, as well as some core action & listener classes and some widgets that support them.

Base Action & Listener in GLAM

GmWidgetAction

The GmWidgetAction class is the base class for all widget actions.

GmWidgetListener

The GmWidgetListener class is the base interface for all widget listeners.

Examples of Core Actions & Listeners in GLAM

GmButtonAction

The GmButtonAction class describes a button action. A button widget generates a button action when it is "pressed."

GmButtonListener

The GmButtonListener class handles GmButtonActions.

Examples of supporting widgets

  • GmButton

  • GmCheckBox

  • GmRadioButton

GmFocusAction

The GmFocusAction class describes a focus action. A focusable widget generates a focus action when a user event modifies its focus.

GmFocusListener

The GmFocusListener class handles GmFocusActions.

Examples of supporting widgets

  • All GmInteractiveWidgets

GmScalarAction

The GmScalarAction class describes a scalar action. A scalar widget generates a scalar action when its value is changed.

GmScalarListener

The GmScalarListener class handles GmScalarActions.

Examples of supporting widgets

  • GmBarMeter

  • GmScrollbar

  • GmSlider

GmSelectionAction

The GmSelectionAction class describes a selection action. A widget that supports selection generates a selection action when one of its components is selected.

GmSelectionListener

The GmSelectionListener class handles GmSelectionActions.

Examples of supporting widgets

  • GmCheckBox

  • GmMenu

  • GmMenuBar

  • GmRadioButton