ViewKit Menu Support

OSF/Motif provides the components for building menus (buttons, menu shells, and so on) but does little to make menu construction easy. ViewKit ObjectPak provides a set of classes that facilitate common operations on menus, including creating menu bars, menu panes, popup menus, option menus, and cascading menu panes. The ObjectPak menu package also provides an object-oriented interface for activating and deactivating menu items, dynamically adding, removing, or replacing menus items or menu panes, and performing other operations.

VkMenuItem

The basis for all ViewKit ObjectPak menu classes is the abstract class VkMenuItem, which is derived from VkComponent. There are two types of classes derived from VkMenuItem. The first serve as containers and correspond to the menu types supported by OSF/Motif: popup menus, pulldown menu panes, menu bars, and option menus. The second type of derived classes are individual menu items: actions, toggles, labels, and separators.

The classes derived from VkMenuItem correspond closely with OSF/Motif widgets and gadgets. For example, an action implemented as a VkMenuAction object represents a XmPushButton gadget along with an associated callback. However, the ObjectPak menus offer several advantages over directly using OSF/Motif widgets and gadgets. You can manipulate the menu objects more easily than widgets. You can display, activate, and deactivate items with a single function call. You can also easily move or replace items.


Caution: ObjectPak implements menu items as gadgets rather than widgets. This causes a problem in callbacks and other situations if you try to use certain Xt functions (such as XtDisplay(3), XtScreen(3), and XtWindow(3)) that expect widgets as arguments. Therefore, you should use the more general functions (such as XtDisplayofObject(3), XtScreenofObject(3), and XtWindowofObject(3)) when you need to obtain this information for ObjectPak menu items.


VkMenu

VkMenu, derived from VkMenuItem, is the abstract base class that implements the functionality needed to create and manipulate menus. It provides support for creating menus and adding, removing, replacing, finding, activating, and deactivating menu items.

Subclasses of VkMenu

Separate subclasses of VkMenu implement the various types of menus supported by ObjectPak:

 

 

VkMenu Subclass

Description

VkMenuBar

Menu bars designed to work with VkWindow class

VkPopupMenu

Popup menus that automatically pop up when the user clicks the right mouse button over a widget

VkOptionMenu

Option menus

VkSubMenu

Pulldown menus panes that can be used either as pull-down panes in a menu bar or pull-right panes in a popup or other pull-down menu

VkRadioSubMenu

A subclass of VkSubMenu used to enforce radio behavior on toggle items that it contains

 

 

Subclasses derived from VkMenuItem

Individual menu items are implemented as subclasses derived from VkMenuItem, as shown in the following table:

 

 

VkMenuItem Subclass

Description

VkMenuAction

A selectable menu item that performs an action, implemented as a PushButtonGadget

VkMenuConfirmFirstAction

A selectable menu item that performs an action that the user must confirm before it is executed. When the user selects this type of menu item, the application posts a question dialog asking the user for confirmation. The application performs the action only if the user confirms it.

VkMenuToggle

A two-state toggle button gadget. To enforce radio behavior on a group of toggles, you must add them to a VkRadioSubMenu object.

VkMenuLabel

A non-selectable label

VkMenuSeparator

A non-selectable separator

 

 

This section describes the features of the ObjectPak menu item classes. First it describes the features implemented by VkMenuItem, which are common to all the menu item classes. Then it describes the unique features of each individual menu item class.

For more detailed information about submenus, refer to "Submenus" and "Radio Submenus" .


Note: The header file <Vk/VkMenuItem.h> contains the declarations for all menu item classes.


Common Features of Menu Items

VkMenuItem provides a standard set of functions for accessing and manipulating menu items. Individual menu items are implemented as subclasses derived from VkMenuItem. Unlike many ObjectPak classes, you should never need to directly instantiate a menu item class. ObjectPak automatically instantiates menu item objects when you create menus (refer to "Constructing Menus" for more detailed information). This guide does not describe the menu item constructors and destructors.

ViewKit implements menu items as gadgets rather than widgets. If you want to directly access menu item gadgets, use Xt functions that accept gadgets, as well as widgets, as arguments.

Displaying and hiding menu items

The VkMenuItem::show() function makes a menu item visible when you display the menu to which it belongs:

