--[[ LibXMenu-1.0.lua Created By: Xruptor A simple DropDown library for creating interactive menus. Example using each available option: local dd1 = LibStub('LibXMenu-1.0'):New("DropDownName", database) dd1.db.color1val = { r = 0, g = 0, b = 0, a = 1, } dd1.initialize = function(self, lvl) if lvl == 1 then self:AddTitle(lvl, "My DropDown") self:AddList(lvl, "Font Size", "fontsize") self:AddList(lvl, "Advance List", "advancelist") self:AddColor(lvl, "Color 1", "color1val") self:AddToggle(lvl, "Switch", "switch") self:AddToggle(lvl, "Switch2", "switch2", otherdb, "otherdboption2") elseif lvl and lvl > 1 then local sub = UIDROPDOWNMENU_MENU_VALUE if sub == "fontsize" then --loop selection add for i = 5, 12, 1 do self:AddSelect(lvl, i, i, "fontsize", nil) end elseif sub == "advancelist" then --several different ways of adding selects self:AddSelect(lvl, "This button 1", "button1", db, "dboption1", nil, 1) self:AddSelect(lvl, "This button 2", "button2", "dboption2", nil, nil, 2) end end end dd1.doUpdate = function(bOpt) --fired after every menu selection click doDisplayUpdates(); if bOpt == 1 then --do something, bOpt is optional tag attached to a button end end ToggleDropDownMenu(1, nil, dd1, "cursor") --]] local MAJOR, MINOR = "LibXMenu-1.0", 5 local lib = LibStub:NewLibrary(MAJOR, MINOR) if not lib then return end --DO NOT MODIFY --Used to prevent checks from displaying on Menulist title options local function HideCheck(item) if item and item.GetName and _G[item:GetName().."Check"] then _G[item:GetName().."Check"]:Hide() end end --[[ lib:AddButton (NOTE:) This function is automatically called by each menu item insertion. You should only use this function if your going to use your own custom button. lvl - menu level 1,2,3 etc... text - name of the menu item keepShownOnClick - (optional) toggle if the menu item should be shown or not on click (true/false) --]] local function AddButton(self, lvl, text, keepshown) if not lvl then return end if not text then return end self.info.text = text self.info.keepShownOnClick = keepshown self.info.owner = self UIDropDownMenu_AddButton(self.info, lvl) wipe(self.info) end --[[ lib:AddToggle lvl - menu level 1,2,3 etc... text - name of the menu item value - element in the database table, used when arg1 and arg2 are both nil. Example: db[value] NOTE: Value of the database element must be a boolean value. TRUE/FALSE. Example: db[value] = true arg1 - custom database variable, if arg2 is nil then value is used as element. Example: arg1[value] arg2 - custom database element for arg1. Example: arg1[arg2] func - override with custom function bOpt - define an optional variable to be passed to doUpdate. Example: button name or button ID. --]] local function AddToggle(self, lvl, text, value, arg1, arg2, func, bOpt) if not lvl then return end if not text then return end if not value then return end value = tonumber(value) or value self.info.arg1 = arg1 self.info.arg2 = arg2 self.info.value = value self.info.func = func or function(item, arg1, arg2) if arg1 and arg2 then arg1[arg2] = not arg1[arg2] elseif arg1 then arg1[item.value] = not arg1[item.value] else item.owner.db[item.value] = not item.owner.db[item.value] end if item.owner.doUpdate then item.owner.doUpdate(bOpt) end end if arg1 and arg2 then self.info.checked = arg1[arg2] elseif arg1 then self.info.checked = arg1[value] else self.info.checked = self.db[value] end AddButton(self, lvl, text, 1) end --[[ lib:AddList lvl - menu level 1,2,3 etc... text - name of the menu item value - menuList value, used in UIDROPDOWNMENU_MENU_VALUE when lvl > 1. --]] local function AddList(self, lvl, text, value, notCheckable) if not lvl then return end if not text then return end if not value then return end self.info.value = value self.info.hasArrow = true self.info.func = HideCheck if notCheckable ~= nil then self.info.notCheckable = notCheckable else self.info.notCheckable = true end self.info.notCheckable = notCheckable or true AddButton(self, lvl, text, 1) end --[[ lib:AddSelect lvl - menu level 1,2,3 etc... text - name of the menu item value - Value in database to compare and store. If arg1 and arg2 then value is stored in the arg1[arg2] table. If arg1 and not arg2 then value is stored in db[arg1] table. arg1 - REQUIRED: database variable, if arg2 then acts as primary database. Example: arg1[arg2] if not arg2 then arg1 is used as an element of the database table. Example: db[arg1] arg2 - custom database variable, if arg1 then acts as an element in arg1 table. Example: arg1[arg2] func - override with custom function bOpt - define an optional variable to be passed to doUpdate. Example: button name or button ID. --]] local function AddSelect(self, lvl, text, value, arg1, arg2, func, bOpt) if not lvl then return end if not text then return end if not value then return end if not arg1 and not arg2 then assert(false, "LibXMenu-1.0: Error, AddSelect() requires arg1") return end value = tonumber(value) or value self.info.arg1 = arg1 self.info.arg2 = arg2 self.info.value = value self.info.func = func or function(item, arg1, arg2) local val = tonumber(item.value) or item.value if arg1 and arg2 then arg1[arg2] = val elseif arg1 then item.owner.db[arg1] = val end local level, num = strmatch(item:GetName(), "DropDownList(%d+)Button(%d+)") level, num = tonumber(level) or 0, tonumber(num) or 0 for i = 1, level, 1 do for j = 1, UIDROPDOWNMENU_MAXBUTTONS, 1 do local check = _G["DropDownList"..i.."Button"..j.."Check"] local iObjChk = _G["DropDownList"..i.."Button"..j] --make sure it's a pair in the same selection field if iObjChk then local passChk = false if iObjChk.arg1 and iObjChk.arg2 then passChk = iObjChk.arg1 == arg1 and iObjChk.arg2 == arg2 elseif iObjChk.arg1 then passChk = iObjChk.arg1 == arg1 end if passChk then if check and i == level and j == num then check:Show() elseif item then check:Hide() end end end end end if item.owner.doUpdate then item.owner.doUpdate(bOpt) end end if arg1 and arg2 then self.info.checked = arg1[arg2] == value elseif arg1 then self.info.checked = self.db[arg1] == value else self.info.checked = false end AddButton(self, lvl, text, 1) end --[[ lib:AddColor (NOTE:) A color table must be first established before using this function lvl - menu level 1,2,3 etc... text - name of the menu item value - database element value or name. Example: db[value] arg1 - (optional) use a secondary database, value is used as key. Example: arg1[value] bOpt - define an optional variable to be passed to doUpdate. Example: button name or button ID. func - override with custom function swatchFunc - override with custom function opacityFunc - override with custom function cancelFunc - override with custom function --]] local function AddColor(self, lvl, text, value, arg1, bOpt, func, swatchFunc, opacityFunc, cancelFunc) if not lvl then return end if not text then return end if not value then return end local db if arg1 then db = arg1[value] else db = self.db[value] end if not db then return end local SetColor = function(item) local colDB = _G[self:GetName()].db[UIDROPDOWNMENU_MENU_VALUE] if not colDB then return end local r, g, b, a if item then local pv = ColorPickerFrame.previousValues r, g, b, a = pv.r, pv.g, pv.b, 1 - pv.opacity else r, g, b = ColorPickerFrame:GetColorRGB() a = 1 - OpacitySliderFrame:GetValue() end colDB.r, colDB.g, colDB.b, colDB.a = r, g, b, a if _G[self:GetName()].doUpdate then _G[self:GetName()].doUpdate(bOpt) end end self.info.hasColorSwatch = true self.info.hasOpacity = 1 self.info.r, self.info.g, self.info.b, self.info.opacity = db.r, db.g, db.b, 1 - db.a self.info.swatchFunc = swatchFunc or SetColor self.info.opacityFunc = opacityFunc or SetColor self.info.cancelFunc = cancelFunc or SetColor self.info.value = value self.info.func = func or UIDropDownMenuButton_OpenColorPicker AddButton(self, lvl, text, nil) end --[[ lib:AddTitle lvl - menu level 1,2,3 etc... text - name of the menu item --]] local function AddTitle(self, lvl, text) if not lvl then return end if not text then return end self.info.isTitle = true self.info.notCheckable = true AddButton(self, lvl, text) end --[[ lib:AddCloseButton lvl - menu level 1,2,3 etc... text - name of the menu item --]] local function AddCloseButton(self, lvl, text) if not lvl then return end if not text then return end self.info.notCheckable = true self.info.func = function() CloseDropDownMenus() end AddButton(self, lvl, text) end --[[ lib:New selfName - name of the dropdown menu db - database for the dropdown menu to use --]] function lib:New(selfName, db) if not selfName then assert(false, "LibXMenu-1.0: Error, DropDown requires a name") return end if not db then assert(false, "LibXMenu-1.0: Error, DropDown requires a Database.") return end --Note: If you don't want to use a database, just use an empty table {}. --Ex. local dd1 = LibStub('LibXMenu-1.0'):New("DropDownName", {}) local dd = CreateFrame("Frame", selfName, UIParent) dd.db = db dd.info = {} dd.displayMode = "MENU" dd.AddButton = AddButton dd.AddToggle = AddToggle dd.AddList = AddList dd.AddSelect = AddSelect dd.AddColor = AddColor dd.AddTitle = AddTitle dd.AddCloseButton = AddCloseButton dd.doUpdate = function() end return dd end