.\" Copyright (c) 2005-2007 Hypertriton, Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED .\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES .\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR .\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING .\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" .Dd May 30, 2005 .Dt AG_MENU 3 .Os .ds vT Agar API Reference .ds oS Agar 1.0 .Sh NAME .Nm AG_Menu .Nd agar menu widget .Sh SYNOPSIS .Bd -literal #include #include .Ed .Sh DESCRIPTION The .Nm widget implements a hierarchical menu system which supports text-based menu and toolbar displays. Individual menu items can bind to boolean values and specific bits in integer values. .Sh INHERITANCE HIERARCHY .Xr AG_Object 3 -> .Xr AG_Widget 3 -> .Nm . .Sh INITIALIZATION .nr nS 1 .Ft "AG_Menu *" .Fn AG_MenuNew "AG_Widget *parent" "Uint flags" .Pp .Ft "AG_Menu *" .Fn AG_MenuNewGlobal "Uint flags" .Pp .Ft void .Fn AG_MenuExpand "AG_Menu *menu" "AG_MenuItem *item" "int x" "int y" .Pp .Ft void .Fn AG_MenuCollapse "AG_Menu *menu" "AG_MenuItem *item" .Pp .Ft void .Fn AG_MenuSetPadding "AG_Menu *menu" "int left" "int right" "int top" "int bottom" .Pp .Ft void .Fn AG_MenuSetLabelPadding "AG_Menu *menu" "int left" "int right" "int top" "int bottom" .Pp .nr nS 0 The .Fn AG_MenuNew function allocates, initializes, and attaches a new .Nm widget. The .Fn AG_MenuNewGlobal variant creates a global application menu. .Pp The .Fn AG_MenuExpand function creates a new (frameless) window at the coordinates .Fa x , .Fa y . The window contains an .Ft AGMenuView widget which shows the child entries of .Fa item . If an item is clicked on, the window is automatically destroyed. The .Fn AG_MenuCollapse function manually destroys the popup window. .Pp .Fn AG_MenuSetPadding sets the global padding around all menu items, in pixels. .Fn AG_MenuSetLabelPadding sets the padding around the text label of items. If a parameter is -1, its current value is preserved. .Sh MENU ITEMS .nr nS 1 .Ft "AG_MenuItem *" .Fn AG_MenuNode "AG_MenuItem *parent" "const char *text" "AG_Surface *icon" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuAction "AG_MenuItem *parent" "const char *text" "AG_Surface *icon" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "AG_MenuItem *" .Fn AG_MenuActionKb "AG_MenuItem *parent" "const char *text" "AG_Surface *icon" "SDLKey keysym" "SDLMod keymod" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "AG_MenuItem *" .Fn AG_MenuDynamicItem "AG_MenuItem *parent" "const char *text" "AG_Surface *icon" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "AG_MenuItem *" .Fn AG_MenuDynamicItemKb "AG_MenuItem *parent" "const char *text" "AG_Surface *icon" "SDLKey key" "SDLMod kmod" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "AG_MenuItem *" .Fn AG_MenuTool "AG_MenuItem *parent" "AG_Toolbar *toolbar" "const char *text" "AG_Surface *icon" "SDLKey keysym" "SDLMod keymod" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "void" .Fn AG_MenuSetIcon "AG_MenuItem *item" "AG_Surface *su" .Pp .Ft "void" .Fn AG_MenuSetLabel "AG_MenuItem *item" "const char *label" .Pp .Ft "void" .Fn AG_MenuSetPollFn "AG_MenuItem *item" "void (*fn)(AG_Event *)" "const char *fmt, ..." .Pp .Ft "void" .Fn AG_MenuItemFree "AG_MenuItem *menu" .Pp .Ft "void" .Fn AG_MenuState "AG_MenuItem *item" "int state" .Pp .Ft "void" .Fn AG_MenuEnable "AG_MenuItem *item" .Pp .Ft "void" .Fn AG_MenuDisable "AG_MenuItem *item" .Pp .nr nS 0 The .Fn AG_MenuNode function inserts a new node (no-op) item displaying the given .Fa text and .Fa icon (or NULL if none). Node items are typically only used to attach subitems. .Pp The .Fn AG_MenuAction function inserts a new action item displaying the given .Fa text and .Fa icon (or NULL if none). When selected, the item will invoke the event handler function .Fa fn , with the additional arguments specified in .Fa fmt (unless it is NULL). .Pp The .Fn AG_MenuActionKb variant also associates the action with the given .Xr SDLKey 3 and modifier. .Pp The .Fn AG_MenuTool variant automatically inserts an item into the given toolbar as well. .Pp The .Fn AG_MenuDynamicItem function creates a dynamic menu item. The specified callback routine .Fa fn will be invoked repeatedly to update the menu item (see .Xr AG_Event 3 for details), with the .Nm itself passed as .Xr AG_SELF 3 . A pointer to the .Ft AG_MenuItem can be retrieved using .Xr AG_SENDER 3 . The callback routine is allowed to directly modify the .Va state member of the .Ft AG_MenuItem . This variable defines the boolean state for the specified menu item (0 = disabled, 1 = enabled). If .Va state is -1, the boolean state is determined from any boolean/flag binding associated with the item. The callback can also change the text label and icon using .Fn AG_MenuSetLabel and .Fn AG_MenuSetIcon . The .Fn AG_MenuSetPollFn routine sets the callback function associated with a given item. .Pp The .Fn AG_MenuItemFree function destroys the given menu item as well as its children. .Pp The .Fn AG_MenuState (or its variants .Fn AG_MenuEnable and .Fn AG_MenuDisable ) request that all subsequently created menu items are assigned the given state. .Sh BOOLEAN AND BITMASK ITEMS .nr nS 1 .Ft "AG_MenuItem *" .Fn AG_MenuBool "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuBoolMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuIntBool "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuIntBoolMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt8Bool "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint8 *value" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt8BoolMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint8 *value" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuFlags "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int flags" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuFlagsMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int flags" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuIntFlags "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int flags" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuIntFlagsMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "int *value" "int flags" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt8Flags "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint8 *value" "Uint8 flags" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt8FlagsMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint8 *value" "Uint8 flags" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt16Flags "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint16 *value" "Uint16 flags" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt16FlagsMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint16 *value" "Uint16 flags" "int invert" "AG_Mutex *mutex" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuInt32Flags "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint32 *value" "Uint32 flags" "int invert" .Pp .Ft "AG_MenuItem *" .Fn AG_MenuIntFlagsMp "AG_MenuItem *" "const char *text" "AG_Surface *icon" "Uint32 *value" "Uint32 flags" "int invert" "AG_Mutex *mutex" .Pp .nr nS 0 The .Fn AG_Menu*Bool functions create a new item that binds to the given boolean variable. If the .Fa invert parameter is non-zero, the actual value is inverted. .Pp The .Fn AG_Menu*Flags functions create a new item controlling one or more bits inside an integer value. The .Fa flags argument specifies the bitmask. If .Fa invert is non-zero, the bits are inverted. .Pp The .Fn AG_Menu*BoolMp and .Fn AG_Menu*FlagsMp variants accept a .Ft "AG_Mutex *" argument specifying a mutex to acquire prior to reading or writing the data. .Sh OTHER ITEMS .nr nS 1 .Ft "void" .Fn AG_MenuSeparator "AG_MenuItem *item" .Pp .Ft "void" .Fn AG_MenuSection "AG_MenuItem *item" "const char *text" "..." .Pp .nr nS 0 The .Fn AG_MenuSeparator function inserts a horizontal menu separator. .Pp .Fn AG_MenuSection creates a non-selectable item displaying the given text. .Sh POPUP MENUS .nr nS 1 .Ft "AG_PopupMenu *" .Fn AG_PopupNew "AG_Widget *widget" .Pp .Ft void .Fn AG_PopupShow "AG_PopupMenu *pm" .Pp .Ft void .Fn AG_PopupShowAt "AG_PopupMenu *pm" "int x" "int y" .Pp .Ft void .Fn AG_PopupHide "AG_PopupMenu *pm" .Pp .Ft void .Fn AG_PopupDestroy "AG_Widget *widget" "AG_PopupMenu *pm" .Pp .nr nS 0 The .Fn AG_PopupNew function creates a new popup menu and associates it with the specified widget. This association will cause the popup menu to be automatically freed when the given widget is destroyed. .Pp Once a popup menu is created, new items can be inserted using the .Va item member of the .Ft AG_PopupMenu structure as parent. .Pp .Fn AG_PopupShow displays the popup menu at the current mouse cursor coordinates. .Fn AG_PopupShowAt displays the popup menu at the specified display coordinates. .Fn AG_PopupHide hides the popup menu from the user. .Pp .Fn AG_PopupDestroy detaches the specified popup menu from its associated widget, and releases its allocated resources. This function is automatically invoked whenever a widget is destroyed. .Sh EVENTS The .Nm widget reacts to the following events: .Pp .Bl -tag -compact -width "window-mousebutton* " .It window-mousebutton* If the cursor is over a menu item, display its sub-items. .It window-mousemotion Change the current sub-item display if the cursor is moved to a different item. .El .Pp The .Nm widget does not generate any event. .Sh BINDINGS The .Nm widget does not provide any binding. .Sh STRUCTURE DATA For the .Ft AG_Menu object: .Pp .Bl -tag -width "AG_MenuItem *itemSel " .It Ft AG_MenuItem *root The root menu item (read-only). .It Ft AG_MenuItem *itemSel The currently selected top-level item (read-only). Top-level items are attached directly to .Va root . .It Ft int selecting Selection is in progress if set to 1 (read-only). .El .Pp For the .Ft AG_MenuItem structure: .Pp .Bl -tag -width "AG_MenuItem *subitems " .It Ft char *text Displayed text for the menu item (read-only, set by .Fn AG_MenuSetLabel ) . .It Ft AG_Surface *iconSrc The .Xr AG_Surface 3 of the menu icon, or NULL (read-only, set by .Fn AG_MenuSetIcon ) . .It Ft int value The boolean state of the item, used by default. If the boolean state was bound to another variable (e.g., using .Fn AG_MenuBool or .Fn AG_MenuSetIntBool ) , this value is ignored. .It Ft int state If this flag is set (the default), the item is "enabled". Otherwise, the user is not allowed to select the item. .It Ft AG_Menu *pmenu Back pointer to the parent .Ft AG_Menu (read-only). .El .Sh EXAMPLES The following code fragment associates a menu with an .Xr AG_Toolbar 3 . Buttons and menu entries are created for the same actions. .Pp .Bd -literal -offset indent AG_Toolbar *toolbar; AG_Menu *menu; AG_MenuItem *item; toolbar = AG_ToolbarNew(win, AG_TOOLBAR_HORIZ, 1, 0); menu = AG_MenuNew(win, 0); item = AG_MenuAddItem(menu, "File"); { AG_MenuToolbar(item, toolbar); AG_MenuAction(item, "Load", NULL, LoadFile, NULL); AG_MenuAction(item, "Save", NULL, SaveFile, NULL); AG_MenuToolbar(item, NULL); } .Ed .Pp The following code fragment creates a menu with an action item, a boolean item and two bitmask items. .Pp .Bd -literal -offset indent Uint16 flags = 0; #define FOO_FLAG 0x01 #define BAR_FLAG 0x02 void SayHello(AG_Event *event) { char *s = AG_STRING(1); AG_TextMsg(AG_MSG_INFO, "Hello, %s!", s); } void QuitApplication(AG_Event *event) { AG_Quit(); } .Li ... AG_Menu *menu = AG_MenuNew(win); AG_MenuItem *item = AG_MenuAddItem(menu, "File"); { AG_MenuInt16Flags(item, "Foo", NULL, &flags, FOO_FLAG, 0); AG_MenuInt16Flags(item, "Bar", NULL, &flags, BAR_FLAG, 0); AG_MenuAction(item, "Say hello", NULL, SayHello, "%s", "world"); AG_MenuAction(item, "Quit", NULL, QuitApplication, NULL); } .Ed .Sh SEE ALSO .Xr AG_Intro 3 , .Xr AG_Event 3 , .Xr AG_Button 3 , .Xr AG_Surface 3 , .Xr AG_Toolbar 3 , .Xr AG_Tlist 3 , .Xr AG_Widget 3 , .Xr AG_Window 3 .Sh HISTORY The .Nm widget first appeared in Agar 1.0.