void show()

By default, all menu items are visible when created (that is, they appear when you display the menu to which they belong). An explicit call to a menu item's show() function is not necessary to display it. You can call show() to display a menu item after you have hidden it with hide().

The VkMenuItem::hide() function makes a menu item invisible when you display the menu to which it belongs:

void hide()

hide() does not remove the menu item from the menu, but unmanages the widget or gadget associated with a menu item. You can display a hidden menu item by calling its show() function.

To remove a menu item from a menu, call VkMenuItem::remove():

void remove()

remove() does not destroy a menu item, but removes the item from the menu hierarchy.


Note: Instead of retaining pointers to all your menu items and using VkMenuItem::remove() to remove menu items, use VkMenu::removeItem(). The effect is the same regardless of the function you use. Typically, using the VkMenu function is easier. Refer to "Manipulating Items in Menu" on page 146 for a more detailed description of VkMenu::removeItem().


Activating and deactivating menu items

The VkMenuItem::activate() function makes a menu item sensitive so that it accepts user input (that is, a user can select the item):

void activate()

By default, all menu items are activated (sensitive) when they are created.

The VkMenuItem::deactivate() function makes a menu item insensitive so that it does not accept user input (that is, a user cannot select the item):

void deactivate()

When insensitive, the menu item appears "grayed out" when you display the menu to which it belongs. You can re-activate a menu item by calling its activate() function.


Note: Instead of retaining pointers to all of your menu items and using VkMenuItem::activate() and VkMenuItem::deactivate() to activate and deactivate menu items, you can instead use VkMenu::activateItem() and VkMenu::deactivateItem() respectively. The effect is the same no matter which functions you use, though typically you will find it easier to use the VkMenu functions. "Activating and deactivating items in a menu" on page 147 describes VkMenuItem::activate() and VkMenuItem::deactivate().


Setting menu item labels

Generally, you should set the label for a menu item by setting a value in the resource database for that item's XmNlabelString resource. For example, if you have a menu item named "addPage", you could set the label for that item by including a resource specification such as:

*addPage.labelString: Add Page

If you do not set the menu item's XmNlabelString resource, ObjectPak uses the item's name.

In some cases, you might need to set the label of an item programmatically. For example, in a page layout system you might want to change the labels for the items in an Edit menu to reflect the type of object the user has currently selected. You can change a menu item's label programmatically with the setLabel() function:

virtual void setLabel(const char * str)

The string is treated first as a resource name that setLabel() looks up relative to the menu item's widget. If the resource exists, its value is used as the item's label. If the resource does not exist, or if the string contains spaces or newline characters, setLabel() uses the string itself as the item's label. This allows applications to dynamically set and change menu item labels without hard-coding the exact label strings in the application code.

Setting the position of menu items

By default, ObjectPak inserts items into a menu in the order you specify them. Therefore, the easiest way to set the positions of menu items is to add them to the menu in the order that you want them to appear.

Occasionally you might need to explicitly set the position of a menu item. To do so, use VkMenuItem::setPosition():

void setPosition(int position)

setPosition() sets the item's position in the menu. You can specify any integer value from zero to the number of items in the menu; a value of zero specifies the first position in the menu. setPosition() ignores invalid values.


Note: setPosition() is effective only before ObjectPak realizes the menu to which the menu item belongs. If you call setPosition() after realizing a menu, it has no effect. For example, if you create a menu bar in a window's constructor, you can use setPosition() to position menu items; however, after calling the window's show() function, setPosition() has no effect.


Menu items utility functions

You can use MenuItem::menuType() to determine the specific menu item type when given a pointer to a VkMenuItem object:

virtual VkMenuItemType menuType()

menuType() returns one of the following enumerated values of type VkMenuItem::VkMenuItemType:

 

 

Enumerated Value

Description

ACTION

A VkMenuAction object

CONFIRMFIRSTACTION

A VkMenuConfirmFirstAction object

TOGGLE

A VkMenuToggle object

LABEL

A VkMenuLabel object

SEPARATOR

A VkMenuSeparator object

SUBMENU

A VkSubMenu object

RADIOSUBMENU

A VkRadioSubMenu object

BAR

A VkMenuBar object

