Table of Contents Previous Chapter

CHAPTER 8 User Interface


8.1 WFO-Advanced UI Philosophy

The user interface on PROFS and FSL workstations has been a key consideration of the overall workstation design from the beginning, receiving a great deal of time and attention. Our approach has been to design, build, and then modify (sometimes extensively) prototypes based on user feedback The feedback is usually generated in a pseudo real-time forecast exercise which approaches actual operational use. Over the years, many designs have been tried. The interface has evolved based on this experience and in keeping with advances in computer technology. For example, early PROFS workstations utilized dedicated menu screens with a variety of product selection methods including command line, light pen, and touch screen. These generally worked satisfactorily when there were only a few products available as was the case with the early workstations. As the number of available products increased, however, it became necessary to use more precise and efficient product selection methods.

By the mid 1980s the mouse had become the industry device of choice for user input and selection. We quickly adopted it as well. Its precise point and click capabilities allowed us to include many more menu choices (buttons) on the screen. However, even with the mouse, our user interface continued on a separate dedicated screen for some time. This configuration created serious ambiguity problems when we began using one selection device to drive two display screens. It also had the disadvantage of requiring an additional display screen per workstation. Eventually, the separate menu screen was abandoned when windowing technology became available.

With the emergence of the X window system, it became feasible for menus to share the data-display screen. Again, we quickly began to take advantage of this advance in technology. However, the ability to have multiple display windows on a single screen immediately presented us with a fundamental user interface issue: What is the best way to control multiple windows on an operational meteorological workstation? It is typical using X to have multiple windows open simultaneously, each with its own set of menus and controls. Initially, we experimented with three UI approaches: 1) multiple windows each with their own menu, 2) multiple windows loading from a single menu, and 3) a "fixed panes" approach with menus loading to one main window. We tested prototypes of the first 2 of these interfaces in early versions of WFO-Advanced and found that they both presented many difficult operational problems. With multiple windows open, the forecaster faced difficult window management and input ambiguity issues. These problems were exacerbated in the "heat of battle" when they could least be afforded.

We believe that an operational forecast workstation must differ substantially from the standard X philosophy. FSL's approach assumes that a forecaster workstation is not simply a collection of related applications, but should be a tightly integrated system of tools and capabilities in which frequent interaction with displayed data is the norm. If there is little data integration or forecaster interaction with the data, then UI options 1 or 2 (above) would probably be preferable. The forecaster could simply load a particular data set, say an IR image loop, into a window and passively let it run for long periods. We currently see some workstations used this way. However, the forecasting environment as envisioned for the AWIPS era, and more particularly the short-term warning environment, demands a time-efficient and unambiguous user interface.

This experience and user feedback from the first two FX-Advanced prototypes drove us to the latter of the above three options, the fixed panes approach with menus loading to one main window. Although less flexible, this layout provides a more structured environment for operational use. In addition, and to support the need for time efficiency, the single menu/single load window solution best accommodates tear-away menus which allow users to bypass the normal menu hierarchy and quickly load desired products.

The selection of the fixed 5-pane display area involved careful trade-offs. We traded some flexibility for simplicity and efficiency. This approach virtually eliminates window management tasks and searching through window stacks for a desired display or menu, yet it allows multiple datasets to be visible at the same time with the ability to quickly swap between the main window and the smaller monitor windows when needed. It may not be obvious to the casual observer that this trade-off is the optimum, but the experience in real-time forecasting experiments and in actual meteorological operations validates the benefits of this approach over the others that have been tried.

8.1.1 Layout

The interface for WFO-Advanced can be configured in several ways. The preferred configuration is a mouse, keyboard, and keypad for each graphic display screen. This allows a two headed system to be used by two users when circumstances call for it. This configuration includes two X servers, one for each screen, providing a somewhat more responsive system. This requires some additional memory in the workstation.

Other configurations are also possible. The keypads can be removed, for instance. The impact is that experienced users are slowed somewhat in their interaction with displayed data. While all of the functions can be exercised via buttons, pop-ups, and menus using the mouse on the display screen, this requires significant additional mouse travel.

Another option is a single mouse/keyboard for two screens. This has been run experimentally at FSL. In this case, a single X server is used for the two display screens. Although forecasters were trained to use this and most felt comfortable, it has not been tested operationally at Denver. The loss of flexibility wherein only one user can operate the two graphic displays raised sufficient concern that it has not been implemented operationally. The ability for another user to operate one of the displays has been considered of such importance to the smooth operation of the office that the single user interface was not set up in Denver.

8.2 User Interface Library

8.2.1 Overview

The User Interface class library was designed to be used to construct Graphical User Interface (GUI) components and presentations for all FX-Advanced components that require a user interface. Essentially, it is the description of building blocks to be used to create a GUI. The design does not dictate how a GUI will look, but rather provides the flexibility to use a set of components with which a GUI that is appropriate for an application can be constructed and customized. The components' look and feel are restricted to be similar to Motif widgets.

