## 4.7 Menus

A menu is a widget that contains a collection of items arranged in a column. If a menu is tied to a menuButton, it behaves a a pull-down menu; i.e, they are activated by pressing the mouse button 1 over a menu button. If a menu is tied to a mouse button, it will behave like a popup menu.

### Widget Info

Symbolic widget type | EZ_WIDGET_MENU
Default class name | "Menu"
Default instance name | "menu"

### Widget Interface Routines

`int EZ_DoPopup(EZ_Widget *widget, int where);`

post a menu.

`int EZ_DoPopupAt(EZ_Widget *widget, int x, int y);`

post a menu at the specified location.

`void EZ_SetMenuSetupProcedure(EZ_Widget *menu, EZ_CallBack p, void *data);`

register a procedure to be invoked before posting the menu.

`EZ_Widget *EZ_GetPopupMenuTitleWidget(EZ_Widget *menu);`

return the title widget (a lanel) on a menu.

`EZ_Widget *EZ_GetSelectedMenuItem(EZ_Widget *menu);`

return the last selected item.

### Screenshot

### Resources

Config_Option | ResourceName | DefaultValue
EZ_CLASS | class | `"Menu"`
EZ_NAME | name | `"menu"`

EZ_BORDER_WIDTH | borderWidth | `2`
EZ_BORDER_TYPE | borderType | `raised`
EZ_FOCUS_PAD | focusPad | `0`

EZ_PADX | padx | `0`
EZ_PADY | pady | `0`
EZ_IPADX | iPadx | `0`
EZ_IPADY | iPady | `0`

EZ_ORIENTATION | orientation | `vertical`
EZ_FILL_MODE | fillMode | `fillBoth`
EZ_SIDE | side | `left`

EZ_CURSOR | cursor | `"XC_left_ptr"`

EZ_CALLBACK | N/A | `null null`
EZ_DESTROY_CALLBACK | N/A | `null null`

EZ_FOREGROUND | foreground | `"black"`
EZ_BACKGROUND | background | `"gray74`
EZ_BG_IMAGE_FILE | bgImageFile | `null`
EZ_BG_PIXMAP | N/A | `none`

EZ_CLIENT_PTR_DATA | N/A | `null`
EZ_CLIENT_INT_DATA | clientIntData | `0`

EZ_MENU_TEAR_OFF | menuTearOff | `true`

### 4.7.1 Creating Simple Menus

EZwgl provides a convenient way to create simple menus, menus that uses only menu-normal-buttons, menu-submenus and menu-separators.

`int EZ_CreateSimpleMenu(char *str, ...)`

### Specifing a Simple Menu

A simple menu is specified by a string and an optional set of arguments that provide callback procedures and/or submenus for the menu and menu items.

The string is a number of fields separated by `|`'s. Each field may contain any number of the following specifications:

- `%t` Makes non-formatting text in this item as the menu title string.

- `%F` Gets the callback-procedure, client-data for the callback of the menu from the optional arguments.

- `%f` Gets the callback-procedure, client-data for the callback of this menu-item from the optional arguments.

- `%l` Inserts a menu-separator.

- `%m` Makes this item as a menu-submenu item and gets the menu from the optional arguments.

- `%n` Sets the instance name of the this menu item to be the substring after the current formating characters and before the next formating character or `|`.

- `%c` Sets the class name of the this menu item to be the substring after the current formating characters and before the next formating character or `|`.

- `%u` Set the index of the underline character for the current item.

- `%s` Set the keyboard shortcut for the current item.

- `%x`[0-9]+ Sets the return value for this item. This value overrides the default position-based value assigned to this menu item. You must enter the numeric value as the part of the text

- \verb+are the on value, off value and initial state (on/off).

- \verb+are the radio button group id, the values this item represents and the initial value of the group variable.

Here are some examples.

    void       submenu1Callback(EZ_Widget *, void *);
    void       Item2Callback(EZ_Widget *, void *);

    EZ_Widget *submenu1 = EZ_CreateSimpleMenu("%F|red|green%x123 %s C-g|blue %u 0|%l|||",
                                                    submenu1Callback, NULL);

    EZ_Widget *menu = EZ_CreateSimpleMenu("%T Test Menu|Item 1|Item 2%f|submenu%m|last item"
                                                    Item2Callback, NULL, submenu1);

The first two lines declare two callbacks, one for a submenu and one for a menu item.

