Mercurial > wow > reaction
diff modules/Config.lua @ 109:410d036c43b2
- reorganize modularity file structure (part 1)
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Thu, 08 Jan 2009 00:57:27 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/Config.lua Thu Jan 08 00:57:27 2009 +0000 @@ -0,0 +1,529 @@ +--[[ + 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 not frame:IsVisible() then + AceConfigDialog:Open(editorName,self) + end + if bar then + AceConfigDialog:SelectGroup(editorName, barOptMap[bar:GetName()], ...) + end + 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) + self:CreateBarTree(bar) + AceConfigDialog:SelectGroup(editorName, barOptMap[tmp.barName]) + tmp.barName = nil + 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 +