[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Programmer's Guide

Menu Components: Buttons, RowColumn, MenuShell

A menu is a three-level hierarchy:

  1. Buttons represent the menu selections.

  2. A RowColumn widget is the manager that contains the buttons.

  3. A MenuShell envelops each PulldownMenu and PopupMenu.

  4. Buttons

    The user makes a choice in a menu by activating one of the buttons in the menu. CascadeButtons, PushButtons, and ToggleButtons and their gadget variants are most commonly used in menus.


    Motif does not support DrawnButtons or ArrowButtons in menus, though they can appear in a RowColumn WorkArea. To give a menu button a distinctive appearance, use a PushButton with a label type of XmPIXMAP and supply XmNlabelPixmap and XmNlabelInsensitivePixmap resources.

    The application learns of the user's choice through the appropriate button callback lists:

    1. When the user activates a CascadeButton, the button calls the XmNcascadingCallback callbacks. If the button has an attached PulldownMenu after these callbacks return, the button posts the menu. Otherwise, the button calls the XmNactivateCallback callbacks.

    2. When the user activates a PushButton, the button calls the XmNactivateCallback callbacks.

    3. When the user activates a ToggleButton, the button calls the XmNvalueChangedCallback callbacks.

      Buttons in a menu have translations and actions that arm, disarm, and activate the buttons. These actions also post and unpost menus in the hierarchy at appropriate times. The buttons inherit menu traversal translations and actions from XmLabel. These actions allow the user to move from button to button within a menu and from menu to menu within the menu hierarchy.

      Use the XmNenableEtchedInMenu resource of XmDisplay to help control the shadowing of activated menu buttons.

    4. RowColumn

      The parent of the buttons in a menu is a RowColumn widget. RowColumn interacts with its button children in these ways:

      1. In a menu (but not a WorkArea), it ensures that all children are CascadeButtons, PushButtons, ToggleButtons, Labels, or Separators (or their gadget variants). If the XmNisHomogeneous resource is True, it ensures that all children are of the class specified by XmNentryClass.

      2. It lays out its children and, if XmNisAligned is True, aligns the labels of children that are XmLabel or XmLabelGadget subclasses.

      3. It stores the widget ID of the last menu item selected in the XmNmenuHistory resource.

      4. It allows the application to supply a single callback list for all button children. If XmNentryCallback is not NULL, it disables the XmNactivateCallback and XmNvalueChangedCallback callbacks for its button children and arranges for the buttons to call the XmNentryCallback callbacks instead.

      5. If XmNradioBehavior is True, it ensures that only one ToggleButton at a time is normally selected. It also changes the default values for XmNindicatorType and XmNvisibleWhenOff for its ToggleButton children to the one-of-many, always-displayed style.

      6. It has additional resources for MenuBars and OptionMenus, described in the following sections.

        In addition to XmNentryCallback, RowColumn also has XmNmapCallback and XmNunmapCallback callbacks. These callbacks apply only to PopupMenus and PulldownMenus. The XmNmapCallback callbacks are called just before the menu is posted, and the XmNunmapCallback callbacks are called just after the menu is unposted. They are useful for changing the menu to reflect the current state of the application. For example, an XmNmapCallback callback can use XtSetSensitive to make some menu items insensitive if they are not applicable in the current state of the program.

      7. MenuShell

        The windows associated with PopupMenus and PulldownMenus are top-level windows. That is, the parent window of such a menu is the root window of the screen, not the window associated with the parent widget. This allows the menu to appear anywhere on the screen without being clipped by the parent widget's window.

        The parent widget of each PopupMenu and PulldownMenu RowColumn must be a MenuShell. It is actually the MenuShell's window that is the top-level window. XmMenuShell is a subclass of OverrideShell, so the window manager ignores MenuShell's windows.

        A MenuShell is often invisible to the application. The Motif convenience routines for creating PopupMenus and PulldownMenus automatically create MenuShell parents for these menus. When a PulldownMenu is the child of a PopupMenu or another PulldownMenu, the child's MenuShell is actually the child of the parent's MenuShell. The convenience routines for creating PulldownMenus manage these relations automatically.

        Motif arranges for the RowColumn's window to coincide with the MenuShell's window. Setting XmNheight, XmNwidth, or XmNborderWidth for either a MenuShell or its child sets that resource to the same value in both the parent and the child. For a child of a MenuShell, setting XmNx or XmNy sets the corresponding resource of the parent but does not change the child's position relative to the parent. XtGetValues for the child's XmNx or XmNy yields the value of the corresponding resource in the parent. The x and y coordinates of the child's upper left outside corner relative to the parent's upper left inside corner are both zero minus the value of XmNborderWidth.

        To change any geometry-related resources of a PopupMenu or PulldownMenu, an application should always specify these resources for the RowColumn child, not the MenuShell parent.

        If an application needs to create a MenuShell explicitly, it should create the MenuShell as a popup child of its parent (using XtCreatePopupShell or XtVaCreatePopupShell ). All Motif convenience routines that create MenuShells do this automatically, and an application rarely needs to create a MenuShell directly.

        [ Previous | Next | Contents | Glossary | Home | Search ]