The library design has three major objectives:

  1. Hide the implementation. Provide an interface that encapsulates and hides the underlying implementation. This will allow us (albeit with significant effort) to base the library on a different underlying product (e.g., Motif API instead of OI) without requiring any recoding of library clients.
  2. Uniform look-and-feel. Provide a uniform look-and-feel for FX-Advanced components and applications that is automatically and centrally controlled and enforced. For instance, we could change the visual appearance of PushButtons in one place and have that change apply to all PushButtons in our system. Clients may need to re-link but client code will be unaffected. This goes well beyond the level of enforcement of look-and-feel provided by the Motif style guide.
  3. Simplified API. Create a simplified programmer's interface to user interface elements. We will accomplish this by
    · creating a smaller API with fewer options,
    · providing automated layout assistance,
    · tailoring the available user interface elements for our needs, and
    · providing an easy-to-use mechanism for library extensions.
The library provides:
  1. Basic elements that we will use in our user interface:
    · buttons (PushButtons, ToggleButtons, and MenuButtons);
    · menus for containing buttons;
    · value entry fields for user input of numeric values and character strings;
    · sliders for user selection of numeric values;
    · PictureAreas for display of image and graphic data;
    · TextAreas for display and edit of text data; and
    · ManagedWindows, that is, top-level windows with window-manager specific borders and decorations and under the control of the workstation window manager (e.g., Motif or HP VUE).
  2. Panes, used to specify the visual layout organizations ("geometry" in Motif parlance) of other elements.
    · They provide automated layout assistance via an attribute that allows the client to specify left to right or top to bottom orientation for the contents, and
    · they may be nested.
  3. Infrastructure for constructing reusable complex elements (such as a time range selection dialog) that are developed as extensions to the library.
The major classes and inheritance relations are shown in Figure8.1.

Figure8.1 Overview of major classes and inheritance relations

The object hierarchy of UI lib classes in an application starts with a ManagedWindow which contains a top level PanedPane. This PanedPane can contain additional PanedPanes which can be additionally nested. Any of these PanedPanes can then contain a MenuPane and/or a UIDevicePane. MenuPanes contain menus which in turn contain buttons. UIDevicePanes contain UIDevices including buttons.

The implementation of the library was done with a product called Object Interface (OI), developed by ParcPlace and now maintained by OpenWare. OI running on Unix machines utilizes Xlib for its implementation. It is capable of presenting both a Motif and OpenLook look and feel interface. For the purposes of this design, the Motif style will be used.

Applications built using the library will also be able to use the OI library and the X library for development. Use of X is strongly discouraged since it makes the applications more difficult to maintain and may cause future portability problems

Figure 8.2 Application Access to Libraries

8.2.2 Client Classes and Callbacks

The overall callback scheme for applications using the UI Class library follows the client/server model. An instantiated object from the UI Class library acts as the server, the application object is the client, and the client inherits the callback protocol from an abstract class defined by the server. For many of the UI classes, there is a corresponding client class. This class defines the message protocol to be used for callback. Member functions of the client class are defined to be pure virtual. It is the client's responsibility to define the implementation of these inherited functions. The UI object is handed a pointer to the client object at creation time.

Figure 8.3 Client classes

8.2.3 Caveats - Tcl/Tk

This library is soon to become obsolete. We are planning to replace it with the Tcl command language and its Tk took kit.

8.3 Software Design

The user interface process, fxa, is the main process of D2D. It has a number of responsibilities:

Note: the information in this section will soon be obsolete as we migrate the entire fxa process into a combination of Tcl script and C++ code.

8.3.1 FXA Process Design

The architecture of the fxa process is based around these two designs:

8.3.2 Classes/Objects

This section describes each of the classes/objects in the fxa process.

8.3.2.1 Tiled Display Window

The singleton of class TiledDisplayWindow is what gets everything started. Constructed inside of the fxa process' main function, it constructs the five display areas, menu bar, tool bar, and status bar.

The constructor uses the user interface library to create a top-level window containing four small display areas and starts an IGC process in each using the UI workspace manager (see below).

It then adds to the window the menu bar. The menu bar contains the fixed menus File and Scale. The singleton ScaleMenuMgr is responsible for building the scale menu. The remaining menus except the Map menu are specified by the dataMenus.txt file. This file tells what pull-down menus, cascade menus, product buttons, application buttons, and title buttons appear in the menu and where. The format of this file is straightforward; comments in the file give details. The constructor adds the map menu, created by the singleton MapMenuMgr, and adds the clock, created by the singleton Clock.

Callbacks for the widgets built by various singletons are the singletons themselves. Callback for application buttons is the AppMgr singleton. Callbacks for the product buttons are objects of class BB2_ProductButtonClient.

