Blitz:Menus

From Amiga Coding
Jump to: navigation, search

Blitz allows you to add standard Intuition menus to your program's windows. There are two sets of internal commands for using menus - the original menu commands and the GadTools menu commands. The original menus will work on all versions of the Amiga OS, however they are also rendered in the style of the old OS 1.x screens and offer very little flexibility. The GadTools menus are more flexible and are styled to match whatever OS version they're running on, however they're only compatible with OS 2.0 and above.

Defining Menus

Each menu title, menu item, and sub item if required, needs to be defined individually using the appropriate command. Once fully defined, the menu items are collected together into a menu strip which can then be attached to a window. Multiple menu strips can be defined, but only one menu strip can be attached to a particular window at any one time.

Intuition Menus

These menus are the original Amiga OS menus, and as such are compatible with every version of the OS from 1.x on. They are limited however (for example, no font sensitivity, no OS-defined imagery for shortcuts etc.), and should be avoided unless OS 1.x compatibility is absolutely required for your software. If you only need compatibility with OS 2 and above, please consider using GadTools Menus instead.

MenuTitle

This command defines a menu title to which a list of menu items belong, based on the parameters you provide. An example of the usage is as follows:

MenuTitle 0, #projectmenu, "Project"

In this example, the 0 is the MenuList ID number. This represents a complete set of menus associated with a window. #projectmenu is a constant defining the ID of this menu title, and is used to identify the menu in which an item has been selected. Numbers can also be used here, but this can make your code trickier to read later on.

Note: Menu title IDs must be assigned sequentially starting at 0. This number defines the order of the menu titles across the screen, starting with 0 at the left.

MenuItem

This command defines a menu item for entry beneath a menu title. It has a number of parameters that are required, and a number of optional parameters. These are as follows:

MenuItem MenuList, flags, menu, item ,itemtext$ [,shortcut$]

MenuList is the overall menu set this item is to belong to. The flags parameter is used for defining special properties of the menu. Please see the Menus Autodocs for details of the flags. Mostly this can be left at 0, but for menu items which can be toggled with a checkmark, set the flags #MENUTOGGLE and #CHECKIT.

The menu parameter is the ID number of the menu title to which this item will belong, starting at 0 for the leftmost title.

The item parameter is the ID number of the item to create, starting at 0 for the first item. This number determines the order of the items in the menu and is used to identify an item selected by the user.

The itemtext$ parameter is a string containing the text to be displayed for that item.

The shortcut$ parameter is a string defining the shortcut key to associate with the entry. It should be a single character and is usually specified as a capital letter, though it is not case sensitive when in use.

SubItem

This command defines a sub-menu item. The parameters are as follows:

SubItem MenuList, flags, menu, item, subitem ,itemtext$ [,shortcut$]

Its usage is almost identical to that of MenuItem above, except that an extra subitem parameter is required to identify the subitem entry within the menu item submenu. Again, this is an ID value starting at 0 for the first entry in the submenu.

Note: It is good practice to add a double-angle character to the end of the parent menu item of any sub items to indicate sub items are available. This can be done by appending Chr$(187) to the end of the parent item's text. GadTools menus will do this automatically.

MenuGap

This command is used to manually adjust the gaps left around menu items - something GadTools menus do automatically. It must be executed before any menu creation commands are executed. For example:

MenuGap 2, 5

This will tell Intuition to leave 2 pixels to the left and right of each item, and 5 pixels above and below each item. Be careful using this command as it can cause graphical glitches on 1.2 and earlier versions of the OS.

Example Code

The following code sets up a menu strip and attaches it to a window.


; Menu constants. These values determine the order of the items in question, starting at 0 for the first.
 
#menu_project        = 0 ; First menu title
  #menu_openproject  = 0 ; First item in Project menu
  #menu_about        = 1 ; Second item in Project menu
  #menu_quit         = 2 ; Third item in Project menu
