## MenuBars, Menus and MenuItems

### OBJECTS

      typedef struct MenuBar     MenuBar;
      typedef struct Menu        Menu;
      typedef struct MenuItem    MenuItem;

      typedef void (*MenuAction)(MenuItem *mi);

      struct MenuBar {
        Control *   ctrl;           /* associated control */
        Font *      font;           /* for displaying all text */
        int         align;          /* text alignment,direction */
        int         num_menus;      /* list of menus */
        Menu **     menus;
      };

      struct Menu {
        MenuBar *   parent;         /* enclosing menubar */
        char *      text;           /* name of the menu */
        int         num_items;      /* list of menu items */
        MenuItem ** items;
        int         lasthit;        /* which item was chosen */
        Font *      font;           /* for displaying items */
      };

      struct MenuItem {
        Menu *      parent;         /* enclosing menu */
        char *      text;           /* menu item name */
        int         shortcut;       /* shortcut key */
        int         state;          /* enabled? checked? */
        Menu *      submenu;        /* pop-up menu */
        MenuAction  action;         /* user-defined action */
        void *      data;           /* user-defined data */
        int         value;          /* user-defined value */
        Font *      font;           /* for displaying this item */
        Colour      fg;             /* for displaying text */
      };

### FUNCTIONS

      MenuBar * new_menu_bar(Window *win);
      void      del_menu_bar(MenuBar *mb);

      Menu *    new_menu(MenuBar *mb, char *name);
      Menu *    new_sub_menu(Menu *parent, char *name);
      void      del_menu(Menu *m);

      MenuItem *new_menu_item(Menu *m, char *name, int key,
                                  MenuAction fn);
      void      del_menu_item(MenuItem *mi);

      void      check_menu_item(MenuItem *mi);
      void      uncheck_menu_item(MenuItem *mi);
      int       menu_item_is_checked(MenuItem *mi);

      void      enable_menu_item(MenuItem *mi);
      void      disable_menu_item(MenuItem *mi);
      int       menu_item_is_enabled(MenuItem *mi);

      void      set_menu_item_value(MenuItem *mi, int value);
      int       get_menu_item_value(MenuItem *mi);

      void      set_menu_item_foreground(MenuItem *mi, Colour col);
      Colour    get_menu_item_foreground(MenuItem *mi);

      void      set_menu_item_font(MenuItem *mi, Font *font);
      Font *    get_menu_item_font(MenuItem *mi);

      void      set_menu_foreground(Menu *m, Colour col);
      Colour    get_menu_foreground(Menu *m);

      void      set_menu_font(Menu *m, Font *font);
      Font *    get_menu_font(Menu *m);

      void      set_menu_bar_font(MenuBar *mb, Font *font);
      Font *    get_menu_bar_font(MenuBar *mb);

### NOTES

A MenuBar is a horizontal bar in which the names of menus appear. A Menu refers to a pull-down menu which contains MenuItems.

A menu bar can be associated with a window by calling new_menu_bar after that window has been created. This function will return NULL if it fails for some reason. Calling del_menu_bar will destroy the menu bar and all associated menus and menu items, also removing the menu bar from the window. Destroying a window will automatically call this function.

After creating a menubar, the new_menu function is used to create menus, which are attached to the menubar. Each menu has a `name` which is displayed in the menubar, for example "File" might be the name of the menu which controls file operations.

The new_sub_menu function can also be used to create menus. The `parent` parameter specifies a menu to which the new sub-menu will be added. The `name` of the sub-menu will appear in the `parent` menu, and selecting this name will make the sub-menu appear. The del_menu function can be used to delete a menu from a menu bar, and destroy all of its menu items.

After the creation of a menu, menu items can be added to it using new_menu_item. The `name` of the item is a string which is displayed in the menu. Next to that name a short-cut key can be displayed. If `key` is non-zero it specifies an ASCII character which can be typed in combination with some other keyboard key to activate this menu item. For instance, if the key were given as 'Q', on a Windows platform the menu item would appear with "Ctrl+Q" next to its name, signifying that pressing the control key and the letter 'Q' together would trigger this menu item. Other platforms would display their own normal menu key-combinations.

A menuitem created with a name which is a hyphen "-" will cause a 'separator' line to appear in the pull-down menu. This can be used to logically group items in a menu.

The function pointer `fn` given as a parameter to new_menu_item is called when that menu item is selected by the user. When this call-back function is called, a pointer to the menu item is passed as a parameter to `fn`.

Use del_menu_item to delete one menu item and remove it from its menu.

The check_menu_item function places a check-mark beside a menu item within its menu, while the uncheck_menu_item function removes any such check-mark. The menu_item_is_checked function returns non-zero if the menu item has a check-mark next to it, zero if it does not. Menu items initially have no check-mark.

Menu items are enabled for mouse selection by default. They can be disabled using disabled_menu_item, and re-enabled using enable_menu_item. Whether a menu item is currently enabled can be determined using menu_item_is_enabled. Separator menu items are disabled when created.

Each menu item can have an integer value associated with it, by set_menu_item_value. The value can be retrieved using get_menu_item_value.

A menu item can also have its own font and foreground colour, which are used when the font's text is to be displayed. The functions set_menu_item_foreground and get_menu_item_foreground access the text colour.

The functions set_menu_item_font and get_menu_item_font are used to access a menu item's text font. By default, a menu item does not have its own font, in which case the menu bar's font is used for displaying text, which is Unifont by default. Setting the menu bar's font using set_menu_bar_font is all that is needed to change all menu items' displayed text to a single font.

Menus can also have a text font, accessed with set_menu_font and get_menu_font. A menu's font is only used when displaying its name in a menu bar or as a submenu name within another menu. If it has no font, the menu bar's font is used. Similarly, its text colour is accessed with set_menu_foreground and get_menu_foreground, and is only used for displaying the menu's name.