# vMenu

Used to define pull down menus.

## Synopsis

Header:
  `<v/vmenu.h>`
Type name:
  vMenu

## Description

The `vMenu` structure is used to define pulldown menus, which includes the top level items on the menu bar, as well as the items contained in the pulldown menus off the menu bar. The `vMenu` structure is also used to define menus for `vPopupMenu` menus. `vMenu` structs are passed to the constructor of `vMenuPane` or `vPopupMenu` objects.

See the section `vPane` for a general description of panes.

## Definition

    typedef struct vMenu
      {
        char* label;       // The label on the menu
        ItemVal menuId;    // A User assigned unique id
        unsigned
         sensitive : 1,    // If item is sensitive or not
         checked : 1;      // If item is checked or not (*)
        char* keyLabel;    // Label for an accelerator key (*)
        vKey accel;        // Value of accelerator key
        vMenu* SubMenu;    // Ptr to a submenu
        unsigned int kShift; // Shift state of accelerator
      } MenuItem;

Note that the items marked with an asterisk (`checked` and `keyLabel`) are not used when defining the top level menu bar items.

## Structure Members

`char* label`

The label on the menu. See the description of the `vCmdWindow` class for information on setting the label of menu bar items.

For some platforms (Windows, but not Athena X), you can add a & to indicate a shortcut for the command. For example, specifying a label `&File` allows Windows users to pull down the `File` menu by pressing `Alt-F`, and specifying a submenu label as `&New` allows the user to use `Alt-N` to select the `New` command. The Athena version of V strips the &, so you can (and probably should) denote shortcuts for menu items even in Athena versions.

`ItemVal MenuId`

A user assigned unique id. This id is passed to the `MenuCommand` (or `WindowCommand`) method when a menu item is selected. If a menu item with a submenu is selected, V will not return the id, but will cause the submenu to be displayed.

It will be common practice to use the same id for menu items and command objects defined on a command bar, and the same id value would then be passed to `WindowCommand` for either the menu selection or the equivalent button selection. Similarly, using the id to set the item's sensitivity will change both the menu and the button.

The values you use for your id in menus and controls should be limited to being less than 30,000. The predefined V values are all above 30,000, and are reserved. There is no enforcement of this policy. It is up to you to pick reasonable values.

If you want a separator line on a pulldown menu, you must use the predefined value `M_Line` for the `MenuId`.

`int sensitive`

Controls if item is initially sensitive or not. Insensitive items are displayed grayed out. The predefined symbols `notSens` and `isSens` can be used to define the `MenuItem`. Note that V uses the static definition of the `MenuItem` to store the current sensitive state, and all menus (or windows) sharing the same static definition will have the same sensitive state. See the description of the `vCmdWindow` class for information on setting the sensitivity of menu bar items.

`int checked`

The user can put a check mark in front of the label of a menu item. This convention is often used to show a given setting is in effect. Like the sensitive member, this statically tracks the checked state. The predefined values `isChk` and `notChk` can be used to specify this value. This value is not used when defining the top level menu bar, and you can use the predefined value `notUsed` for that case. See the description of the `vCmdWindow` class for information on setting checked state of menu items.

`char* keyLabel`

Label for an accelerator key. The predefined symbol `noKeyLbl` can be used to indicate there is no `keyLabel`. This value is not used when defining the top level menu bar, and you can use the predefined value `notUsed` accelerator key.

`vKey accel`

This is the value of the keystroke that is the accelerator for this menu item. When the user presses this key, the `vWindow::MenuCommand` method will be called just as though the user had used the mouse to select the menu item. This value may be used in combination with the `kShift` and `keyLabel` parameters. See the explanation of `vWindow::KeyIn` for a complete explanation of key codes.

Note that the Windows version really doesn't support `Alt` key codes. The Windows system intercepts Alt keys and tries to interpret them as menu accelerators. Unfortunately, there is no simple way to override this behavior, so Alt keys are essentially unsupported on Windows. Using functions keys with combinations of Shift and Control is supported, as are regular control keys.

`MenuItem* SubMenu`

Pointer to another `MenuItem` definition of a submenu. V will cause submenus to be shown automatically when selected. The predefined symbol `noSub` can be used to indicate there is no submenu.

`unsigned int kShift`

This is the shift value to be used with the `accel` key definition. To use `Ctrl-D` as the accelerator key, you would specify the value for Control-D (easily specified as `'D'-'@'`) for `accel`, and leave `kShift` set to zero. If you use a Ctrl code, you must specify both the control code, and the `VKM_Ctrl` shift code. Note that this value is at the end of the `vMenu` structure because of it was forgotten in early implementations of V. By placing it at the end, earlier versions of Vcode are compatible with no changes to the source. Sigh, I didn't get this one right.

### Example

This example defines a menu bar with the items File and Edit. The `MenuBar` definition would be passed to the constructor of the appropriate `vCmdWindow` derived object.

Only the File submenu is shown here, and is an example of the menu as it might be included in a standard File menu. Note that this example menu includes items that can all be specified by using standard predefined values (see Predefined ItemVals). It also includes an optionally defined `Debug` item. A definition like this might be used for the `FileMenu` in the `Menu` example. Note that & is used to denote shortcuts for menu items.

    static vMenu FileMenu[] =
      {
        {"&New", M_New, isSens,notChk,noKeyLbl,noKey,noSub},
        {"&Open", M_Open, isSens,notChk,noKeyLbl, noKey, noSub},
        {"&Save", M_Save, isSens,notChk,noKeyLbl,noKey,noSub},
        {"Save &As", M_SaveAs, isSens,notChk,noKeyLbl,noKey,noSub},
    #ifdef vDEBUG
        {"-", M_Line, notSens,notChk,noKeyLbl,noKey,noSub},
        {"&Debug", M_SetDebug,isSens,notChk,noKeyLbl,noKey,noSub},
    #endif
        {"-", M_Line, notSens,notChk,noKeyLbl,noKey,noSub},
        {"E&xit", M_Exit, isSens,notChk,noKeyLbl,noKey,noSub},
        {0}
      };

    static vMenu EditMenu[] = {...};  // Define Edit pulldown

    // Define menu bar, which includes the File and Edit pulldown
    static vMenu MenuBar[] =
      {
        {"&File",M_File,isSens,notUsed,notUsed,noKey,&FileMenu[0]},
        {"&Edit",M_Edit,isSens,notUsed,notUsed,noKey,&EditMenu[0]},
        {0,0}                         // end of menubar
      };

      ...

      vMenuPane myMenuPane = new vMenuPane(MenuBar);  // construct pane
      AddPane(myMenuPane);

## See Also

vCmdWindow, vPane, vPopupMenu