Next, the constructor builds the tool bar. The tool bar (also known as the control bar in the code) creates the clear button, frame step buttons, and the controls menu. The TiledDisplayWindow is itself the callback client of these buttons. On the controls menu, three singletons are the callback clients: GraphicsControlsMgr, ImageControlsMgr, and AnimationMgr (the looping controls). It then adds the load mode button, created by the LoadModeMgr singleton. It ends with the WarnGen button; the TiledDisplayWindow is itself the callback client.

Next, the constructor builds the large display area and starts an IGC to serve it.

Finally, the constructor builds the status bar. It contains two display areas: the left for general status, and the right for radar. Two AnnouncementDisplayer objects are created, one to display general messages, the other for radar messages.

8.3.2.2 UI Workspace Manager

The singleton UI_WSM_Impl, known as the "workspace manager," maintains information about all IGC processes. It maintains a mapping between ID numbers (called UI WSM IDs) and the IGC objects that represent running IGC processes. It also tracks which IGC is the active one. The active IGC is the one serving the large display area.

The TiledDisplayWindow singleton calls methods in the UI_WSM_Impl singleton to create IGCs by calling createWSMtuple. This method takes a size type (large or small), a Cartesian pixel extent, and the window in which the IGC should display itself. It then creates the underlay window for that IGC as a child of the window passed in and starts the IGC process, passing it the size type.

When the user wants to swap a small IGC with a large one, the small IGC wishing to do the swap sends an IPC message which is received by the workspace manager's swapWithLargeDisplay method. This method initiates the swap: it tells the small IGC and the large, active one to suspend themselves. After responses from both IGCs have been received by the suspendAcknowledged method of this singleton, the singleton workspace manager tells each IGC to transform itself, passing the new window IDs they'll use. The singleton then saves the ID of the new active IGC.

All IGC requests (to load data, for example) are made to the active IGC. By asking the UI_WSM_Impl singleton for a pointer to the active IGC object, user interface callback objects can get the IGC to perform. For example, the BB2_ProductButtonClient callback is invoked when the user selects a product to load. The callback object determines the depict key to load. It then asks the UI_WSM_Impl for the active IGC object, and calls the load method of that object, passing in the depict key.

8.3.2.3 Product Button Client

Objects of class BB2_ProductButtonClient are the callback clients for product buttons, which are menu buttons that forecasters use to load products. The buttonSelected method of this class is invoked when a product button is selected. The class maps from the product button key (defined by class DM_ProductButtonInfo) to a depict key that depends on the current scale. (It queries the ScaleMenuMgr for the current scale.)

After determining the scale and the depict key, it tells the IGC to load the product via the LoadModeMgr (described below).

8.3.2.4 Product Button

Objects of class BB2_ProductButton (derived from PushButton, which can appear in a menu) are product buttons. They contain a product button key which they use to determine their label and also which depict key to load depending on the scale. The depict key is also used to determine which product time ("green time") to display next to the label.

As forecasters change scale, the set of available products changes. Product buttons must enable or disable themselves to reflect this information and also to change the product time displayed. They do so by registering with the ScaleMenuMgr, which notifies every single product button what the new scale is.

8.3.2.5 Scale Menu Manager

The singleton of class ScaleMenuMgr manages the scale menu. The ScaleMenuMgr attaches a scale menu to the user interface. It builds the items in the scale menu by consulting DM_ScaleInfo.

Using an object-oriented callback strategy, callback clients can be registered with the ScaleMenuMgr. Whenever the forecaster changes the scale, the ScaleMenuMgr tells every client what the new scale is. Product buttons (described above) register so they can enable or disable themselves and display a new product time. Applications (represented by objects of class App) register to know when to send a scale change update to a running application.

Also, the ScaleMenuMgr sends the new scale to the active IGC whenever it changes. (The IGC will clear its display if there are no products loaded.)

8.3.2.6 Load Mode Manager

The load mode manager singleton is responsible for tracking the current load mode. It builds a load mode option menu in the tool bar, and remembers the forecaster's selection.

Like the scale menu manager, the LoadModeMgr keeps a set of callback clients to be notified if the load mode changes. The application interface uses this feature to send the load mode update to running applications.

The most important responsibility of the LoadModeMgr is to send load requests to the active IGC process. The parameters in the load request depend on the current load mode, so the LoadModeMgr is uniquely suited to calling IGC::load.

For certain load modes, the forecaster must enter a forecast time. The LoadModeMgr displays a dialog box and sends the request after the selection. For the Inventory load mode, the forecaster must enter both the forecast time and an inventory time. The LoadModeMgr arranges for the inventory time dialog box to appear after the forecaster makes a selection from the forecast time dialog.

Finally, the LoadModeMgr tracks if image combination is on, and sets the appropriate parameter in the load request.