#menu_settings       = 1 ; Second menu title
  #menu_size         = 0 ; First item in Settings menu
    #menu_small      = 0 ; First sub-item
    #menu_medium     = 1 ; Second sub-item
    #menu_large      = 2 ; Third sub-item
  #menu_opensettings = 1 ; Second item in Settings menu
  #menu_savesettings = 2 ; Third item in Settings menu

MenuGap 2, 0 ; Leave a little extra space to the left and right of each item

MenuTitle 0, #menu_project, "Project"
  MenuItem 0, 0, #menu_project, #menu_openproject, "Open...", "O"
  MenuItem 0, 0, #menu_project, #menu_about, "About...", "?"
  MenuItem 0, 0, #menu_project, #menu_quit, "Quit", "Q"

MenuTitle 0, #menu_settings, "Settings"
  MenuItem 0, 0, #menu_settings, #menu_size, "Size"
    SubItem 0, #CHECKIT|#CHECKED, #menu_settings, #menu_size, #menu_small, "Small", "S" ; This item has a checkmark and is mutually exclusive with the other subitems below. It defaults to checked with the #CHECKED flag
    SubItem 0, #CHECKIT, #menu_settings, #menu_size, #menu_medium, "Medium", "M" ; This item is also a checkmark item but defaults to unchecked.
    SubItem 0, #CHECKIT, #menu_settings, #menu_size, #menu_large, "Large", "L" ; Third sub-item is another checkmark item but again defaults to unchecked.
  MenuItem 0, 0, #menu_settings, #menu_opensettings, "Open Settings...", "P"
  MenuItem 0, 0, #menu_settings, #menu_savesettings, "Save Settings", "A"

