DECwindows Motif Guide to Application
Programming
Chapter 2 DECwindows 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)) {
|
|