| DECwindows Motif Guide to Application
Programming
 
 
 
 Chapter 2DECwindows Application Interface Design
 This chapter discusses the design of a DECwindows application
 interface. The chapter includes a description of the OpenVMS DECburger
 demo application interface.
2.1 Designing a DECwindows Application---Where to Begin 
 The first step in designing a DECwindows application interface is to
 become familiar with the application interface guidelines contained in
 the DECwindows Companion to the  OSF/Motif Style Guide, the definitive reference on the look and feel of a
 DECwindows application. If you design your application in accordance
 with the guidelines of the DECwindows Companion to the  OSF/Motif Style Guide, you can be certain that your
 application interface will be consistent with other DECwindows
 applications.
 
 Once you are familiar with the application interface guidelines, you
 can decide the form of the application; that is, what you want your
 application to look like. You might want to sketch out how you want
 your application to look before you create it. A sketch also helps you
 to visualize the parent/child relationships of the widgets in your
 interface, as described in Section 1.4.1.
2.1.1 Application Design Topics 
Answering the following questions can help you design your application
interface:
 
  Must all parts of the application be visible when the application
  is started? Or, can you present an initial environment and then wait
  for a user action before revealing additional components? For example,
  the DECwindows Clock application initially presents only a clock; a
  user must click MB3 to get a customize menu.
  Will the application need only one main window that remains visible
  as long as the application is running, or will it require widgets that
  appear, perform a function, and then disappear?
  Will the physical relationship between widgets be important? That
  is, will you need form widgets to maintain a physical layout in the
  event that the application is resized?
  Will the application require the user to enter text or take some
  other action in response to a query? Will your application use the
  compound string text widget to determine character set and writing
  direction information?
  Will the application need label widgets to provide the user with
  information? If so, will this text need to be translated for
  international use? (UIL provides capabilities for this.)
  Will the application need capabilities --- such as color mixing or
  help --- implemented by the widgets provided by Digital? Using the
  widgets provided by Digital can save you considerable programming time
  while allowing your application to be in compliance with the
  DECwindows Companion to the  OSF/Motif Style Guide.
  Will the application take advantage of gadgets? Because gadgets use
  fewer resources than widgets, use gadgets whenever appropriate. With the exception of the XmFileSelectionBox widget, all manager
  widgets accept gadgets. However, there are several resources that can
  be used only if the child objects are widgets:
 
    XmNbottomShadowColor
    XmNbottomShadowPixmap
 XmNforeground
 XmNhighlightColor
 XmNhighlightPixmap
 XmNtopShadowColor
 XmNtopShadowPixmap
 2.1.2 Use of Callbacks
 Remember that callbacks are the connection between the application
 interface and your functional code. As you design your user interface,
 try to equate a user action with the callback to be generated; that is,
 if you want the user to perform an action such as cancel, a cancel push
 button should be available.
2.1.3 Making Assumptions About Resources 
 As you design your application, be careful about assumptions you make
 about available resources. DECwindows applications are likely to be
 displayed on a variety of hardware platforms and your application
 should provide for differing screen sizes, availability of color
 resources, and so forth.
 
 Depending on your application, you might want to selectively reduce
 functionality if you are unable to allocate sufficient resources. This
 requires that you determine the minimum operating environment your
 application needs and reduce functionality until you reach that
 environment.
 
Chapter 10 describes a set of interoperability coding recommendations
that you should follow if you are writing DECwindows applications for
multiple hardware platforms. Chapter 10 provides information on the
following topics:
 
  Font fallback
  Screen independence
  Color support
 2.1.4 Selecting Appropriate Widgets
 After you have determined what your application will look like, check
 the OSF/Motif Programmer's Guide for the widgets that most
 closely implement your planned user interface.
 
 As described in Section 1.1.2, there are three major types of widgets in
 the Toolkit:
 
  Container widgets Most applications use some form of container
  widget, such as XmBulletinBoard or XmMainWindow, as the main widget of
  their application. These widgets support many types of children and
  give your application a flexible platform.
 For example, if your
  application needs to include a menu bar, you might find that the
  XmMainWindow widget would make a suitable main window for your
  application because it easily supports a menu bar child. You might also
  find that the simple geometry management provided by XmBulletinBoard is
  a convenient way to make sure that child widgets do not overlap.
Input/output widgets Input/output and choice widgets are used
  to present information or to query the user for input. Pick the type of
  widget that best fits your application. For example, if a text entry
  field needs to handle more than one line of text, you might want to use
  the XmCreateScrolledText routine to create an XmText widget that is
  contained within a scrolled window. Using this routine is easier than
  creating separate text and scroll bar widgets.
Choice widgets These widgets allow your application to present
  choices to the user and obtain a response. Choice widgets can be
  "pick one" and "pick many."
 
 As described in Section 1.4.3, you might find that you can use part of
 an existing application to build a new application. That is, if you
 already have written an application that uses an XmMainWindow widget,
 consider reusing that code with different callbacks.
 
You should use existing Toolkit widgets whenever possible. However, if
you cannot find a widget that suits your needs, you can create your own
widget, as described in the X Window System Toolkit. Note that, if you create your
own widgets, you become responsible for implementing the DECwindows
look and feel.
2.1.5 Widgets in the OpenVMS DECburger Application 
 This section describes the reasons for using the various widgets in the
 OpenVMS DECburger demo application. Figure 2-1 shows the OSF/Motif
 widgets as used in the DECburger user interface. The widgets provided
 by Digital are shown in subsequent chapters.
 
Figure 2-1 OpenVMS DECburger User Interface
 
   
The OpenVMS DECburger demo application uses an XmMainWindow widget as
the base of the application, as shown in Figure 2-2.
 
Figure 2-2 OpenVMS DECburger XmMainWindow Widget
 
   
The main window widget presents some of the OpenVMS DECburger
application's basic functions, such as placing an order, as items in a
menu bar widget. The DECburger XmMenuBar widget contains the four
XmCascadeButton menu entries shown in Figure 2-3. (The menu bar
widget also contains an Options menu entry on color systems.)
 
Figure 2-3 OpenVMS DECburger XmMenuBar Widget
 
   
Each XmCascadeButton controls an XmPulldownMenu widget. When the user
selects one of the entries in the menu bar widget, a pull-down menu
widget appears on the screen. The pull-down menu widget disappears when
the user releases MB1.
 
The XmPulldownMenu displayed in Figure 2-4 is the Order pull-down
menu widget DECburger uses when the order box is already displayed. The
contents of this menu vary depending on whether the order-entry box is
visible.
 
Figure 2-4 OpenVMS DECburger XmPulldownMenu Widget
 
   
The OpenVMS DECburger Order-Entry Box shown in Figure 2-5 is an
XmFormDialog widget, which is a general container widget that imposes
geometry management on its children. Dialog widgets can extend beyond
the boundaries of their parent widgets, and the DECburger Order-Entry
Box does so.
 
Figure 2-5 OpenVMS DECburger XmFormDialog Widget
 
   
To distinguish each XmForm widget in the Order-Entry Box, DECburger
includes a descriptive text label at the top of each section. Each of
these text labels is an XmLabel gadget.
 
DECburger uses the XmRadioBox widget shown in Figure 2-6 to present a
list of choices from which the user can choose only one item at a time.
Each item in the radio box widget is implemented by an XmToggleButton
gadget.
 
Figure 2-6 OpenVMS DECburger XmRadioBox Widget
 
   
To present a list of choices from which the user can select any number
of items, DECburger uses an XmRowColumn widget, as shown in
Figure 2-7. Each item in the menu is an XmToggleButton gadget.
 
Figure 2-7 OpenVMS DECburger XmRowColumn Widget
 
   
To solicit quantity information, DECburger uses an XmScale widget, as
shown in Figure 2-8. Because scale widgets graphically present a
range of values, they prevent users from entering an incorrect value.
 
Figure 2-8 OpenVMS DECburger XmScale Widget
 
   
DECburger uses an XmOptionMenu widget to present a list of choices from
which only one item can be selected at a time, as shown in
Figure 2-9. Each item in the option menu widget is an XmPushButton
gadget. As with the pull-down menu widget, the option menu appears on
the display only when the user presses MB1. In this way, the list of
items does not take up any display space until it is invoked. The
option menu widget always displays its current selection.
 
Figure 2-9 OpenVMS DECburger XmOptionMenu Widget
 
   
DECburger uses an XmText widget to handle another quantity choice, as
shown in Figure 2-10. The text widget lets the user enter text from
the keyboard.
 
Figure 2-10 OpenVMS DECburger XmText Widget
 
   
To present a long list of choices, DECburger uses the XmScrolledList
widget shown in Figure 2-11. Only a portion of the entire list of
items is visible in the scrolled list as it appears on the display.
XmScrolledList widgets can be configured to allow users to select more
than one item at a time.
 
Figure 2-11 OpenVMS DECburger XmScrolledList Widget
 
   
DECburger uses the XmForm widget shown in Figure 2-12 to implement
drink quantity selection. The XmForm widget includes two XmPushButton
widgets with pixmap labels. The "up arrow" XmPushButton
increases the drink quantity; the "down arrow" XmPushButton
decreases the drink quantity. (Note that XmPushButton widgets are used
instead of gadgets because you cannot use pixmap labels with
XmPushButton gadgets.) The XmForm widget also includes two XmLabel
gadgets to display descriptive text and to present the current value
selected by the user.
 
Figure 2-12 OpenVMS DECburger XmForm Widget
 
   
DECburger uses an XmFormDialog widget containing four XmPushButton
widgets to implement the OK, Apply, Reset, and Cancel functions, as
shown in Figure 2-13. Note the use of widgets instead of gadgets to
allow DECburger to specify a larger font size to emphasize these
important functions. You cannot specify the font in a gadget; gadgets
use the font specified in their parent. (The figure does not represent
the actual font used in these buttons. To see this attribute, run the
DECburger application.)
 