The third line creates a simple menu. This submenu has callback `submenu1Callback` with client data `NULL`. It contains 5 menu items and a menu-separator. The first three items are labeled by "red", "green" and "blue" respectively. The second item has a numeric return value of `123` and a keyboard shortcut "C-g". The letter 'b' in the third item will be underlined and will be used as a keyboard accelerator. The other items have the default return values (their position in the menu). The last two items have no lables specified, so the default lable `item #` will be used for them.

The forth line create a menu with title "Test Menu" and no callbacks. It contains four items. The second item has a callback procedure `Item2Callback` with call-data `NULL`. The third menu is a submenu-item with menu `submenu1`.

### Specifing a Menu Tree

One can create a menu hierarchy with a single call to `EZ_CreateMenuFromList`. This function requires an array of menu descriptions of the followingn type.

    typedef struct menuEntry_ {
      int           type;           /* entry type, e.g. EZ_WIDGET_MENU_NORMAL_BUTTON */
      char          *name;          /* instance name, may be NULL */
      char          *label;         /* label string */
      char          *accelerator;   /* keyboard accelerator, e.g. C-a,  may be NULL */
      int           underline;      /* index of label to underline */
      int           returnValue;    /* return value */
      EZ_CallBack   callback;       /* callback  */
      void          *clientData;    /* client data to be passed to callback */
      int           v1,v2,v3;       /* for radioBtn, groupId, buttonValue, groupVarValue */
                                    /* for checkBtn, onValue, offValue, initialOnOffState */
    } EZ_MenuEntry;

For example, the next code segments defines a menu with a submenu.

    static  void btnCb(EZ_Widget *, void *);
    static  void rbtnCb(EZ_Widget *, void *);
    static  void cbtnCb(EZ_Widget *, void *);

    static EZ_MenuEntry menuEntries[] = {
      {EZ_WIDGET_MENU_NORMAL_BUTTON,  NULL,  "normal Button",  NULL,  0,     100,   btnCb,    NULL,  0, 0, 0 },
      {EZ_WIDGET_MENU_NORMAL_BUTTON,  NULL,  "Another Button", "M-b", 0,     200,   btnCb,    NULL,  0, 0, 0 },
      {EZ_WIDGET_MENU_SEPARATOR,      NULL,  NULL,             NULL,  0,     0,     NULL,     NULL,  0, 0, 0 },
      {EZ_WIDGET_MENU_SUBMENU,        NULL,  "Walk Through",   "C-s", 0,     300,   NULL,    NULL,   0, 0, 0 },
         {EZ_WIDGET_MENU_NORMAL_BUTTON,  NULL, "S 1",            NULL,  0,     400,   btnCb,    NULL,  0, 0, 0 },
         {EZ_WIDGET_MENU_NORMAL_BUTTON,  NULL, "S 2",            NULL,  0,     500,   btnCb,    NULL,  0, 0, 0 },
         {EZ_WIDGET_MENU_SEPARATOR,      NULL,  NULL,            NULL,  0,     0,     NULL,     NULL,  0, 0, 0 },
         {EZ_WIDGET_MENU_CHECK_BUTTON,   NULL, "C 1",            NULL,  0,     600,   cbtnCb,   NULL,  0, 1, 1 },
         {EZ_WIDGET_MENU_CHECK_BUTTON,   NULL, "C 2",            NULL,  0,     700,   cbtnCb,   NULL,  0, 1, 0 },
         {EZ_WIDGET_MENU_SEPARATOR,      NULL,  NULL,            NULL,  0,     0,     NULL,     NULL,  0, 0, 0 },
         {EZ_WIDGET_MENU_RADIO_BUTTON,   NULL, "R 1",            "C-r"  0,     800,   rbtnCb,   NULL,  5, 0, 0 },
         {EZ_WIDGET_MENU_RADIO_BUTTON,   NULL, "R 2",            NULL,  0,     900,   rbtnCb,   NULL,  5, 1, 0 },
         {EZ_WIDGET_MENU_RADIO_BUTTON,   NULL, "R 3",            NULL,  0,     1000,  rbtnCb,   NULL,  5, 2, 2 },
         {0,                             NULL, NULL,             NULL,  0,     0,     NULL,     NULL,  0, 0, 0 },
      {EZ_WIDGET_MENU_NORMAL_BUTTON,  NULL,  "Last Button", NULL,     0,     2000,  btnCb,    NULL,  0, 0, 0 },
      {0,                      NULL, NULL,             NULL,       0, 0,     NULL,     NULL,  0, 0, 0 },
      NULL,
    };

    EZ_Widget *menu = EZ_CreateMenuFromList(menuEntries);

HTML Documentation Maintainance:`Arturo Espinosa <arturo@nuclecu.unam.mx>`