win.l = Window(0, 100, 100, 200, 100, #WFLG_DRAGBAR|#WFLG_DEPTHGADGET|#WFLG_CLOSEGADGET|#WFLG_ACTIVATE|#WFLG_NEWLOOKMENUS, "Test Window", 1, 2) ; Enable New Look menus
If win = False Then NPrint "Unable to open window!":End

SetMenu 0 ; Attach MenuStrip 0 to the current window

; Put event handling code here...

GadTools Menus

These menus use the GadTools system provided with OS 2.0 and above to provide their functionality. In order to match styles correctly, a screen object must be currently used and the #NewLookMenus flag should be set when opening the window. Otherwise the menus will default to the OS 1.x look. By and large they work the same way as the Intuition menus above, including using the same flags.

Important! If you use GadTools menus with a standard Intuition window, you MUST close the window yourself before the program ends or it could crash on exit. I don't know if this is a limitation of the GadTools library or a bug, but closing the window with the CloseWindow command prevents this from happening.

GTMenuTitle

This command is the same as MenuTitle above, see the description there for details.

Note: Menu title IDs must be assigned sequentially starting at 0. This number defines the order of the menu titles across the screen, starting with 0 at the left.

GTMenuItem

This command is similar to the MenuItem command above, see the description there for details. Some parameters have changed or been added however, usage is as follows:

GTMenuItem GTMenuList, flags, menu, item [,itemtext$ [,shortcut$ [,mutualexclude [,UserData]]]]

Please see the GadTools Menus Autodocs for details of the flags, though most are the same as the Intuition menu flags. Mostly this can be left at 0, but for menu items which can be toggled with a checkmark, set the flags #MENUTOGGLE and #CHECKIT. Mutually exclusive items should not have the #MENUTOGGLE flag set - only #CHECKIT is required along with the mutualexclude parameter (see below).

The itemtext$ parameter is optional for GadTools menus, and omitting this parameter will insert a horizontal separator line in the menu at that position instead.

The Shortcut$ parameter, as for standard Intuition menus, contains a single character that will be used for the keyboard shortcut of that menu item. However, you must not assign a keyboard shortcut for menu items that are mutually exclusive. Doing so will cause your program to crash badly during menu creation. I suspect a bug in the Blitz GadTools library since I can't find anything in the GadTools Autodocs that says you shouldn't do this.

The mutualexclude parameter is a value whose bits map out which other entries in the same menu should be disabled when this entry is enabled, to allow the user to pick one of several options.

Finally, the UserData parameter is a value that is provided by the user and stored in the internal structure of the menu. The menus don't use this directly, but the value can be retrieved by your program if required. Normally this isn't required, but in the case of a program using MUI, this parameter is the value returned by MUI as an event code if the user selects this item.

GTSubItem

This command defines a sub-menu item. The parameters are as follows:

GTSubItem GTMenuList, flags, menu, item, subitem [,itemtext$ [,shortcut$ [,mutualexclude [,UserData]]]]

Its usage is almost identical to that of GTMenuItem above, except that an extra subitem parameter is required to identify the subitem entry within the menu item submenu. Again, this is an ID value starting at 0 for the first entry in the submenu.

Any menu item to which sub items are assigned will have an appropriate graphical arrow added on the right to indicate that a submenu is available with further options.

Example Code

The following code sets up a menu strip and attaches it to a window.


WBToScreen 0 ; We need a currently used screen - in this case, we'll use the Workbench screen

; Menu constants. These values determine the order of the items in question, starting at 0 for the first.
 
#menu_project        = 0 ; First menu title
  #menu_openproject  = 0 ; First item in Project menu
  #menu_spacer1      = 1 ; Spacer
  #menu_about        = 2 ; Second item in Project menu
  #menu_quit         = 3 ; Third item in Project menu
#menu_settings       = 1 ; Second menu title
  #menu_size         = 0 ; First item in Settings menu
    #menu_small      = 0 ; First sub-item
    #menu_medium     = 1 ; Second sub-item
    #menu_large      = 2 ; Third sub-item
  #menu_opensettings = 1 ; Second item in Settings menu
  #menu_savesettings = 2 ; Third item in Settings menu

GTMenuTitle 0, #menu_project, "Project"
  GTMenuItem 0, 0, #menu_project, #menu_openproject, "Open...", "O"
  GTMenuItem 0, 0, #menu_project, #menu_spacer1 ; No item text string given - this will be a spacer
  GTMenuItem 0, 0, #menu_project, #menu_about, "About...", "?"
  GTMenuItem 0, 0, #menu_project, #menu_quit, "Quit", "Q"

GTMenuTitle 0, #menu_settings, "Settings"
  GTMenuItem 0, 0, #menu_settings, #menu_size, "Size"
    GTSubItem 0, #CHECKIT|#CHECKED, #menu_settings, #menu_size, #menu_small, "Small", "", %110 ; This item has a checkmark and is mutually exclusive with the other subitem below. It defaults to checked with the #CHECKED flag
    GTSubItem 0, #CHECKIT, #menu_settings, #menu_size, #menu_medium, "Medium", "", %101 ; This item is also a checkmark item but defaults to unchecked.
    GTSubItem 0, #CHECKIT, #menu_settings, #menu_size, #menu_large, "Large", "", %011 ; Third sub-item is another checkmark item but again defaults to unchecked.
  GTMenuItem 0, 0, #menu_settings, #menu_opensettings, "Open Settings...", "P"
  GTMenuItem 0, 0, #menu_settings, #menu_savesettings, "Save Settings", "A"

CreateMenuStrip 0 ; Turns the definitions above into a MenuStrip object

win.l = Window(0, 100, 100, 200, 100, #WFLG_DRAGBAR|#WFLG_DEPTHGADGET|#WFLG_CLOSEGADGET|#WFLG_ACTIVATE|#WFLG_NEWLOOKMENUS, "Test Window", 1, 2) ; Enable New Look menus
If win = False Then NPrint "Unable to open window!":End

GTSetMenu 0 ; Attach MenuStrip 0 to the current window

; Put event handling code here...
GTTestWindowMenu.png

This code will produce menus something like the example screenshot shown here. Note that this screenshot is from OS4, and shows the menu items in pop-up mode rather than in pull-down mode as is the default.