A help index dialog
Creating a Help menu is just like creating any other menu, except that once you have created the CascadeButton, you
should set the XmNmenuHelpWidget resource for the MenuBar. This resource specifies which CascadeButton is
placed to the far right in the MenuBar, which is where the Style Guide states that the Help menu must be positioned.
the source code contains a routine that demonstrates how to build a Help menu and attach it to the MenuBar. In this
example, we present an alternate approach to creating MenuBar titles and their associated PulldownMenus.
void
BuildHelpMenu(MenuBar)
Widget MenuBar;
{
Widget HelpPullDown, widget;
int i;
static char *h_items[] = {
"On Context", NULL, "On Help", "On Window", "On Keys",
"Index", "Tutorial", "On Version"
};
/* Help menu */
HelpPullDown = XmCreatePulldownMenu (MenuBar, "HelpPullDown", NULL, 0);
widget = XtVaCreateManagedWidget ("Help",
xmCascadeButtonWidgetClass, MenuBar,
XmNsubMenuId, HelpPullDown,
NULL);
/* tell the MenuBar that this is the help widget */
XtVaSetValues (MenuBar, XmNmenuHelpWidget, widget, NULL);
/* Now add the menu items to the pulldown menu */
for (i = 0; i < XtNumber (h_items); i++) {
if (h_items[i] != NULL) {
widget = XtVaCreateManagedWidget (h_items[i],
xmPushButtonGadgetClass, HelpPullDown, NULL);
XtAddCallback (widget, XmNactivateCallback,
do_help, h_items[i]);
}
else
widget = XtVaCreateManagedWidget ("sep",
xmSeparatorGadgetClass, HelpPullDown, NULL);
}
}
Much of the work required to create a PulldownMenu is involved in creating the menu items. We can optimize the
code by using a loop that creates individual items based on the names provided in a static array. If you want to add a
new help item to the list, you just need to add its name to the h_items list. A NULL entry causes a Separator gadget
to be added to the menu. In the source code we specify the same callback function for each item in the menu; the
client_data is the same as the name of the menu item. In Section #smenucreate, we expand on this approach to
build arbitrary menus for the MenuBar.
16.3.6 Sensitivity
As we mentioned earlier, MenuBar titles and menu items should not be dynamically created or destroyed. They may,
however, be activated or deactivated using XtSetSensitive(). When a CascadeButton or a menu item is
insensitive, it is grayed out, and the user is unable to display the associated menu or activate the menu item.
16 Menus 16.3.6 Sensitivity
448
For CascadeButtons, insensitivity has the additional effect of preventing the user from accessing any of the items on
the associated menu, including access through mnemonics and accelerators, since the menu cannot be displayed. The
menu and all its items are completely unavailable until the sensitivity of the CascadeButton is reset. An alternate way
to disable an entire menu is to set the PulldownMenu pane insensitive. This approach has the advantage of still
allowing the user to display the menu and see all the items, while making the items unavailable.
For example, take an editor program. If the user is not editing a file, it doesn't make sense to have the Save item in the
File menu be selectable. Once the user starts editing a file, the Save button is sensitized so that the user can select it.
Since the user cannot select the item until its sensitivity is reset, it is important that the application do so at the
appropriate time. Another less realistic example, but one that we can demonstrate, involves a menu item that pops up a
dialog. As long as that dialog is up, the user cannot reselect the menu item again. For purposes of this demonstration,
let's say that the Open item pops up a FileSelectionDialog and desensitizes itself. When the dialog is dismissed, the
menu item is resensitized. This behavior is not a great design. The dialog really should be cached, and the menu item
should remain sensitive. If the item is reselected, the dialog should be remapped or raised to the top of the window
stack, if necessary.
To implement this behavior, we specify a callback routine for the Open menu item that creates a FileSelectionDialog
and sets the item insensitive. We also specify a callback routine for the dialog box that resets the menu item's
sensitivity. The code fragment in the source code shows these callback routines.
/* reset_sensitive() −− generalized routine that resets the
* sensitivity on the widget passed as the client_data parameter
* in a call to XtAddCallback().
*/
void
reset_sensitive(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Widget reset_widget = (Widget) client_data;
XtSetSensitive (reset_widget, True);
}
/* open_callback() −− the callback routine for when the "Open"
* menu item is selected from the "File" title in the MenuBar.
*/
void
open_callback(menu_item, client_data, call_data)
Widget menu_item;
XtPointer client_data;
XtPointer call_data;
{
Widget dialog, parent = menu_item;
/* Get the window manager shell widget associated with item */
while (!XtIsWMShell (parent))
parent = XtParent (parent);
/* turn off the sensitivity for the Open button ... */
XtSetSensitive (menu_item, False);
dialog = XmCreateFileSelectionDialog (parent, "files", NULL, 0);
/* Add callback routines to respond to OK button selection here. */
/* Make sure that if the dialog is popped down or destroyed, the
16 Menus 16.3.6 Sensitivity
449

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.