22 Advanced Dialog Programming
This chapter describes some Motif features that have not been described, or at least not completely, in earlier chapters.
The topics, which all deal with dialogs, include the creation of multi−stage help systems, the development of
WorkingDialogs that allow the user to interrupt long−running tasks, and a method for dynamically changing the
pixmaps displayed in a dialog.
In one sense, this chapter isn't about dialogs at all, but about various aspects of X programming that become most
evident when working with dialogs. Here we address some issues involved in creating multi−stage help systems, we
show you how to create a WorkingDialogs that allows the user to interrupt a long−running task, and we describe a
method for dynamically changing the pixmaps that are displayed in a dialog. These topics explore some of the most
interesting problems in this book.
These topics take us deeper into the lower layers of X than anything we've discussed so far in this book. You should
have a good basic understanding of X event−processing, as implemented both in Xlib and Xt. Otherwise, be prepared
to refer frequently to Volume One, Xlib Programming Manual, and Volume Four, X Toolkit Intrinsics Programming
Manual, when faced with references to lower−level functions.
22.1 Help Systems
The Motif Style Guide doesn't have much to say about how help is presented to the user, although it does discuss the
ways in which the user can request help from an application. The user can request help by selecting the Help button in
a dialog box, by choosing help items from the Help menu in the MenuBar, or by pressing the HELP or F1 key on the
keyboard. Help information should be presented clearly, so that it is accessible and beneficial to users. You should
also maintain consistency in a help system, so that the user can become familiar with the style of help that you
provide.
The easiest and most straightforward method of presenting help information involves creating an InformationDialog
with the necessary text displayed as the XmNmessageString. the source code demonstrates how to display a help
dialog when the user presses the Help button in another dialog box. XtSetLanguageProc() is only available in
X11R5; there is no corresponding function in X11R4. XmStringCreateLocalized() is only available in Motif
1.2; XmStringCreateSimple() is the corresponding function in Motif 1.1. XmFONTLIST_DEFAULT_TAG
replaces XmSTRING_DEFAULT_CHARSET in Motif 1.2.
/* simple_help.c −− create a PushButton that posts a dialog box
* that entices the user to press the help button. The callback
* for this button displays a new dialog that gives help.
*/
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, button;
XtAppContext app;
XmString label;
void pushed();
599
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
label = XmStringCreateLocalized ("Push Me");
button = XtVaCreateManagedWidget ("button",
xmPushButtonWidgetClass, toplevel,
XmNlabelString, label,
NULL);
XtAddCallback (button, XmNactivateCallback,
pushed, "You probably need help for this item.");
XmStringFree (label);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
#define HELP_TEXT "This is the help information.0ow press 'OK'"
/* pushed() −− the callback routine for the main app's pushbutton. */
void
pushed(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
char *text = (char *) client_data;
Widget dialog;
XmString t = XmStringCreateLocalized (text);
Arg args[5];
int n;
void help_callback(), help_done();
n = 0;
XtSetArg (args[n], XmNautoUnmanage, False); n++;
XtSetArg (args[n], XmNmessageString, t); n++;
dialog = XmCreateMessageDialog (XtParent(w), "notice", args, n);
XmStringFree (t);
XtUnmanageChild (
XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
XtAddCallback (dialog, XmNokCallback, help_done, NULL);
XtAddCallback (dialog, XmNhelpCallback, help_callback, HELP_TEXT);
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}
/*
* help_callback() −− callback routine for the Help button in the
* original dialog box that displays an InformationDialog based on the
* help_text parameter.
*/
void
help_callback(parent, client_data, call_data)
Widget parent;
XtPointer client_data;
XtPointer call_data;
{
22 Advanced Dialog Programming 22 Advanced Dialog Programming
600
char *help_text = (char *) client_data;
Widget dialog;
XmString text;
void help_done();
Arg args[5];
int n;
n = 0;
text = XmStringCreateLtoR (help_text, XmFONTLIST_DEFAULT_TAG);
XtSetArg (args[n], XmNmessageString, text); n++;
XtSetArg (args[n], XmNautoUnmanage, False); n++;
dialog = XmCreateInformationDialog (parent, "help", args, n);
XmStringFree (text);
XtUnmanageChild ( /* no need for the cancel button */
XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
XtSetSensitive ( /* no more help is available. */
XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON), False);
/* the OK button will call help_done() below */
XtAddCallback (dialog, XmNokCallback, help_done, NULL);
/* display the help text */
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}
/* help_done() −− called when user presses "OK" in dialogs. */
void
help_done(dialog, client_data, call_data)
Widget dialog;
XtPointer client_data;
XtPointer call_data;
{
XtDestroyWidget (dialog);
}
The main window contains a PushButton that posts a simple MessageDialog. This dialog, as you can tell from the
figure, contains a Help button, that pops up an InformationDialog. This dialog is intended to provide help text for the
user.
22 Advanced Dialog Programming 22 Advanced Dialog Programming
601
Output of simple_help.c
The callback routine for the Help button is installed using the XmNhelpCallback. This routine pops up an
InformationDialog that contains some predefined text. Obviously, this text is for demonstration purposes only. We
used XmStringCreateLtoR() to display the text, instead of XmStringCreateLocalized(), since the help
message contains newline characters. You could also use XmStringCreateLtoR() to specify an alternate font for
use in your help system, but we are not taking advantage of this feature. See Chapter 19, Compound Strings, for more
information on how you can use compound strings to display text using different fonts.
The XmNhelpCallback resource serves as the callback for any widget that wishes to provide help information;
every Motif widget has an XmNhelpCallback resource associated with it. Whenever the user presses the HELP
key on the keyboard (if one exists and the X server is set up correctly), By default, Sun workstations do not generate
the proper event when the HELP key is pressed, and your mileage may vary for other computers. the
XmNhelpCallback is invoked for the widget that has the keyboard focus. The F1 key also serves as a help key for
compatibility with Microsoft Windows and to compensate for any computer that may not have a HELP key. The F1
key works by default, but it may be remapped to perform another function in the user's .mwmrc file.
If a widget does not have an XmNhelpCallback function installed, Motif climbs the widget tree, searching for the
nearest ancestor that has a help callback. If you assign help callbacks to widgets, we recommend that you provide
specific help information for individual interface components, such as PushButtons, Lists, and Text widgets, and more
general information for manager widgets. It is possible to design an elaborate context−sensitive help system for an
application by installing help callback routines for the widgets in the interface and providing relevant help information
throughout the hierarchy.
Although simple_help.c is rather contrived, we can use it to examine the different actions the user might take within a
help system. You can think of the Push Me button as any widget in an application on which the user might want help.
When the button is activated, the user is presented with a MessageDialog that undoubtedly requires help. The user can
select the Help button or press the F1 or HELP keys to access the help information. Since the InformationDialog is
modeless, as it should be, the user can either close the InformationDialog or the original MessageDialog.
22 Advanced Dialog Programming 22 Advanced Dialog Programming
602

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.