Native dialogs support - Menus

Menus are implemented on Windows, X and OS X.  Menus on X are implemented with GTK, and have a special requirement:  you must set the ALLEGRO_GTK_TOPLEVEL display flag prior to creating the display which will have menus attached.

A menu can be attached to a single display window or popped up as a context menu.  If you wish to use the same menu on multiple displays or use a sub-menu as a context menu, you must make a copy via al_clone_menu or al_clone_menu_for_popup.

Top level items in a non-popup menu must have at least one sub-item, or the behavior is undefined.

Each menu item can be given an ID of any 16-bit integer greater than zero.  When a user clicks on a menu item, an event will be generated only if it has an ID.  This ID should be unique per menu; if you duplicate IDs, then there will be no way for you to determine exactly which item generated the event.

There are many functions that take pos as a parameter used for locating a particular menu item.  In those cases, it represents one of two things: an ID or a zero-based index.  Any value greater than zero will always be treated as an ID.  Anything else (including zero) will be considered an index based on the absolute value.  In other words, 0 is the first menu item, -1 is the second menu item, -2 is the third menu item, and so on.

The event type is ALLEGRO_EVENT_MENU_CLICK.  It contains three fields:


event.user.data1 := id;
event.user.data2 := AL_INTPTR_T (display);
event.user.data3 := AL_INTPTR_T (menu);
  

The display and menu may be NIL if it was not possible to tell exactly which item generated the event.

A basic example:


CONST
  FILE_EXIT_ID = 1;
VAR
  Menu, FileMenu: ALLEGRO_MENUptr;
  ...
BEGIN
  Menu := al_create_menu;
  FileMenu := al_create_menu;
  al_append_menu_item (FileMenu, 'Exit', FILE_EXIT_ID, 0, NIL, NIL);
  al_append_menu_item (Menu, 'File', 0, 0, NILL, FileMenu);
  al_set_display_menu (Display, Menu);
  al_register_event_source (Queue, al_get_default_menu_event_source);
  ...
  al_wait_for_event (Queue, Event);
  IF Event._type = ALLEGRO_EVENT_MENU_CLICK THEN
    IF Event.user.data1 = FILE_EXIT_ID THEN
     ExitProgram;
  ...
END;
  

Because there is no "DISPLAY_DESTROYED" event, you must call al_set_display_menu (Display, NIL) before destroying any display with a menu attached, to avoid leaking resources.