WoW:USEROBJECT MenuClass: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
m (New page: {{userfunc}} <!-- Leave this line in! --> Create a drop down menu at your leisure and show it when you're ready. == Usage == <pre>local menu = MenuClass:New() menu:AddItem('Do Something',...)
 
mNo edit summary
Line 1: Line 1:
{{userfunc}} <!-- Leave this line in! -->
{{usermodule|MenuClass}}
Create a drop down menu at your leisure and show it when you're ready. This is a very basic context menu, nothing advanced.
Create a drop down menu at your leisure and show it when you're ready. This is a very basic context menu, nothing advanced.


Line 17: Line 17:


== Properties ==
== Properties ==
;.menuItems : Table. Stores the menu items.
;.menuItems
;.anchor : String. The anchor.
: Table. Stores the menu items.
;.x : The x offset
;.anchor
;.y : The y offset
: String. The anchor.
;.displayMode : The display mode.
;.x
;.autoHideDelay : The time it takes for the menu to automatically hide.
: The x offset
;.menuFrame : The menu frame.
;.y
;.uniqueID : A self incrementing number used to ensure that the generic menu frame is unique.
: The y offset
;.isTitle : Is this menu item a header? 1 if yes, nil if no.
;.displayMode
: The display mode.
;.autoHideDelay
: The time it takes for the menu to automatically hide.
;.menuFrame
: The menu frame.
;.uniqueID
: A self incrementing number used to ensure that the generic menu frame is unique.
;.isTitle
: Is this menu item a header? 1 if yes, nil if no.


== Methods ==
== Methods ==
;&#58;Activate() : Creates the menu frame if it has not already been set with :SetMenuFrame().
;&#58;Activate()
;&#58;AddItem(<string> text, <function> func, <number> isTitle) : Add a menu item with ''text'' text that does ''func''. Requires at least 1.
: Creates the menu frame if it has not already been set with :SetMenuFrame().
;&#58;GetAttribute(<string|number> text, <string|number> attribute) : Gets an attribute for the given menu item.
;&#58;AddItem(<string> text, <function> func, <number> isTitle)
;&#58;New() : Allocate memory for the new menu and set the defaults. Required. Returns the menu.
: Add a menu item with ''text'' text that does ''func''. Requires at least 1.
;&#58;RemoveItem(<string> text) : Remove the first menu item that matches ''text''
;&#58;GetAttribute(<string|number> text, <string|number> attribute)
;&#58;SetAnchor(<string> anchor) : Set the ''anchor''. Optional. Default: "cursor"
: Gets an attribute for the given menu item.
;&#58;SetAttribute(<string|number> text, <string|number> attribute, <string|number> value) : Sets an attribute for the given menu item.
;&#58;New()
;&#58;SetDisplayMode(<string> displayMode) : Set the ''displayMode''. Optional. Default: "MENU"
: Allocate memory for the new menu and set the defaults. Required. Returns the menu.
;&#58;SetAutoHideDelay(<number> autoHideDelay) : Set the ''autoHideDelay''. Optional. Default: nil (does not auto close)
;&#58;RemoveItem(<string> text)
;&#58;SetMenuFrame(<menuFrame> menuFrame) : Set the ''menuFrame''. Optional. Default: self generating menuFrame. If set, this must be a frame that inherits '''UIDropDownMenuTemplate'''.
: Remove the first menu item that matches ''text''
;&#58;SetX(<number> x[, <boolean> save]) : Set the ''x'' offset. Optional. Default: nil (0 if ''anchor'' is not "cursor"). If save resolves to true, ''x'' will be added to rather than replaced.
;&#58;SetAnchor(<string> anchor)
;&#58;SetY(<number> y[, <boolean> save]) : Set the ''y'' offset. Optional. Default: nil (0 if ''anchor'' is not "cursor"). If save resolves to true, ''y'' will be added to rather than replaced.
: Set the ''anchor''. Optional. Default: "cursor"
;&#58;Show() : Show the menu.
;&#58;SetAttribute(<string|number> text, <string|number> attribute, <string|number> value)
: Sets an attribute for the given menu item.
;&#58;SetDisplayMode(<string> displayMode)
: Set the ''displayMode''. Optional. Default: "MENU"
;&#58;SetAutoHideDelay(<number> autoHideDelay)
: Set the ''autoHideDelay''. Optional. Default: nil (does not auto close)
;&#58;SetMenuFrame(<menuFrame> menuFrame)
: Set the ''menuFrame''. Optional. Default: self generating menuFrame. If set, this must be a frame that inherits '''UIDropDownMenuTemplate'''.
;&#58;SetX(<number> x[, <boolean> save])
: Set the ''x'' offset. Optional. Default: nil (0 if ''anchor'' is not "cursor"). If save resolves to true, ''x'' will be added to rather than replaced.
;&#58;SetY(<number> y[, <boolean> save])
: Set the ''y'' offset. Optional. Default: nil (0 if ''anchor'' is not "cursor"). If save resolves to true, ''y'' will be added to rather than replaced.
;&#58;Show()
: Show the menu.


== Code ==
== Code ==

Revision as of 17:03, 21 September 2013

This page documents a <i>user-defined modules</i> that into your own AddOns.

User defined modules < MenuClass

Create a drop down menu at your leisure and show it when you're ready. This is a very basic context menu, nothing advanced.

Usage

local menu = MenuClass:New()
menu:AddItem('Do Something', function()
    SendChatMessage("Hello Bob!", "WHISPER", "Common", "Bob")
end)
menu:AddItem('Close', function()
    -- do nothing, just close.
end)

local f = SomeClickableFrame
f:SetScript('OnClick', function(self, button)
    menu:Show()
end)

Properties

.menuItems
Table. Stores the menu items.
.anchor
String. The anchor.
.x
The x offset
.y
The y offset
.displayMode
The display mode.
.autoHideDelay
The time it takes for the menu to automatically hide.
.menuFrame
The menu frame.
.uniqueID
A self incrementing number used to ensure that the generic menu frame is unique.
.isTitle
Is this menu item a header? 1 if yes, nil if no.

Methods

:Activate()
Creates the menu frame if it has not already been set with :SetMenuFrame().
:AddItem(<string> text, <function> func, <number> isTitle)
Add a menu item with text text that does func. Requires at least 1.
:GetAttribute(<string|number> text, <string|number> attribute)
Gets an attribute for the given menu item.
:New()
Allocate memory for the new menu and set the defaults. Required. Returns the menu.
:RemoveItem(<string> text)
Remove the first menu item that matches text
:SetAnchor(<string> anchor)
Set the anchor. Optional. Default: "cursor"
:SetAttribute(<string|number> text, <string|number> attribute, <string|number> value)
Sets an attribute for the given menu item.
:SetDisplayMode(<string> displayMode)
Set the displayMode. Optional. Default: "MENU"
:SetAutoHideDelay(<number> autoHideDelay)
Set the autoHideDelay. Optional. Default: nil (does not auto close)
:SetMenuFrame(<menuFrame> menuFrame)
Set the menuFrame. Optional. Default: self generating menuFrame. If set, this must be a frame that inherits UIDropDownMenuTemplate.
:SetX(<number> x[, <boolean> save])
Set the x offset. Optional. Default: nil (0 if anchor is not "cursor"). If save resolves to true, x will be added to rather than replaced.
:SetY(<number> y[, <boolean> save])
Set the y offset. Optional. Default: nil (0 if anchor is not "cursor"). If save resolves to true, y will be added to rather than replaced.
:Show()
Show the menu.

Code

-- Set to false to use file-scoped variables or true to use the new addon-scoped variables
local useAddonScope = true
local addonName, MenuClass

if useAddonScope then
    addonName, MenuClass = ...
else
    addonName, MenuClass = "--your addon's name--", {}
end

function MenuClass:New()
    local ret = {}
    
    -- set the defaults
    ret.menuList = {}
    ret.anchor = 'cursor'; -- default at the cursor
    ret.x = nil;
    ret.y = nil;
    ret.displayMode = 'MENU'; -- default
    ret.autoHideDelay = nil;
    ret.menuFrame = nil; -- If not defined, :Show() will create a generic menu frame
    ret.uniqueID = 1

    -- import the functions
    for k,v in pairs(self) do
        ret[k] = v
    end
    
    -- return a copy of the class
    return ret
end

--[[
    Return the index where "text" lives.
    ; text : The text to search for.
--]]
function MenuClass:GetItemByText(text)
    for k,v in pairs(self.menuList) do
        if v.text == text then
            return k
        end
    end
end

--[[
    Add menu items
    ; text : The display text.
    ; func : The function to execute OnClick.
    ; isTitle : 1 if this is a header (usually the first one)
    returns the last index of the menu item that was just added.
--]]
function MenuClass:AddItem(text, func, isTitle)
    local info = {}
    
    info["text"] = text
    info["isTitle"] = isTitle    
    info["func"] = func

    table.insert(self.menuList, info)
    return #self.menuList
end

--[[
    Set an attribute for the menu item.
    Valid attributes are found in the FrameXML\UIDropDownMenu.lua file with their valid values.
    Arbitrary non-official attributes are allowed, but are only useful if you plan to access them with :GetAttribute().
    ; text : The text of the menu item or index of the menu item.
    ; attribute : Set this attribute to "value".
    ; value : The value to set the attribute to.
--]]
function MenuClass:SetAttribute(text, attribute, value)
    self.menuList[self:GetItemByText(text) or (self.menuList[text] and text) or 1][attribute or "uniqueID"] = value
end

--[[
    Get an attribute for the menu item.
    Valid attributes are found in the FrameXML\UIDropDownMenu.lua file with their valid values or any arbitrary attribute set with :SetAttribute().
    ; text : The text of the menu item or index of the menu item.
    ; attribute : Get this attribute.
--]]
function MenuClass:GetAttribute(text, attribute)
    return self.menuList[self:GetItemByText(text) or (self.menuList[text] and text) or 1][attribute or "uniqueID"]
end

--[[
    Remove the first item matching "text"
    ; text : The text to search for.
--]]
function MenuClass:RemoveItem(text)
    table.remove(self.menuList, self:GetItemByText(text))
end

--[[
    ; anchor : Set the anchor point. 
--]]
function MenuClass:SetAnchor(anchor)
    if anchor ~= 'cursor' then
        self.x = 0
        self.y = 0
    end
    self.anchor = anchor
end

--[[
    ; displayMode : "MENU"
--]]
function MenuClass:SetDisplayMode(displayMode)
    self.displayMode = displayMode
end

--[[
    ; autoHideDelay : How long, without a click, before the menu goes away.
--]]
function MenuClass:SetAutoHideDelay(autoHideDelay)
    self.autoHideDelay = tonumber(autoHideDelay)
end

--[[
    ; menuFrame : Should inherit a Drop Down Menu template.
--]]
function MenuClass:SetMenuFrame(menuFrame)
    self.menuFrame = menuFrame
end

function MenuClass:GetMenuList()
    return self.menuList
end

--[[
    ; x : X position
    ; save : When not nil, will add to the current value rather than replace it
--]]
function MenuClass:SetX(x, save)
    if save then
        self.x = self.x + x
    else
        self.x = x
    end
end

--[[
    ; y : Y position
    ; save : When not nil, will add to the current value rather than replace it
--]]
function MenuClass:SetY(y, save)
    if save then
        self.y = self.y + y
    else
        self.y = y
    end
end

function MenuClass:Activate()
    if not self.menuFrame then
        while _G['GenericMenuClassFrame'..self.uniqueID] do -- ensure that there's no namespace collisions
            self.uniqueID = self.uniqueID + 1
        end
        -- the frame must be named for some reason
        self.menuFrame = CreateFrame('Frame', 'GenericMenuClassFrame'..self.uniqueID, UIParent, "UIDropDownMenuTemplate")
    end
    self.menuFrame.menuList = self.menuList
end

--[[
    Show the menu.
--]]
function MenuClass:Show()
    self:Activate()
    EasyMenu(self.menuList, self.menuFrame, self.anchor, self.x, self.y, self.displayMode, self.autoHideDelay)
end

-- If you're not using the addon-scoped variables, you must have a global variable in order to use this menu.
if not useAddonScope then
    _G[addonName.."Menu"] = MenuClass
end