OPTION

A VkOptionMenu object

POPUP

A VkPopupMenu object

OBJECT

A user-defined subclass of
VkMenuActionObject (described
in "Command Classes" )

 

 

You can also determine when an object pointed to by a VkMenuItem pointer is a menu by calling MenuItem::isContainer():

virtual Boolean isContainer()

isContainer() returns TRUE if the VkMenuItem object is an item that can "contain" other menu items (in other words, a menu).

Menu Actions

VkMenuAction class provides a selectable menu item that performs an action. A VkMenuAction object is implemented as a PushButtonGadget.

A VkMenuAction object is associated with a callback function that performs an operation and, optionally, a callback function that "undoes" the operation. You specify these callback functions when you add the item to a menu using one of the methods described in "Constructing Menus" . Consult the section for information on using VkMenuAction objects in a menu. VkMenuAction provides public functions in addition to those implemented by VkMenuItem.

You can determine whether an action has an undo callback associated with it by calling VkMenuAction::hasUndo():

Boolean hasUndo()

hasUndo() returns TRUE if the object has an associated undo callback function.

Calling an undo callback function

If an object has an undo callback function, you can call it programmatically using VkMenuAction::undo():

virtual void undo()

Typically, you will not need to call undo() explicitly. ObjectPak provides automatic undo handling for your application using the VkUndoManager class, as described in Chapter 6--Undo Management and Command Classes. All you have to do is provide undo callback functions for your VkMenuAction objects and create an instance of VkUndoManager as described Chapter 6--Undo Management and Command Classes.

Confirmable Menu Actions

The VkMenuConfirmFirstAction class, derived from VkMenuAction, provides a selectable menu item that performs an action. When the user selects this type of menu item, the application posts a question dialog asking the user for confirmation. The application performs the action only if the user confirms it.

The VkMenuConfirmFirstAction class is intended for irrecoverable actions (for example, deleting a file), VkMenuConfirmFirstAction objects do not support undo callback functions.

The VkMenuConfirmFirstAction class uses a PushButtonGadget to implement the menu choice and the VkQuestionDialog(3) to implement the question dialog. (See "Question Dialog" for more information on the VkQuestionDialog class.)

The question displayed in the confirmation dialog is determined by the value of the "noUndoQuestion" resource, which ObjectPak looks up relative to the menu item's widget. For example, if you have a menu item named "quit", you can set the question text for that item by including a resource specification such as:

*quit.noUndoQuestion: Do you really want to quit?

If you do not provide a value for this resource, ObjectPak uses the default question: "This action cannot be undone. Do you want to proceed anyway?"

Menu Toggles

The VkMenuToggle class, which is derived from VkMenuAction, provides a two-state toggle as a menu item. To enforce radio behavior on a group of toggles, you must add them to a VkRadioSubMenu object; otherwise, VkMenuToggle object exhibit simple checkbox-style behavior. A VkMenuToggle object is implemented as a ToggleButtonGadget.

In addition to the public functions provided by VkMenuItem, VkMenuToggle provides functions for setting and retrieving the toggle state.

Setting the visual state of a toggle

You can set the visual state of a VkMenuToggle object, without activating its associated callback, using VkMenuToggle::setVisualState():

void setVisualState(Boolean state)

setVisualState() selects the toggle if state is TRUE and deselects the toggle if state is FALSE.

You can set the visual state of a VkMenuToggle object and activate its associated callback with VkMenuToggle::setStateAndNotify():

void setStateAndNotify(Boolean state)

Retrieving the current value of a toggle

Call VkMenuToggle::getState() to retrieve the current value of a VkMenuToggle object:

Boolean getState()

getState() returns TRUE if the toggle is currently selected and FALSE if it is currently deselected.

Menu Labels

The VkMenuLabel class provides a non-selectable label as a menu item. A VkMenuLabel object is implemented as a LabelGadget.

The VkMenuLabel class does not provide any public functions other than those implemented by VkMenuItem.

Menu Separators

The VkMenuSeparator class provides a non-selectable separator as a menu item. A VkMenuSeparator object is implemented as a SeparatorGadget.

The VkMenuSeparator class does not provide any public functions other than those implemented by VkMenuItem.

Documentation Type: