Mercurial > wow > reaction
view modules/ConfigUI.lua @ 157:e77f716af1b7
Pushed state rule logic from State.lua to Bar.lua
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 12 Jun 2009 21:44:44 +0000 |
parents | f823f2a5dcb1 |
children | 8cc187143acd |
line wrap: on
line source
--[[ ReAction Configuration UI module Hooks into Blizzard Interface Options AddOns panel --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local AceConfigReg = LibStub("AceConfigRegistry-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") ReAction:UpdateRevision("$Revision$") -- some constants local configName = "ReAction" -- module declaration local moduleID = "ConfigUI" local module = ReAction:NewModule( moduleID, "AceEvent-3.0" ) -- module methods function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID, { profile = { closeOnLaunch = true, editorCloseOnLaunch = true, } } ) self:RegisterEvent("PLAYER_REGEN_DISABLED") ReAction.RegisterCallback(self,"OnOptionsRegistered","OnOptionsRefreshed") ReAction.RegisterCallback(self,"OnOptionsRefreshed") self:InitializeOptions() end function module:OnOptionsRefreshed(evt) AceConfigReg:NotifyChange(configName) if self.editor then self.editor:Refresh() end end function module:PLAYER_REGEN_DISABLED() if self.editor then self.editor:Hide() end end function module:OpenConfig() InterfaceOptionsFrame_OpenToCategory(configName) end function module:InitializeOptions() ReAction:RegisterOptions(self, { _launchEditor = { type = "execute", handler = self, name = L["Edit Bars..."], desc = L["Show the ReAction Bar Editor dialogue"], func = function() self:LaunchBarEditor() -- you can't close a dialog in response to an options click, because the end of the -- handler for all the button events calls lib:Open() -- So, schedule a close on the next OnUpdate if self.db.profile.closeOnLaunch then self.editor.closePending = true end end, order = 2, }, _closeThis = { type = "toggle", name = L["Close on Launch"], desc = L["Close the Interface Options window when launching the ReAction Bar Editor"], get = function() return self.db.profile.closeOnLaunch end, set = function(info, val) self.db.profile.closeOnLaunch = val end, order = 3, }, _keybind = { type = "execute", handler = self, name = L["Key Bindings"], desc = L["Show the keybinding dialogue"], func = function() ReAction:SetKeybindMode(true) end, order = 4, }, }, true) -- global AceConfigReg:RegisterOptionsTable(configName,ReAction.options) self.frame = AceConfigDialog:AddToBlizOptions(configName, configName) self.frame.obj:SetCallback("default", function() ReAction.db:ResetProfile() ReAction:RefreshOptions() end ) end -- Bar Editor -- local function NewEditor() -- private variables local editorName = "ReAction-Editor" local barOptMap = setmetatable({},{__mode="v"}) local tmp = { } local pointTable = { CENTER = L["Center"], LEFT = L["Left"], RIGHT = L["Right"], TOP = L["Top"], BOTTOM = L["Bottom"], TOPLEFT = L["Top Left"], TOPRIGHT = L["Top Right"], BOTTOMLEFT = L["Bottom Left"], BOTTOMRIGHT = L["Bottom Right"], } -- use a local GUI container to work around AceConfigDialog closing -- both the bar editor and the global options when interface options is closed local editor = LibStub("AceGUI-3.0"):Create("Frame") local frame = editor.frame frame:SetClampedToScreen(true) frame:Hide() local old_OnUpdate = frame:GetScript("OnUpdate") frame:SetScript("OnUpdate", function(dt) if old_OnUpdate then old_OnUpdate(dt) end if editor.closePending then InterfaceOptionsFrame:Hide() editor.closePending = false end if editor.selfClosePending then editor:Hide() AceConfigReg:NotifyChange(configName) editor.selfClosePending = false end end ) editor:SetCallback("OnClose", function() ReAction:SetConfigMode(false) end ) AceConfigDialog:SetDefaultSize(editorName, 700, 540) local name = ("ReAction - %s"):format(L["Bar Editor"]) editor:SetTitle(name) local options = { type = "group", name = name, handler = editor, childGroups = "tree", args = { desc = { type = "description", name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."], order = 1 }, launchConfig = { type = "execute", name = L["Global Config"], desc = L["Opens ReAction global configuration settings panel"], func = function() module:OpenConfig() -- you can't close a dialog in response to an options click, because the end of the -- handler for all the button events calls lib:Open() -- So, schedule a close on the next OnUpdate if module.db.profile.editorCloseOnLaunch then editor.selfClosePending = true end end, order = 2 }, closeThis = { type = "toggle", name = L["Close on Launch"], desc = L["Close the Bar Editor when opening the ReAction global Interface Options"], get = function() return module.db.profile.editorCloseOnLaunch end, set = function(info, val) module.db.profile.editorCloseOnLaunch = val end, order = 3, }, new = { type = "group", name = L["New Bar..."], order = 4, args = { desc = { type = "description", name = L["Choose a name, type, and initial grid for your new action bar:"], order = 1, }, name = { type = "input", name = L["Bar Name"], desc = L["Enter a name for your new action bar"], get = function() return tmp.barName or "" end, set = function(info, val) tmp.barName = val end, order = 2, }, type = { type = "select", name = L["Button Type"], get = function() return tmp.barType or ReAction:GetDefaultBarType() or "" end, set = function(info, val) local c = ReAction:GetBarTypeConfig(val) tmp.barType = val tmp.barSize = c.defaultButtonSize or tmp.barSize tmp.barRows = c.defaultBarRows or tmp.barRows tmp.barCols = c.defaultBarCols or tmp.barCols tmp.barSpacing = c.defaultBarSpacing or tmp.barSpacing end, values = "GetBarTypes", order = 3, }, grid = { type = "group", name = L["Button Grid"], inline = true, args = { hdr = { type = "header", name = L["Button Grid"], order = 1, }, rows = { type = "range", name = L["Rows"], get = function() return tmp.barRows or 1 end, set = function(info, val) tmp.barRows = val end, width = "half", min = 1, max = 32, step = 1, order = 2, }, cols = { type = "range", name = L["Columns"], get = function() return tmp.barCols or 12 end, set = function(info, val) tmp.barCols = val end, width = "half", min = 1, max = 32, step = 1, order = 3, }, sz = { type = "range", name = L["Size"], get = function() return tmp.barSize or 36 end, set = function(info, val) tmp.barSize = val end, width = "half", min = 10, max = 72, step = 1, order = 4, }, spacing = { type = "range", name = L["Spacing"], get = function() return tmp.barSpacing or 3 end, set = function(info, val) tmp.barSpacing = val end, width = "half", min = 0, max = 24, step = 1, order = 5, } }, order = 4 }, spacer = { type = "header", name = "", width = "full", order = -2 }, go = { type = "execute", name = L["Create Bar"], func = "CreateBar", order = -1, } } } } } AceConfigReg:RegisterOptionsTable(editorName, options) function editor:Open(bar, ...) if bar then AceConfigDialog:SelectGroup(editorName, barOptMap[bar:GetName()], ...) end AceConfigDialog:Open(editorName,self) end function editor:Refresh() AceConfigReg:NotifyChange(editorName) end function editor:CreateBarTree(bar) local name = bar:GetName() -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be -- unique strings. So generate a unique key (it can be whatever) for the bar local args = options.args local key local i = 1 repeat key = ("bar%s"):format(i) i = i+1 until args[key] == nil barOptMap[name] = key args[key] = { type = "group", name = name, childGroups = "tab", args = { general = { type = "group", name = L["General"], order = 1, args = { name = { type = "input", name = L["Rename Bar"], get = function() return bar:GetName() end, set = function(info, value) return ReAction:RenameBar(bar, value) end, order = 1, }, delete = { type = "execute", name = L["Delete Bar"], desc = function() return bar:GetName() end, confirm = true, func = function() ReAction:EraseBar(bar) end, order = 2 }, anchor = { type = "group", name = L["Anchor"], inline = true, args = { frame = { type = "input", name = L["Frame"], desc = L["The frame that the bar is anchored to"], get = function() local _, f = bar:GetAnchor(); return f end, set = function(info, val) bar:SetAnchor(nil,val) end, validate = function(info, name) if name then local f = ReAction:GetBar(name) if f then return true else f = _G[name] if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then local _, explicit = f:IsProtected() return explicit end end end return false end, width = "double", order = 1 }, point = { type = "select", name = L["Point"], desc = L["Anchor point on the bar frame"], style = "dropdown", get = function() return bar:GetAnchor() end, set = function(info, val) bar:SetAnchor(val) end, values = pointTable, order = 2, }, relativePoint = { type = "select", name = L["Relative Point"], desc = L["Anchor point on the target frame"], style = "dropdown", get = function() local p,f,r = bar:GetAnchor(); return r end, set = function(info, val) bar:SetAnchor(nil,nil,val) end, values = pointTable, order = 3, }, x = { type = "input", pattern = "\-?%d+", name = L["X offset"], get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end, set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end, order = 4 }, y = { type = "input", pattern = "\-?%d+", name = L["Y offset"], get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end, set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end, order = 5 }, }, order = 3 }, alpha = { type = "range", name = L["Transparency"], get = function() return bar:GetAlpha() end, set = function(info, val) bar:SetAlpha(val) end, min = 0, max = 1, isPercent = true, step = 0.01, bigStep = 0.05, order = 4, }, }, }, } } self:RefreshBarTree(bar) end function editor:RefreshBarTree(bar) local key = barOptMap[bar:GetName()] if key and options.args[key] then options.args[key].plugins = ReAction:GenerateBarOptionsTable(bar) AceConfigReg:NotifyChange(editorName) end end function editor:OnCreateBar(evt, bar) if not tmp.creating then -- a bit of hack to work around OnCreateBar event handler ordering self:CreateBarTree(bar) end end function editor:OnDestroyBar(evt, bar, name) local key = barOptMap[name] if key then options.args[key] = nil end self:Refresh() end function editor:OnEraseBar(evt, name) local key = barOptMap[name] barOptMap[name] = nil if key then options.args[key] = nil self:Refresh() end end function editor:OnRenameBar(evt, bar, oldname, newname) local key = barOptMap[oldname] barOptMap[oldname], barOptMap[newname] = nil, key if key then options.args[key].name = newname self:Refresh() end end function editor:OnBarOptionGeneratorRegistered(evt) for name in pairs(barOptMap) do local bar = ReAction:GetBar(name) if bar then self:RefreshBarTree(bar) end end end local _scratch = { } function editor:GetBarTypes() for k,v in pairs(_scratch) do _scratch[k] = nil end return ReAction:GetBarTypeOptions(_scratch) end function editor:CreateBar() if tmp.barName and tmp.barName ~= "" then tmp.creating = true local bar = ReAction:CreateBar(tmp.barName, tmp.barType or ReAction:GetDefaultBarType(), tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing) if bar then self:CreateBarTree(bar) AceConfigDialog:SelectGroup(editorName, barOptMap[tmp.barName]) tmp.barName = nil end tmp.creating = false end end ReAction.RegisterCallback(editor,"OnCreateBar") ReAction.RegisterCallback(editor,"OnDestroyBar") ReAction.RegisterCallback(editor,"OnEraseBar") ReAction.RegisterCallback(editor,"OnRenameBar") ReAction.RegisterCallback(editor,"OnBarOptionGeneratorRegistered") for name, bar in ReAction:IterateBars() do editor:CreateBarTree(bar) end return editor end function module:LaunchBarEditor(bar, ...) if InCombatLockdown() then ReAction:UserError(L["ReAction config mode disabled during combat."]) else if not self.editor then self.editor = NewEditor() end self.editor:Open(bar, ...) ReAction:SetConfigMode(true) end end