WoW:UI Object UIDropDownMenu: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
m (Move page script moved page UI Object UIDropDownMenu to UI Object UIDropDownMenu without leaving a redirect)
 
(12 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{Stub/API}}
[[Image:UIDropDownMenu-NoMenu.png|thumb|right|A dropdown box created using UIDropDownMenu.]]
This guide will demonstrate how to create dynamic drop down menu frames and point out common traps that you will fall into when modifying these frames during run time
UIDropDownMenu is a [[FrameXML]] Frame template that can be used to create contextual menus and dropdown boxes in World of Warcraft. The relevant API is highlighted on this page.


==Essential Class Methods==
== The menu architecture ==
[[File:UIDropDownMenu-Menu.png|thumb|right|The "MENU" style for context menus.]]
FrameXML provides a Frame template -- '''UIDropDownMenuTemplate''' -- that all menu or dropdown boxes should inherit from. Once a frame inheriting from UIDropDownMenuTemplate has been created, call '''UIDropDownMenu_Initialize''' to bind a menu function to it; the menu function will be responsible for creating the menu entries when the menu is open. The frame is used to store limited menu-related data, as well as a container for the dropdown list box if that menu style is used. Note that most of the usual frame-related methods may not work as expected on the dropdown menus, so additional API is provided to perform functions such as setting the selected entries, text, or adjusting dropdown box appearance.


===Creates a drop down menu frame on the core UI parent window===
The menus themselves are displayed using FrameXML-owned frames. Because of this, menu representations generally do not exist in memory unless the menu is open, and only one menu may be open at a time. The function provided to UIDropDownMenu_Initialize is used to create the required menu's entries when that menu is opened.


; Frame Creation
To implement a dropdown menu or list, one typically needs to create a frame inheriting from UIDropDownMenuTemplate, implement an initialization function to populate the menu when needed, and bind the initialization function to the frame using UIDropDownMenu_Initialize.
: <b>MyDropDownMenu = CreateFrame("Frame", "MyDropDownMenu", UIParent, "UIDropDownMenuTemplate");
: MyDropDownMenu:SetPoint("CENTER",UIParent); --This is the only frame inherited method along with Frame:Show() and Frame:Hide()</b>


