Menu resources
Using menu resource file is fast and easy way to construct menu layout which can be attached to window as a menu bar, or it can be attached to widget as well. Engine's menu_*() functions can be used to manipulate some of the menu parameters at runtime after the menu is created as defined in resource file.
Menu resource file compiles to C, and is further compiled and linked as static part of the application. Provided menu resource compiler is written in perl, which handles resource syntax explained below. When resource file is compiled, the resulting file menu_defs.h is produced. Compatible file can be ofcourse produced by some other mechanism if provided compiler or source syntax feels discomfortable.
Menu resource compiler expects input file to be UTF-8 encoded, and supports include-directive, so resource file can be divided into several files:
include "the_other_menu_file.m2c"
menu_*() functions can be used to manipulate some of the menu parameters at runtime.
Layout
Menu resource layout is made of structured keywords, like window and widget to attach the menu either to window or widget, respectively, and menu keyword which defines the actual content of the drop down menu.
Menu resource layout is defined as follows:
; ; Menu is attached to window where WIDGET_STACK_ID was set to 1. ; ; container_type "container_id" { ; window "1" { ; ; menu "menu_name" { optional_icon ; _________ _____________ ; menu "My menu" { my_menu_icon.tga ; ; type "title", item_id, callback, flags, optional_icon ; ____ _____ _______ ________ _____ _____________ ; item "Item one", 1, my_cb_1, none, item_one.tga item "Item two", 2, my_cb_2 menu "My submenu" { item "Item three", 3, my_cb_3 delim radio "Radio A", 10, my_cb_radio, checked radio "Radio B", 10, my_cb_radio radio "Radio C", 10, my_cb_radio } } }
When menu it attached to window, container id must be the WIDGET_STACK_ID which is passed to window_open() function when window is created in Ano script.
Menu
Menu is the box where all the selectable and other items are listed from top to bottom. Menu box itself is wrapped by its parent container, window or widget. Menu box is defined as follows:
menu "menu_name" { optional_icon ; menu items comes here }
Menu name is the string that appears in menu bar, and when clicked, opens the actual menu. Menu name is mandatory component. If optional icon is defined, it will appear left side of the name string. Leave empty if there is no need for an icon. Submenu does not support icon and if defined, it will not be displayed. Supported file formats for icons are BMP and TGA, unpacked true color, alpha channel recommended for transparency. If icon name starts with @, it is substituted with application installation prefix, so if icon is /where/ever/app/is/installed/share/icons/somemenu.tga, that can be written to layout table as @/share/icons/somemenu.tga. Using this trick is recommended, because paths will work even if installation prefix changes.
Menu item
Menu item components from left to right are explained below (see example layout above). Each component is separated with whitespace.
Possible menu item types are:
- item, ordinary selectable menu item
- check, selectable item with toggleable check mark
- radio, radio group with mutually exclusive check mark
- title, unselectable item with text label
- delim, unselectable horizontal line between two menu items
- space, small gap between two menu items
Menu name is the string that appears in the menu item container, and when it is clicked, menu item callback function is called. This component is mandatory.
Item id is custom number to pass to callback function when item was selected. Handy, if you want to use same callback for several menu items. Radio group must use same id number for every item in the group. This component is mandatory.
Menu item callback function is defined in Ano script, and will be called when item was selected. Callback function must have four parameters defined, each explained below:
; ; Callback function parameters: ; ; item contains item name as defined in menu resource file ; position contains item position in menu stack ; tag contains item id number specified in menu resource file ; flag contains togglable item state, on or off, 1 or 0, ; respectively, or item order number in radio group, ; counting from zero ; ; Example menu item callback function ; callback my_cb_1 (_item, _position, _tag, _flag) { dump _item dump _position dump _tag dump _flag }
Menu item flags defines some special flags for the item. Several flags can be specified for one item by separating them with pipe (|). Possible menu item flags are:
- disabled, menu is initially disabled and cannot be selected until enabled
- checked, menu is initially checked if item type is radio or checkable item
If icon is defined, it appears on left side of the menu item text. Leave out or use none if there is no need for an icon. Item type of item, check and radio supports icons attached to them. Supported file formats for icons are BMP and TGA, unpacked true color, alpha channel recommended for transparency. If this strings starts with @, it is substituted with application installation prefix, so if icon is /where/ever/app/is/installed/share/icons/someitem.tga, that can be written to layout table as @/share/icons/someitem.tga. Using this trick is recommended, because paths will work even if installation prefix changes.
Widgets
Attaching menu to widget is just about same than attaching menu to window, except we need another container within window which identifies the widget where the menu is to be attached. Widget identifier must be its name, as defined in widget resource file, by widget name attribute. In following example, menu is attached to block widget my_menu_launcher. Widget needs buttonpress callback defined for menu popup to work. Buttonpress callback function does not have to do anything, it just needs to be there, as menu system takes use of that callback to hook the menu popup.
Menu pops up by pressing middle mouse button on top of container widget, or alternatively keep <ctrl> key pressed while pressing left mouse button.
Example
; ; Menu is attached to block widget my_menu_launcher. ; ; container_type "container_id" { ; window "1" { widget "my_menu_launcher" { ; ; menu "menu_name" { optional_icon ; _________ _____________ ; menu "My menu" { my_menu_icon.tga ; ; type "title", item_id, callback, flags, optional_icon ; ____ _____ _______ ________ _____ _____________ ; item "Item one", 1, my_cb_1, none, item_one.tga item "Item two", 2, my_cb_2 menu "My submenu" { item "Item three", 3, my_cb_3 delim radio "Radio A", 10, my_cb_radio, checked radio "Radio B", 10, my_cb_radio radio "Radio C", 10, my_cb_radio } } } }
This is the widget definition for popup menu above:
window "1" { set "0" { widget "block" { name "my_menu_launcher" state enable position x = 0, y = 0 size width = 200, height = 40 color "rgba:#ffffddff" border color = rgba:#5aa6bbff, thickness = 2 ; This empty callback is needed for menu to pop up action buttonpress = cb_button_press } } }
Empty callback function cb_button_press is defined in Ano script. This is needed as menu system uses the buttonpress callback function to hook the menu in it:
callback cb_button_press (_x, _y, _x_root, _y_root, _state, _button) { }
Copyright © 2024, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.