The XmNshowAsDefault resource identifies the OK XmPushButton as the
default; the XmNdefaultButtonShadowThickness is set to one for all of
the XmPushButton widgets so that they have the same size when selected.
 
Figure 2-13 OpenVMS DECburger XmFormDialog Widget
 
   2.1.6 Toolkit Intrinsic Routines Used in OpenVMS DECburger
 As described in Section 1.1.8, your application can use intrinsic
 routines to initialize the Toolkit, get information about the screen
 and display, map and unmap widgets to the screen, process input from an
 application end user, and so forth.
 
For example, the OpenVMS DECburger demo program uses the following
intrinsic routines:
 
  XtAppInitialize---Initializes the Toolkit internals to create a
  default application context for use by the other convenience routines.
  XtAppInitialize returns the "top-level" widget for an
  application.
 
  
    | 
 
XtAppContext app_context;
   .
   .
   .
toplevel_widget = XtAppInitialize(&app_context, "DECburger", NULL, 0,
                                  &argc, argv, &fallback, NULL, 0);
 | XtDisplay---Returns the display pointer for the specified widget.
  DECburger uses XtDisplay when querying colors associated with the
  default color map.
 
  
    | 
 
XQueryColor(the_display,
                  XDefaultColormapOfScreen(the_screen), &newcolor);
 | XtScreen---Returns the screen pointer for the specified widget.
  DECburger uses XtScreen to determine the screen associated with the
  top-level widget.
 
  
    | 
 
the_screen = XtScreen(toplevel_widget);
 | XtSetMappedWhenManaged---Maps a window if it is managed. DECburger
  allows a user to customize the background color only if a color
  workstation is being used. Specifically, DECburger uses
  XtSetMappedWhenManaged to map the Options menu entry.
 
  
    | 
 
XtSetMappedWhenManaged(widget_array[k_options_pdme], TRUE);
 | XtManageChild---Adds a single child widget to the managed children
  of the parent widget. DECburger first calls this routine to manage the
  main window.
 
  
    | 
 
XtManageChild(main_window_widget);
 | XtUnmanageChild---Removes a single child widget from the managed
  children of the parent widget.
 
  
    | 
 
XtUnmanageChild(widget_array[k_order_box]);
 |  XtRealizeWidget---Realizing a widget creates a window for the
  widget and maps the window to the display. For composite widgets (that
  is, widgets with children), realizing a widget also creates and maps
  windows for all of the managed children of the widget. Therefore,
  DECburger needs to realize only its top-level widget.
 
  
    | 
 
XtRealizeWidget(toplevel_widget);
 | XtAppMainLoop---Performs a loop that waits for the user to interact
  with the user interface and then processes input data in the form of
  callbacks.
 
  
    | 
 
XtAppMainLoop(app_context);
 | XtSetArg---Fills in the argument data structures in an argument
  list. XtSetArg takes the following arguments:
  
    The address of the argument-list element
    The name of the widget attribute
    The value being assigned to the attribute or the address where the
    value will be returned by XtGetValues
   In the following example, XtSetArg fills in an argument data
    structure with the name of a widget attribute (DXmNfirstTopic) and the
    value being assigned to that attribute (compound string identified by
    help_topic).
 
 
  
    | 
 
XtSetArg (arglist[0], DXmNfirstTopic, help_topic);
 | XtSetValues---Modifies the current value of a resource associated
  with a widget instance. XtSetValues is commonly used together with
  XtSetArg to change the value of a resource. In the following example,
  XtSetArg first fills in an argument data structure with the name of a
  widget resource DXmNfirstTopic and the value being
  assigned to that attribute (compound string identified by help_topic).
  XtSetValues then sets the DXmNfirstTopic
  attribute for this instance of the help widget.
 
 
  
    | 
 
XtSetArg (arglist[0], DXmNfirstTopic, help_topic);
XtSetValues (help_widget[help_num], arglist, 1);
 | XtGetValues---Retrieves the current value of resource data
  associated with a widget instance. DECburger uses XtGetValues together
  with XtSetArg.
 
  
    | 
 
XtSetArg(arglist[0], XmNbackground, &newcolor.pixel);
XtGetValues(main_window_widget, arglist, 1);
 |  This example calls the XtSetArg and XtGetValues intrinsic routines
    to get the background color of the main window widget and store it in
    the newcolor.pixel pixel field.
XtIsManaged---Determines if the specified widget is currently
  managed. Applications are obliged to create new instances of the help
  widget if one is already managed. DECburger uses XtIsManaged to
  determine if a help widget is already managed.
 
  
    | 
 
if (XtIsManaged(main_help_widget)) {
 |  
 
   |