----
== General API ==
; UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList) : Initializes a dropdown menu attached to a specific frame.
:; frame : Required - Frame handle the menu will be bound to.
:; initFunction : Required - Function called when the menu is opened, responsible for adding menu buttons. Signature: (frame, level, menuList); additional [[#Global variables|global variables]] are used to communicate menu state.
:; displayMode : Optional - "MENU" to use context-menu style, any other value to create a dropdown list box.
:; level : Optional - 2nd argument to the initialization function when called for the first time.
:; menuList : Optional - 3rd argument to the initialization function; used by {{api|EasyMenu}}.
; UIDropDownMenu_AddButton(info, level) : Add a button to the currently open menu.
:; info : Table describing the button: [[#The info table|key/value pairs listed below]].
:; level : Number specifying nesting level; can typically reuse the level argument to initFunction.
; ToggleDropDownMenu(level, value, dropDownFrame, anchorName, ofsX, ofsY, menuList, button) : Opens or closes a menu; arguments marked as internal are used from within the UIDropDownMenu implementation to open sub-menus etc.
:; level : Internal - level of the opened menu; nil for external calls.
:; value : Internal - parent node value for the sub menu; nil for external calls.
:; dropDownFrame : Both - dropdown menu frame reference (menu handle).
:; anchorName, ofsX, ofsY : Both - Positioning information (anchor and x,y offsets) for context menus.
:; menuList : Internal - EasyMenu wrapper argument, passed as the third argument to the initialization function.
:; button : Internal - Dropdown menu "open" button.
; UIDropDownMenu_EnableDropDown(dropDownFrame) : Enables a dropdown menu that has been disabled.
:; dropDownFrame : Both - dropdown menu frame reference (menu handle).
; UIDropDownMenu_DisableDropDown(dropDownFrame) : Disables a dropdown menu that is currently enabled.
:; dropDownFrame : Both - dropdown menu frame reference (menu handle).


===Basic Drop Down Menu Frame Modifiers===
=== Initialization functions ===
The initFunction supplied to UIDropDownMenu_Initialize is called when the menu (as well as any nested menu levels) should be constructed, as well as as part of the UIDropDownMenu_Initialize call (this allows you to use the selection API to specify a selection immediately after binding the function to a menu frame should you so desire). The function is given three arguments:
; frame : Frame handle to the menu frame.
; level : Number specifying nesting level.
; menuList : An {{api|EasyMenu}} helper argument that can safely be ignored.
Additionally, some [[#Global variables|global variables]] may be useful to determine which entry's nested menu the initializer function is asked to supply.


Futher modifications are made using functions that are bound to a "virtual" drop down menu. You need to supply the actual frame object as an argument to modify a particular drop down menu object as shown below:
It is expected that the initialization function will create any required menu entries using UIDropDownMenu_AddButton when called.


: <b>UIDropDownMenu_SetWidth(80, MyDropDownMenu)</b> --Sets the width of MyDropDownMenu to 80 pixels. When MyDropDownMenu is orignally created, it has a default width. If the default width is not appropriate, then this function is the one for you.
=== The info table ===
Bolded keys are required.
{| class="darktable"
! Key !! Value type !! Description
|-
| '''text''' || String || Button text for this option.
|-
| icon || String || A texture path. The icon is scaled down and displayed to the right of the text.
|-
| value || Any || A value tag for this option.
|-
| func || Function || Function called when this button is clicked. The signature is (self, arg1, arg2, checked)
|-
| arg1, arg2 || Any || Arguments to the custom function assigned in func.
|-
| isTitle || Boolean || True if this is a title (cannot be clicked, special formatting).
|-
| disabled || Boolean || If true, this button is disabled (cannot be clicked, special formatting)
|-
| checked || Boolean || If true, this button is checked (tick icon displayed next to it)
|-
| hasArrow || Boolean || If true, this button has an arrow and opens a nested menu.
|-
| hasColorSwatch || Boolean || If true, this button has an attached color selector.
|-
| r, g, b || Numbers [0.0, 1.0] || Initial color value for the color selector.
|-
| colorCode || String || "<nowiki>|</nowiki>cffrrggbb" sequence that is prepended to info.text only if the button is enabled.
|-
| swatchFunc || Function || Function called when the color is changed.
|-
| hasOpacity || Boolean || If true, opacity can be customized in addition to color.
|-
| opacity || Number [0.0, 1.0] || Initial opacity value (0 = transparent).
|-
| opacityFunc || Function || Function called when opacity is changed.
|-
| cancelFunc || Function || Function called when color/opacity alteration is cancelled.
|-
| notClickable || Boolean || If true, this button cannot be clicked.
|-
| notCheckable || String || If true, this button cannot be checked (selected) - this also moves the button to the left, since there's no space stored for the tick-icon
|-
| keepShownOnClick || Boolean || If true, the menu isn't hidden when this button is clicked.
|-
| tooltipTitle || String || Tooltip title text. The tooltip appears when the player hovers over the button.
|-
| tooltipText || String || Tooltip content text.
|-
| justifyH || String || Horizontal text justification: "LEFT", "CENTER", "RIGHT".
|-
| fontObject || Font || Font object used to render the button's text.
|-
| menuList || Table || Table used to store nested menu descriptions for the {{api|EasyMenu}} functionality.
|}


: <b>UIDropDownMenu_SetButtonWidth(20, MyDropDownMenu)</b> --Changes the drop down menu button with from it's default width to 20 pixels
== Selection functions ==
To use the _SetSelected* functions, your dropdown menu must be the currently open / currently being initialized. Otherwise, the functions will not have the desired effect.
; UIDropDownMenu_SetSelectedName(frame, name, useValue) : Sets selection based on info.text values.
; UIDropDownMenu_SetSelectedValue(frame, value, useValue) : Sets selection based on info.value values.
; UIDropDownMenu_SetSelectedID(frame, id, useValue) : Sets selection based on button appearance order.
; UIDropDownMenu_GetSelectedName(frame) : Returns selected button's text field.
; UIDropDownMenu_GetSelectedID(frame) : Return selected button's ID.
; UIDropDownMenu_GetSelectedValue(frame) : Returns selected button's value field.


----
== Layout functions ==
; UIDropDownMenu_SetWidth(frame, width, padding) : Adjusts dropdown menu width.
; UIDropDownMenu_SetButtonWidth(frame, width) : Adjust the dropdown box button width.
; UIDropDownMenu_SetText(frame, text) : Alters text displayed on the dropdown box.
; UIDropDownMenu_GetText(frame) : Return text displayed on the dropdown box.
; UIDropDownMenu_JustifyText(frame, justification) : Adjusts text justification on the dropdown box.


===Drop Down Menu Item Initialiser===
== Global variables ==
; UIDROPDOWNMENU_OPEN_MENU : Frame handle of the currently open menu.
; UIDROPDOWNMENU_INIT_MENU : Frame handle of the menu currently initializing.
; UIDROPDOWNMENU_MENU_LEVEL : Current menu nesting level.
; UIDROPDOWNMENU_MENU_VALUE : Value of the parent node.
; UIDROPDOWNMENU_SHOW_TIME : Number of seconds to keep the menu visible after the cursor leaves it.


Drop down menues require an initialisation function in order to create menu items. It is important to note that every time the drop down menu button is clicked that the initialise function is executed. When creating drop down menues that have dynamic menu items, this is an important point to consider.
== See Also ==  
 
* [[Using UIDropDownMenu]] -- a tutorial.
: <b>UIDropDownMenu_Initialize(MyDropDownMenu, MyDropDownMenu_Initialise);</b> --The virtual drop down menu will now call the function MyDropDownMenu_Initialize to setup the menu items for MyDropDownMenu
* [[API EasyMenu]] -- table-based UIDropDownMenu interface.
 
[[Category:FrameXML documentation]]
----
 
===Typical Drop Down Menu Initialisation Function===
 
: function MyDropDownMenu_Initialise()
:: level = level or 1 --drop down menues can have sub menues. The value of ''level'' determines the drop down sub menu tier
::
:: local info = UIDropDownMenu_CreateInfo();
::
 
:: info.text = "First Menu Item"; --the text of the menu item
:: info.value = 0; -- the value of the menu item. This can be a string also.
:: info.func = MyDropDownMenuItem_OnClick; --sets the function to execute when this item is clicked
:: info.owner = this:GetParent(); --binds the drop down menu as the parent of the menu item. This is very important for dynamic drop down menues.
:: info.checked = nil; --initially set the menu item to being unchecked with a yellow tick
:: info.icon = nil; --we can use this to set an icon for the drop down menu item to accompany the text
:: UIDropDownMenu_AddButton(info, level); --Adds the new button to the drop down menu specified in the UIDropDownMenu_Initialise function. In this case, it's MyDropDownMenu
::
 
:: info.text = "Second Menu Item";
:: info.value = 1;
:: info.func = MyDropDownMenuItem_OnClick
:: info.owner = this:GetParent();
:: info.checked = nil;
:: info.icon = nil;
:: UIDropDownMenu_AddButton(info, level);
: end
 
The <b>''info''</b> structure is used to determine the attributes of a single menu item. Setting the value of <b>info.value</b> is important as I'll demonstrate next. For now, our MyDropDownMenu is ready to use with two menu items.
 
----
 
===Drop Down Menu Item Clicking===
 
I will now show how to handle an item clicking event. As you can see from the initialisation function defined in <b>info.func</b>, the specified function will be called when that menu item is clicked. You are not restricted to specifying one function for all menu items. It's handy having one function for all items though as you reduce the amount of code in your mod and it is essential for dynamic drop down menues which have changing menu items.
 
When this function is called from clicking the drop down menu item, the scope of the governing object is the individual menu item. You can therefore get information on the specific menu item click (i.e. this.value, this.owner, this.icon etc).
 
: function MyDropDownMenuItem_OnClick()
:: <b>UIDropDownMenu_SetSelectedValue(this.owner, this.value);</b> --this is where the <b>info.value</b> comes in handy. The SetSelectedValue function updates the drop down menu's currently selected item. The function prefers the <b>info.value</b> value instead of the <b>info.text</b> value for setting the selected value. Furthermore, when depending on a selected value of a drop down menu for other sections in your mod, the GetSelectedValue method is more usefull than the GetText method.
::
 
:: if (this.value == 0) then
::: --We clicked the first menu item. Enter code here to affect the rest of your mod.
:: elseif (this.value == 1) then
::: --We clicked the second menu item. Enter code here to affect the rest of your mod.
:: end
: end
 
We are now all setup for using the drop down menu with our mod. Below are some usefull functions for getting information from your new drop down menu.
 
----
 
===Drop Down Menu Functions===
 
: <b>UIDropDownMenu_GetSelectedValue(MyDropDownMenu)</b> --Gets the <b>info.value</b> value of the currently selected item in MyDropDownMenu.
:
: <b>UIDropDownMenu_GetText(MyDropDownMenu)</b> --Gets the <b>info.text</b> value of the currently selected item in MyDropDownMenu.
:
: <b>UIDropDownMenu_ClearAll(MyDropDownMenu)</b> --Resets MyDropDownMenu so it's no longer selecting anything.

Latest revision as of 04:49, 15 August 2023

A dropdown box created using UIDropDownMenu.

UIDropDownMenu is a FrameXML Frame template that can be used to create contextual menus and dropdown boxes in World of Warcraft. The relevant API is highlighted on this page.

The menu architecture[edit]

The "MENU" style for context menus.

FrameXML provides a Frame template -- UIDropDownMenuTemplate -- that all menu or dropdown boxes should inherit from. Once a frame inheriting from UIDropDownMenuTemplate has been created, call UIDropDownMenu_Initialize to bind a menu function to it; the menu function will be responsible for creating the menu entries when the menu is open. The frame is used to store limited menu-related data, as well as a container for the dropdown list box if that menu style is used. Note that most of the usual frame-related methods may not work as expected on the dropdown menus, so additional API is provided to perform functions such as setting the selected entries, text, or adjusting dropdown box appearance.

The menus themselves are displayed using FrameXML-owned frames. Because of this, menu representations generally do not exist in memory unless the menu is open, and only one menu may be open at a time. The function provided to UIDropDownMenu_Initialize is used to create the required menu's entries when that menu is opened.

To implement a dropdown menu or list, one typically needs to create a frame inheriting from UIDropDownMenuTemplate, implement an initialization function to populate the menu when needed, and bind the initialization function to the frame using UIDropDownMenu_Initialize.

General API[edit]

UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList)
Initializes a dropdown menu attached to a specific frame.
frame
Required - Frame handle the menu will be bound to.
initFunction
Required - Function called when the menu is opened, responsible for adding menu buttons. Signature: (frame, level, menuList); additional global variables are used to communicate menu state.
displayMode
Optional - "MENU" to use context-menu style, any other value to create a dropdown list box.
level
Optional - 2nd argument to the initialization function when called for the first time.
menuList
Optional - 3rd argument to the initialization function; used by EasyMenu.
UIDropDownMenu_AddButton(info, level)
Add a button to the currently open menu.
info
Table describing the button: key/value pairs listed below.
level
Number specifying nesting level; can typically reuse the level argument to initFunction.
ToggleDropDownMenu(level, value, dropDownFrame, anchorName, ofsX, ofsY, menuList, button)
Opens or closes a menu; arguments marked as internal are used from within the UIDropDownMenu implementation to open sub-menus etc.
level
Internal - level of the opened menu; nil for external calls.
value
Internal - parent node value for the sub menu; nil for external calls.
dropDownFrame
Both - dropdown menu frame reference (menu handle).
anchorName, ofsX, ofsY
Both - Positioning information (anchor and x,y offsets) for context menus.
menuList
Internal - EasyMenu wrapper argument, passed as the third argument to the initialization function.
button
Internal - Dropdown menu "open" button.
UIDropDownMenu_EnableDropDown(dropDownFrame)
Enables a dropdown menu that has been disabled.
dropDownFrame
Both - dropdown menu frame reference (menu handle).
UIDropDownMenu_DisableDropDown(dropDownFrame)
Disables a dropdown menu that is currently enabled.
dropDownFrame
Both - dropdown menu frame reference (menu handle).

Initialization functions[edit]

The initFunction supplied to UIDropDownMenu_Initialize is called when the menu (as well as any nested menu levels) should be constructed, as well as as part of the UIDropDownMenu_Initialize call (this allows you to use the selection API to specify a selection immediately after binding the function to a menu frame should you so desire). The function is given three arguments:

frame
Frame handle to the menu frame.
level
Number specifying nesting level.
menuList
An EasyMenu helper argument that can safely be ignored.

Additionally, some global variables may be useful to determine which entry's nested menu the initializer function is asked to supply.

It is expected that the initialization function will create any required menu entries using UIDropDownMenu_AddButton when called.

The info table[edit]

Bolded keys are required.

Key Value type Description
text String Button text for this option.
icon String A texture path. The icon is scaled down and displayed to the right of the text.
value Any A value tag for this option.
func Function Function called when this button is clicked. The signature is (self, arg1, arg2, checked)
arg1, arg2 Any Arguments to the custom function assigned in func.
isTitle Boolean True if this is a title (cannot be clicked, special formatting).
disabled Boolean If true, this button is disabled (cannot be clicked, special formatting)
checked Boolean If true, this button is checked (tick icon displayed next to it)
hasArrow Boolean If true, this button has an arrow and opens a nested menu.
hasColorSwatch Boolean If true, this button has an attached color selector.
r, g, b Numbers [0.0, 1.0] Initial color value for the color selector.
colorCode String "|cffrrggbb" sequence that is prepended to info.text only if the button is enabled.
swatchFunc Function Function called when the color is changed.
hasOpacity Boolean If true, opacity can be customized in addition to color.
opacity Number [0.0, 1.0] Initial opacity value (0 = transparent).
opacityFunc Function Function called when opacity is changed.
cancelFunc Function Function called when color/opacity alteration is cancelled.
notClickable Boolean If true, this button cannot be clicked.
notCheckable String If true, this button cannot be checked (selected) - this also moves the button to the left, since there's no space stored for the tick-icon
keepShownOnClick Boolean If true, the menu isn't hidden when this button is clicked.
tooltipTitle String Tooltip title text. The tooltip appears when the player hovers over the button.
tooltipText String Tooltip content text.
justifyH String Horizontal text justification: "LEFT", "CENTER", "RIGHT".
fontObject Font Font object used to render the button's text.
menuList Table Table used to store nested menu descriptions for the EasyMenu functionality.

Selection functions[edit]

To use the _SetSelected* functions, your dropdown menu must be the currently open / currently being initialized. Otherwise, the functions will not have the desired effect.

UIDropDownMenu_SetSelectedName(frame, name, useValue)
Sets selection based on info.text values.
UIDropDownMenu_SetSelectedValue(frame, value, useValue)
Sets selection based on info.value values.
UIDropDownMenu_SetSelectedID(frame, id, useValue)
Sets selection based on button appearance order.
UIDropDownMenu_GetSelectedName(frame)
Returns selected button's text field.
UIDropDownMenu_GetSelectedID(frame)
Return selected button's ID.
UIDropDownMenu_GetSelectedValue(frame)
Returns selected button's value field.

Layout functions[edit]

UIDropDownMenu_SetWidth(frame, width, padding)
Adjusts dropdown menu width.
UIDropDownMenu_SetButtonWidth(frame, width)
Adjust the dropdown box button width.
UIDropDownMenu_SetText(frame, text)
Alters text displayed on the dropdown box.
UIDropDownMenu_GetText(frame)
Return text displayed on the dropdown box.
UIDropDownMenu_JustifyText(frame, justification)
Adjusts text justification on the dropdown box.

Global variables[edit]

UIDROPDOWNMENU_OPEN_MENU
Frame handle of the currently open menu.
UIDROPDOWNMENU_INIT_MENU
Frame handle of the menu currently initializing.
UIDROPDOWNMENU_MENU_LEVEL
Current menu nesting level.
UIDROPDOWNMENU_MENU_VALUE
Value of the parent node.
UIDROPDOWNMENU_SHOW_TIME
Number of seconds to keep the menu visible after the cursor leaves it.

See Also[edit]