8.3.2.7 Control Classes

Three singletons maintain the three different control dialog boxes:

Although not appearing on the Controls menu, the FrameMenuMgr singleton builds and tracks the frame count menu and the current frame count display. When the user selects a frame count, the request is passed to the active IGC. When the IGC determines the actual number of frames available, it sends it to this singleton to update the display.

8.3.2.8 Clock Classes

Two classes maintain the display of the D2D clock and the notion of time used for the loading of products:

8.3.2.9 Map Menu Manager

The singleton MapMenuMgr object creates the map menu. It uses DM_ScaleInfo to determine what maps are available and displays them on the menu. It enables and disables various maps depending on the currently selected scale. The IGC process tells the MapMenuMgr via an IPC message what scale to use.

Selecting a map from the menu results in an IGC load request with the selected map's depict key.

8.3.2.10 Announcement Classes

The announcer system is responsible for receiving and displaying status messages in the status bar at the bottom of the D2D window. It comprises the following classes:

8.3.2.11 Procedure/Bundle Classes

The D2D procedure feature lets the forecaster collect bundles, which encapsulate the IGC display state, into sets called procedures. Bundles and procedures are stored in files and can be named by the forecaster.

Bundles are created by the IGC process and are passed to the fxa process for ownership. They live in the D2D history list until they're copied to a procedure. When the procedure is saved, the bundle files are collected into a single directory named after the procedure. When selected by a forecaster, either from the history list or from a procedure, a bundle is loaded into the active IGC display. The fxa process treats bundle files as opaque data. It only manages them; it never looks inside.

Because both procedures and the history list display a list of bundles, the class Bundle-List is used to manage the list. This class creates a user interface list widget and populates it with text strings representing the bundle names. An object-oriented callback mechanism tells the callback client of the BundleList when bundles in the list are selected.

The singleton class BundleHistory creates a BundleList to display the bundles in the history list. It gets called by the IGC process to "take a bundle" whenever the process completes one. By taking a bundle, the BundleHistory takes ownership of the file and displays the bundle name in its contained BundleList. Selecting a bundle on the list and pressing Load asks the IGC to load it. Pressing Copy Out copies the bundle to every open procedure.

The class ProcedureDialog represents a procedure. It too contains a BundleList plus a number of buttons that operate on the contained bundles. Loading works as for the history list, as does copying out. Pressing Rename opens the bundle rename dialog, contained in class RenameBundleDialog. The other buttons are straightforward.

ProcedureDialogs are tracked by the ProcedureMgr singleton, which is the callback client for the New... and Open... buttons on the Procedures cascade menu.

8.3.2.12 UI_KeypadClient

This class, derived from KeypadEventClient, handles events generated by the D2D keypad (also known as the touchpad). An object of this class is created in the fxa main function and is registered with the EventDispatcher. Whenever the EventDispatcher sees output on the keypad's file descriptor, it passes it to the UI_KeypadClient object.

The UI_KeypadClient passes the request to the appropriate singleton for processing.

8.3.3 Interprocess Communication

The user interface process, fxa, has one main IPC receiver defined in the ipcUIproc directory. It's the class IGC_uiProcReceiver. The IGC processes use the IGC_uiProcMsg class to send messages to the fxa process through a proxy interface. The workspace manager (see Section 8.3.2.2) is the proxy.

The IGC processes link with the class UI_WorkspaceManager. Methods in this class send IPC messages to the fxa process; these are handled by the UI_WSM_Impl (in addition to its function of tracking running IGCs and handling swapping). The fxa-side object passes the requests to the various singletons for handling.

Also, the fxa process links with other receivers that are part of other software interfaces (for example, the data management receiver for inventory notifications).

8.3.4 Starting FXA and the Main Function

To start the D2D display, one runs the start-d2d script. This script initializes the LOG_FILE environment variable, loads X resources needed by fxa and the various applications and extensions, checks and optionally stops/starts the DMQ IPC system, kills any existing run and orphaned processes from a previous run, and executes fxa. The script also displays the D2D splash page and gives an idea of the initialization progress.

The script monitors the standard output of fxa: as soon as it sees the text "Ready" it knows the fxa has initialized to the point that it's entered the Event Dispatcher loop. Because the IGCs usually haven't yet initialized at this point, the script waits a bit longer before exiting (and thereby removing the splash page).

The file uiProc/fxa.C contains fxa's main function. It registers a signal client with the signal catcher to handle shutdown (SIGTERM, SIGINTR, etc.) and child died (SIG-CHLD) signals. It parses the command line with the user interface library class UIxConnection. It sets the DISPLAY environment variable for future child processes, creates the EventDispatcher and the TiledDisplayWindow, and enters the dispatch loop.

 
Table of Contents Next Chapter


This document is maintained by Joe Wakefield. Last updated 9 Jan 97.