# HG changeset patch # User Flick # Date 1211493728 0 # Node ID 768be7eb22a0a3a1794ef90e4f124f625c7443d7 # Parent f9cdb920470a3f026103ddaf4e65fe16bc68207e Converted several ReAction APIs to event-driven model instead of 'call-method-on-all-modules' model. Cleaned up a number of other architectural issues. diff -r f9cdb920470a -r 768be7eb22a0 Bar.lua --- a/Bar.lua Tue May 13 16:42:52 2008 +0000 +++ b/Bar.lua Thu May 22 22:02:08 2008 +0000 @@ -34,6 +34,8 @@ f:SetWidth(config.width) f:SetWidth(config.height) + ReAction.RegisterCallback(self, "OnConfigModeChanged") + self.frame = f self:RefreshLayout() self:ApplyAnchor() @@ -46,14 +48,19 @@ f:Hide() f:SetParent(UIParent) f:ClearAllPoints() + ReAction.UnregisterAllCallbacks(self) self.labelString = nil self.controlFrame = nil self.frame = nil self.config = nil end +function Bar:OnConfigModeChanged(event, mode) + self:ShowControls(mode) +end + function Bar:RefreshLayout() - ReAction:CallMethodOnAllModules("RefreshBar", self) + ReAction:RefreshBar(self) end function Bar:ApplyAnchor() @@ -186,7 +193,7 @@ local point, relativeTo, relativePoint, x, y = f:GetPoint(1) relativeTo = relativeTo or f:GetParent() local anchorTo - for name, b in pairs(ReAction.bars) do + for name, b in ReAction:IterateBars() do if b and b:GetFrame() == relativeTo then anchorTo = name break @@ -401,7 +408,7 @@ local function GetClosestVisibleEdge( f ) local r, o, e1, e2 local a = anchorOutside - for _, b in pairs(ReAction.bars) do + for _, b in ReAction:IterateBars() do local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a) if d and (not r or d < r) then r, o, e1, e2 = d, b:GetFrame(), e, opp @@ -523,10 +530,6 @@ end end - local function RefreshBarEditor() - ReAction:CallModuleMethod("ConfigUI","RefreshBarEditor") - end - CreateControls = function(bar) local f = bar.frame @@ -584,7 +587,7 @@ StoreSize(bar) ClampToButtons(bar) ApplyAnchor(bar) - RefreshBarEditor() + ReAction:RefreshOptions() end -- edge drag handles @@ -751,23 +754,23 @@ end StoreExtents(bar) - RefreshBarEditor() + ReAction:RefreshOptions() updateDragTooltip() end ) control:SetScript("OnEnter", function() - -- add bar type and status information to name + -- TODO: add bar type and status information to name + --[[ local name = bar.name for _, m in ReAction:IterateModules() do - --[[ local suffix = safecall(m,"GetBarNameModifier",bar) if suffix then name = ("%s %s"):format(name,suffix) end - --]] end + ]]-- updateDragTooltip() end @@ -825,7 +828,7 @@ type = "execute", name = L["Settings..."], desc = L["Open the editor for this bar"], - func = function() CloseMenu(self.controlFrame); ReAction:CallModuleMethod("ConfigUI","LaunchBarEditor",self) end, + func = function() CloseMenu(self.controlFrame); ReAction:ShowEditor(self) end, disabled = InCombatLockdown, order = 1 }, diff -r f9cdb920470a -r 768be7eb22a0 ReAction.lua --- a/ReAction.lua Tue May 13 16:42:52 2008 +0000 +++ b/ReAction.lua Thu May 22 22:02:08 2008 +0000 @@ -1,13 +1,37 @@ --- ReAction.lua --- See modules/ReAction_ModuleTemplate for Module API listing --- See Bar.lua for Bar object listing +--[[ + ReAction.lua + + The ReAction core manages 4 collections: + - modules (via AceAddon) + - bars + - options + - bar-type constructors + + and publishes events when those collections change. It also implements a single property, 'config mode', + and has a couple convenience methods which drill down to particular modules. + + Most of the "real work" of the addon happens in Bar.lua and the various modules. + + Events (with handler arguments): + -------------------------------- + "OnCreateBar" (bar, name) : after a bar object is created + "OnDestroyBar" (bar, name) : before a bar object is destroyed + "OnEraseBar" (bar, name) : before a bar config is removed from the profile db + "OnRenameBar" (bar, oldname, newname) : after a bar is renamed + "OnRefreshBar" (bar, name) : after a bar's state has been updated + "OnOptionsRefreshed" () : after the global options tree is refreshed + "OnConfigModeChanged" (mode) : after the config mode is changed + "OnBarOptionGeneratorRegistered" (module, function) : after an options generator function is registered + + ReAction is also an AceAddon-3.0 and contains an AceDB-3.0, which in turn publish more events. +]]-- +local version = GetAddOnMetadata("ReAction","Version") ------ CORE ------ local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction", "AceConsole-3.0", "AceEvent-3.0" ) -ReAction.version = GetAddOnMetadata("ReAction","Version") ReAction.revision = tonumber(("$Revision$"):match("%d+")) ------ GLOBALS ------ @@ -20,29 +44,78 @@ dbprint = function(msg) DEFAULT_CHAT_FRAME:AddMessage(msg) end - --seterrorhandler(dbprint) else dbprint = function() end end ReAction.dbprint = dbprint ------ LIBRARIES ------ +local callbacks = LibStub("CallbackHandler-1.0"):New(ReAction) local L = LibStub("AceLocale-3.0"):GetLocale("ReAction") ReAction.L = L ------ PRIVATE ------ -local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, SafeCall, CheckMethod, SlashHandler +local private = { } +local bars = {} +local defaultBarConfig = {} +local barOptionGenerators = { } +local options = { + type = "group", + name = "ReAction", + childGroups = "tab", + args = { + _desc = { + type = "description", + name = L["Customizable replacement for Blizzard's Action Bars"], + order = 1, + }, + global = { + type = "group", + name = L["Global Settings"], + desc = L["Global configuration settings"], + args = { + unlock = { + type = "toggle", + name = L["Unlock Bars"], + desc = L["Unlock bars for dragging and resizing with the mouse"], + handler = ReAction, + get = "GetConfigMode", + set = function(info, value) ReAction:SetConfigMode(value) end, + disabled = InCombatLockdown, + order = 1 + }, + }, + plugins = { }, + order = 2, + }, + module = { + type = "group", + childGroups = "select", + name = L["Module Settings"], + desc = L["Configuration settings for each module"], + args = { }, + plugins = { }, + order = 3, + }, + }, + plugins = { } +} +ReAction.options = options + +local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, CallModuleMethod, SlashHandler do local pcall = pcall local geterrorhandler = geterrorhandler + local self = ReAction + local inited = false - SelectBar = function(x) + function SelectBar(x) local bar, name if type(x) == "string" then name = x - bar = ReAction:GetBar(name) + bar = self:GetBar(name) else - for k,v in pairs(ReAction.bars) do + for k,v in pairs(bars) do if v == x then name = k bar = x @@ -52,37 +125,40 @@ return bar, name end - DestroyBar = function(x) + function DestroyBar(x) local bar, name = SelectBar(x) - if name and bar then - ReAction.bars[name] = nil - ReAction:CallMethodOnAllModules("RemoveFromBar", bar) + if bar and name then + bars[name] = nil + callbacks:Fire("OnDestroyBar", bar, name) bar:Destroy() end end - InitializeBars = function () - if not(ReAction.inited) then - for name, config in pairs(ReAction.db.profile.bars) do + function InitializeBars() + if not inited then + for name, config in pairs(self.db.profile.bars) do if config then - ReAction:CreateBar(name, config) + self:CreateBar(name, config) end end - ReAction:CallMethodOnAllBars("ApplyAnchor") -- re-anchor in the case of oddball ordering - ReAction.inited = true + -- re-anchor in case anchor order does not match init order + for name, bar in pairs(bars) do + bar:ApplyAnchor() + end + inited = true end end - TearDownBars = function() - for name, bar in pairs(ReAction.bars) do + function TearDownBars() + for name, bar in pairs(bars) do if bar then - ReAction.bars[name] = DestroyBar(bar) + bars[name] = DestroyBar(bar) end end - ReAction.inited = false + inited = false end - DeepCopy = function(x) + function DeepCopy(x) if type(x) ~= "table" then return x end @@ -93,39 +169,41 @@ return r end - SafeCall = function(f, ...) - if f then - local success, err = pcall(f,...) - if not success then - geterrorhandler()(err) + function CallModuleMethod(modulename, method, ...) + local m = self:GetModule(modulename,true) + if not m then + LoadAddOn(("ReAction_%s"):format(modulename)) + m = self:GetModule(modulename,true) + if m then + dbprint(("succesfully loaded LOD module: %s"):format(modulename)) end end + if m then + if type(m) == "table" and type(m[method]) == "function" then + m[method](m,...) + else + dbprint(("Bad call '%s' to %s module"):format(tostring(method),modulename)); + end + else + self:Print(("Module '%s' not found"):format(tostring(modulename))) + end end - CheckMethod = function(m) - if type(m) == "function" then - return m - end - if type(m) ~= "string" then - error("Invalid method") - end - end - - SlashHandler = function(option) + function SlashHandler(option) if option == "config" then - ReAction:ShowConfig() + self:ShowConfig() elseif option == "edit" then - ReAction:ShowEditor() + self:ShowEditor() elseif option == "unlock" then - ReAction:SetConfigMode(true) + self:SetConfigMode(true) elseif option == "lock" then - ReAction:SetConfigMode(false) + self:SetConfigMode(false) else - ReAction:Print(("%3.1f.%d"):format(ReAction.version,ReAction.revision)) - ReAction:Print("/reaction config") - ReAction:Print("/reaction edit") - ReAction:Print("/reaction lock") - ReAction:Print("/reaction unlock") + self:Print(("%3.1f.%d"):format(version,self.revision)) + self:Print("/rxn config") + self:Print("/rxn edit") + self:Print("/rxn lock") + self:Print("/rxn unlock") end end end @@ -144,57 +222,12 @@ ) self.db.RegisterCallback(self,"OnProfileChanged") self.db.RegisterCallback(self,"OnProfileReset","OnProfileChanged") - self.callbacks = LibStub("CallbackHandler-1.0"):New(self) + + options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) + self:RegisterChatCommand("reaction", SlashHandler) self:RegisterChatCommand("rxn", SlashHandler) self:RegisterEvent("PLAYER_REGEN_DISABLED") - - self.bars = {} - self.defaultBarConfig = {} - - self.options = { - type = "group", - name = "ReAction", - childGroups = "tab", - args = { - _desc = { - type = "description", - name = L["Customizable replacement for Blizzard's Action Bars"], - order = 1, - }, - global = { - type = "group", - name = L["Global Settings"], - desc = L["Global configuration settings"], - args = { - unlock = { - type = "toggle", - handler = module, - name = L["Unlock Bars"], - desc = L["Unlock bars for dragging and resizing with the mouse"], - get = function() return self.configMode end, - set = function(info, value) self:SetConfigMode(value) end, - disabled = InCombatLockdown, - order = 1 - }, - }, - plugins = { }, - order = 2, - }, - module = { - type = "group", - childGroups = "select", - name = L["Module Settings"], - desc = L["Configuration settings for each module"], - args = { }, - plugins = { }, - order = 3, - }, - profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) - }, - plugins = { } - } - end function ReAction:OnEnable() @@ -210,29 +243,9 @@ InitializeBars() end -function ReAction:OnModuleEnable(module) - if module.ApplyToBar then - for _, b in pairs(bars) do - if b then - module:ApplyToBar(b) - end - end - end -end - -function ReAction:OnModuleDisable(module) - if module.RemoveFromBar then - for _, b in pairs(bars) do - if b then - module:RemoveFromBar(b) - end - end - end -end - function ReAction:PLAYER_REGEN_DISABLED() - if self.configMode == true then - UIErrorsFrame:AddMessage(L["ReAction config mode disabled during combat."]) + if private.configMode == true then + self:UserError(L["ReAction config mode disabled during combat."]) self:SetConfigMode(false) end end @@ -245,45 +258,9 @@ UIErrorsFrame:AddMessage(msg) end -function ReAction:CallMethodOnAllModules(method, ...) - local m = CheckMethod(method) - for _, x in self:IterateModules() do - if x then - SafeCall(m or x[method], x, ...) - end - end -end - -function ReAction:CallMethodOnAllBars(method,...) - local m = CheckMethod(method) - for _, x in pairs(self.bars) do - if x then - SafeCall(m or x[method], x, ...) - end - end -end - -function ReAction:CallModuleMethod(modulename, method, ...) - local m = self:GetModule(modulename,true) - if not m then - LoadAddOn(("ReAction_%s"):format(modulename)) - m = self:GetModule(modulename,true) - if m then - dbprint(("succesfully loaded LOD module: %s"):format(modulename)) - end - end - if m then - if type(m) == "table" and type(m[method]) == "function" then - m[method](m,...) - else - dbprint(("Bad call '%s' to %s module"):format(tostring(method),modulename)); - end - else - self:Print(("Module '%s' not found"):format(tostring(modulename))) - end -end - - +-- usage: +-- (1) ReAction:CreateBar(name, cfgTable) +-- (2) ReAction:CreateBar(name, "barType", [nRows], [nCols], [btnSize], [btnSpacing]) function ReAction:CreateBar(name, ...) local config = select(1,...) if config and type(config) ~= "table" then @@ -291,7 +268,7 @@ if type(bartype) ~= "string" then error("ReAction:CreateBar() - first argument must be a config table or a default config type string") end - config = self.defaultBarConfig[bartype] + config = defaultBarConfig[bartype] if not config then error(("ReAction:CreateBar() - unknown bar type '%s'"):format(bartype)) end @@ -317,14 +294,13 @@ repeat name = prefix..i i = i + 1 - until self.bars[name] == nil + until bars[name] == nil end profile.bars[name] = profile.bars[name] or config local bar = self.Bar:new( name, profile.bars[name] ) -- ReAction.Bar defined in Bar.lua - self:CallMethodOnAllModules("ApplyToBar", bar) - self.bars[name] = bar - self.callbacks:Fire("OnCreateBar", bar) - if self.configMode then + bars[name] = bar + callbacks:Fire("OnCreateBar", bar, name) + if private.configMode then bar:ShowControls(true) end @@ -333,69 +309,150 @@ function ReAction:EraseBar(x) local bar, name = SelectBar(x) - if name and bar then + if bar and name then + callbacks:Fire("OnEraseBar", bar, name) DestroyBar(bar) self.db.profile.bars[name] = nil - self:CallMethodOnAllModules("EraseBarConfig", name) - self.callbacks:Fire("OnEraseBar",name) end end function ReAction:GetBar(name) - return self.bars[name] + return bars[name] +end + +function ReAction:IterateBars() + return pairs(bars) end function ReAction:RenameBar(x, newname) local bar, name = SelectBar(x) - if bar and name and newname then - if self.bars[newname] then - UIErrorsFrame:AddMessage(("%s ('%s')"):format(L["ReAction: name already in use"],newname)) + if type(newname) ~= "string" then + error("ReAction:RenameBar() - second argument must be a string") + end + if bar and name and #newname > 0 then + if bars[newname] then + self:UserError(("%s ('%s')"):format(L["ReAction: name already in use"],newname)) else - self.bars[newname] = self.bars[name] - self.bars[name] = nil + bars[newname], bars[name] = bars[name], nil bar:SetName(newname or "") local cfg = self.db.profile.bars cfg[newname], cfg[name] = cfg[name], nil - self:CallMethodOnAllModules("RenameBarConfig", name, newname) - self.callbacks:Fire("OnRenameBar", name, newname) + callbacks:Fire("OnRenameBar", bar, name, newname) end end end +function ReAction:RefreshBar(x) + local bar, name = SelectBar(x) + if bar and name then + callbacks:Fire("OnRefreshBar", bar, name) + end +end + function ReAction:RegisterBarType( name, config, isDefaultChoice ) - self.defaultBarConfig[name] = config + defaultBarConfig[name] = config if isDefaultChoice then - self.defaultBarConfigChoice = name + defaultBarConfigChoice = name end self:RefreshOptions() end function ReAction:UnregisterBarType( name ) - self.defaultBarConfig[name] = nil - if self.defaultBarConfigChoice == name then - self.defaultBarConfigChoice = nil + defaultBarConfig[name] = nil + if private.defaultBarConfigChoice == name then + private.defaultBarConfigChoice = nil end self:RefreshOptions() end -function ReAction:RegisterOptions(module, options, global) - self.options.args[global and "global" or "module"].plugins[module:GetName()] = options +function ReAction:IterateBarTypes() + return pairs(defaultBarConfig) +end + +function ReAction:GetBarTypeConfig(name) + if name then + return defaultBarConfig[name] + end +end + +function ReAction:GetBarTypeOptions( fill ) + fill = fill or { } + for k in self:IterateBarTypes() do + fill[k] = k + end + return fill +end + +function ReAction:GetDefaultBarType() + return private.defaultBarConfigChoice +end + +function ReAction:RegisterOptions(module, opts, global) + options.args[global and "global" or "module"].plugins[module:GetName()] = opts + self:RefreshOptions() end function ReAction:RefreshOptions() - self.callbacks:Fire("OnOptionsRefreshed") + callbacks:Fire("OnOptionsRefreshed") +end + +-- +-- In addition to global and general module options, options tables +-- must be generated dynamically for each bar. +-- +-- 'func' should be a function or a method string. +-- The function or method will be passed the bar as its parameter. +-- (methods will of course get the module as the first 'self' parameter) +-- +-- A generator can be unregistered by passing a nil func. +-- +function ReAction:RegisterBarOptionGenerator( module, func ) + if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly + error("ReAction:RegisterBarOptionGenerator() : Invalid module") + end + if type(func) == "string" then + if not module[func] then + error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func)) + end + elseif func and type(func) ~= "function" then + error("ReAction:RegisterBarOptionGenerator() : Invalid function") + end + barOptionGenerators[module] = func + callbacks:Fire("OnBarOptionGeneratorRegistered", module, func) +end + +-- builds a table suitable for use as an AceConfig3 group 'plugins' sub-table +function ReAction:GenerateBarOptionsTable( bar ) + local opts = { } + for module, func in pairs(barOptionGenerators) do + local success, r + if type(func) == "string" then + success, r = pcall(module[func], module, bar) + else + success, r = pcall(func, bar) + end + if success then + opts[module:GetName()] = { [module:GetName()] = r } + else + geterrorhandler()(r) + end + end + return opts end function ReAction:SetConfigMode( mode ) - self:CallMethodOnAllBars("ShowControls",mode) - self:CallMethodOnAllModules("ApplyConfigMode",mode,self.bars) - self.configMode = mode + private.configMode = mode + callbacks:Fire("OnConfigModeChanged", mode) +end + +function ReAction:GetConfigMode() + return private.configMode end function ReAction:ShowConfig() - self:CallModuleMethod("ConfigUI","OpenConfig") + CallModuleMethod("ConfigUI","OpenConfig") end -function ReAction:ShowEditor() - self:CallModuleMethod("ConfigUI","LaunchBarEditor") +function ReAction:ShowEditor(bar) + CallModuleMethod("ConfigUI","LaunchBarEditor",bar) end diff -r f9cdb920470a -r 768be7eb22a0 modules/ReAction_Action/ReAction_Action.lua --- a/modules/ReAction_Action/ReAction_Action.lua Tue May 13 16:42:52 2008 +0000 +++ b/modules/ReAction_Action/ReAction_Action.lua Thu May 22 22:02:08 2008 +0000 @@ -27,7 +27,6 @@ } ) self.buttons = { } - self.options = setmetatable({},{__mode="k"}) ReAction:RegisterOptions(self, { [moduleID] = { @@ -43,6 +42,16 @@ } } }) + + ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") + + ReAction.RegisterCallback(self, "OnCreateBar", "OnRefreshBar") + ReAction.RegisterCallback(self, "OnDestroyBar") + ReAction.RegisterCallback(self, "OnRefreshBar") + ReAction.RegisterCallback(self, "OnEraseBar") + ReAction.RegisterCallback(self, "OnRenameBar") + ReAction.RegisterCallback(self, "OnConfigModeChanged") + end function module:OnEnable() @@ -60,22 +69,17 @@ ReAction:UnregisterBarType(L["Action Bar"]) end -function module:ApplyToBar(bar) - self:RefreshBar(bar) -end - -function module:RefreshBar(bar) +function module:OnRefreshBar(event, bar, name) if bar.config.type == moduleID then if self.buttons[bar] == nil then self.buttons[bar] = { } end local btns = self.buttons[bar] local profile = self.db.profile - local barName = bar:GetName() - if profile.buttons[barName] == nil then - profile.buttons[barName] = {} + if profile.buttons[name] == nil then + profile.buttons[name] = {} end - local btnCfg = profile.buttons[barName] + local btnCfg = profile.buttons[name] local r, c = bar:GetButtonGrid() local n = r*c @@ -103,7 +107,7 @@ end end -function module:RemoveFromBar(bar) +function module:OnDestroyBar(event, bar, name) if self.buttons[bar] then local btns = self.buttons[bar] for _,b in pairs(btns) do @@ -115,11 +119,11 @@ end end -function module:EraseBarConfig(barName) - self.db.profile.buttons[barName] = nil +function module:OnEraseBar(event, bar, name) + self.db.profile.buttons[name] = nil end -function module:RenameBarConfig(oldname, newname) +function module:OnRenameBar(event, bar, oldname, newname) local b = self.db.profile.buttons b[newname], b[oldname] = b[oldname], nil end @@ -139,8 +143,8 @@ end end -function module:ApplyConfigMode(mode,bars) - for _, bar in pairs(bars) do +function module:OnConfigModeChanged(event, mode) + for _, bar in ReAction:IterateBars() do if bar and self.buttons[bar] then for _, b in pairs(self.buttons[bar]) do if b then @@ -179,16 +183,13 @@ ---- Options ---- function module:GetBarOptions(bar) - if not self.options[bar] then - self.options[bar] = { - type = "group", - name = L["Action Buttons"], - hidden = function() return bar.config.type ~= moduleID end, - args = { - } + return { + type = "group", + name = L["Action Buttons"], + hidden = function() return bar.config.type ~= moduleID end, + args = { } - end - return self.options[bar] + } end diff -r f9cdb920470a -r 768be7eb22a0 modules/ReAction_ConfigUI/ReAction_ConfigUI.lua --- a/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua Tue May 13 16:42:52 2008 +0000 +++ b/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua Thu May 22 22:02:08 2008 +0000 @@ -85,7 +85,7 @@ self.frame.obj:SetCallback("default", function() ReAction.db:ResetProfile() - self:OnOptionsRefreshed() + ReAction:RefreshOptions() end ) end @@ -96,7 +96,7 @@ local function NewEditor() -- private variables local editorName = "ReAction-Editor" - local barOptMap = { } + local barOptMap = setmetatable({},{__mode="v"}) local tmp = { } local pointTable = { CENTER = L["Center"], @@ -126,7 +126,7 @@ editor.closePending = false end if editor.selfClosePending then - ed:Hide() + editor:Hide() AceConfigReg:NotifyChange(configName) editor.selfClosePending = false end @@ -193,9 +193,9 @@ type = { type = "select", name = L["Button Type"], - get = function() return tmp.barType or ReAction.defaultBarConfigChoice or "" end, + get = function() return tmp.barType or ReAction:GetDefaultBarType() or "" end, set = function(info, val) - local c = ReAction.defaultBarConfig[val] + local c = ReAction:GetBarTypeConfig(val) tmp.barType = val tmp.barSize = c.defaultButtonSize or tmp.barSize tmp.barRows = c.defaultBarRows or tmp.barRows @@ -403,12 +403,10 @@ end function editor:RefreshBarTree(bar) - local opts = options.args[barOptMap[bar:GetName()]] - opts.plugins = { } - for name, module in ReAction:IterateModules() do - if module.GetBarOptions then - opts.plugins[module:GetName()] = { [module:GetName()] = module:GetBarOptions(bar) } - end + local key = barOptMap[bar:GetName()] + if key and options.args[key] then + options.args[key].plugins = ReAction:GenerateBarOptionsTable(bar) + AceConfigReg:NotifyChange(editorName) end end @@ -416,6 +414,14 @@ self:CreateBarTree(bar) 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 @@ -434,29 +440,37 @@ 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 - for k in pairs(ReAction.defaultBarConfig) do - _scratch[k] = k - end - return _scratch + return ReAction:GetBarTypeOptions(_scratch) end function editor:CreateBar() if tmp.barName and tmp.barName ~= "" then - ReAction:CreateBar(tmp.barName, tmp.barType or ReAction.defaultBarConfigChoice, tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing) + ReAction:CreateBar(tmp.barName, tmp.barType or ReAction:GetDefaultBarType(), tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing) tmp.barName = nil 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 pairs(ReAction.bars) do + for name, bar in ReAction:IterateBars() do editor:CreateBarTree(bar) end @@ -471,6 +485,7 @@ if not self.editor then self.editor = NewEditor() end + -- TODO: figure out how to open to a particular bar: currently AceConfigDialogue doesn't support this self.editor:Open() ReAction:SetConfigMode(true) end diff -r f9cdb920470a -r 768be7eb22a0 modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua --- a/modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua Tue May 13 16:42:52 2008 +0000 +++ b/modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua Thu May 22 22:02:08 2008 +0000 @@ -14,7 +14,7 @@ -- mixins go here ) --- module methods +-- handlers function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID { @@ -24,7 +24,13 @@ } ) - end + -- register some common events + ReAction.RegisterCallback(self, "OnCreateBar") + ReAction.RegisterCallback(self, "OnDestroyBar") + ReAction.RegisterCallback(self, "OnRefreshBar") + ReAction.RegisterCallback(self, "OnEraseBar") + ReAction.RegisterCallback(self, "OnRenameBar") + ReAction.RegisterCallback(self, "OnConfigModeChanged") end function module:OnEnable() @@ -35,40 +41,33 @@ end - ----- ReAction module API ---- - -- apply module features and settings to a bar object (see Bar.lua for Bar API) -function module:ApplyToBar(bar) +function module:OnCreateBar(event, bar, name) end -- remove module features and settings from a bar object -function module:RemoveFromBar(bar) +function module:OnDestroyBar(event, bar, name) end -- refresh module features and settings on a bar object -function module:RefreshBar(bar) +function module:OnRefreshBar(event, bar, name) end --- notification of config mode (true/false) on the list of bars -function module:ApplyConfigMode(mode,listOfBars) +-- erase any local configuration entries for the supplied bar name +function module:OnEraseBar(event, bar, name) end --- return a name-modifier (suffix) for the bar name display. This can reflect a dynamic state. -function module:GetBarNameModifier(bar) - return nil -end - --- erase any local configuration entries for the supplied bar name -function module:EraseBarConfig(barName) +-- update any local configuration/option entries with the new bar name index +function module:OnRenameBar(event, bar, oldName, newName) end --- update any local configuration entries with the new bar name index -function module:RenameBarConfig(oldName, newName) +-- update any local display/options based on config mode (true/false) +function module:OnConfigModeChanged(event, mode) end + diff -r f9cdb920470a -r 768be7eb22a0 modules/ReAction_PetAction/ReAction_PetAction.lua --- a/modules/ReAction_PetAction/ReAction_PetAction.lua Tue May 13 16:42:52 2008 +0000 +++ b/modules/ReAction_PetAction/ReAction_PetAction.lua Thu May 22 22:02:08 2008 +0000 @@ -27,7 +27,15 @@ } ) self.buttons = { } - self.options = setmetatable({},{__mode="k"}) + + ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") + + ReAction.RegisterCallback(self, "OnCreateBar") + ReAction.RegisterCallback(self, "OnDestroyBar") + ReAction.RegisterCallback(self, "OnRefreshBar") + ReAction.RegisterCallback(self, "OnEraseBar") + ReAction.RegisterCallback(self, "OnRenameBar") + ReAction.RegisterCallback(self, "OnConfigModeChanged") end function module:OnEnable() @@ -45,27 +53,26 @@ ReAction:UnregisterBarType(L["Pet Action Bar"]) end -function module:ApplyToBar(bar) +function module:OnCreateBar(event, bar, name) if bar.config.type == moduleID then -- auto show/hide when pet exists bar:GetFrame():SetAttribute("unit","pet") RegisterUnitWatch(bar:GetFrame()) - self:RefreshBar(bar) + self:OnRefreshBar(event, bar, name) end end -function module:RefreshBar(bar) +function module:OnRefreshBar(event, bar, name) if bar.config.type == moduleID then if self.buttons[bar] == nil then self.buttons[bar] = { } end local btns = self.buttons[bar] local profile = self.db.profile - local barName = bar:GetName() - if profile.buttons[barName] == nil then - profile.buttons[barName] = {} + if profile.buttons[name] == nil then + profile.buttons[name] = {} end - local btnCfg = profile.buttons[barName] + local btnCfg = profile.buttons[name] local r, c = bar:GetButtonGrid() local n = r*c @@ -93,7 +100,7 @@ end end -function module:RemoveFromBar(bar) +function module:OnDestroyBar(event, bar, name) if self.buttons[bar] then local btns = self.buttons[bar] for _,b in pairs(btns) do @@ -105,18 +112,18 @@ end end -function module:EraseBarConfig(barName) - self.db.profile.buttons[barName] = nil +function module:OnEraseBar(event, bar, name) + self.db.profile.buttons[name] = nil end -function module:RenameBarConfig(oldname, newname) +function module:OnRenameBar(event, bar, oldname, newname) local b = self.db.profile.buttons b[newname], b[oldname] = b[oldname], nil end -function module:ApplyConfigMode(mode,bars) - for _, bar in pairs(bars) do +function module:OnConfigModeChanged(event, mode) + for _, bar in ReAction:IterateBars() do if bar and self.buttons[bar] then for _, b in pairs(self.buttons[bar]) do if b then @@ -160,16 +167,13 @@ ---- Options ---- function module:GetBarOptions(bar) - if not self.options[bar] then - self.options[bar] = { - type = "group", - name = L["Pet Buttons"], - hidden = function() return bar.config.type ~= moduleID end, - args = { - } + return { + type = "group", + name = L["Pet Buttons"], + hidden = function() return bar.config.type ~= moduleID end, + args = { } - end - return self.options[bar] + } end diff -r f9cdb920470a -r 768be7eb22a0 modules/ReAction_PossessBar/ReAction_PossessBar.lua --- a/modules/ReAction_PossessBar/ReAction_PossessBar.lua Tue May 13 16:42:52 2008 +0000 +++ b/modules/ReAction_PossessBar/ReAction_PossessBar.lua Thu May 22 22:02:08 2008 +0000 @@ -26,7 +26,6 @@ } ) self.buttons = { } - self.options = setmetatable({},{__mode="k"}) ReAction:RegisterOptions(self, { [moduleID] = { @@ -42,6 +41,15 @@ } } }) + + ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") + + ReAction.RegisterCallback(self, "OnCreateBar") + ReAction.RegisterCallback(self, "OnDestroyBar") + ReAction.RegisterCallback(self, "OnRefreshBar") + ReAction.RegisterCallback(self, "OnEraseBar") + ReAction.RegisterCallback(self, "OnRenameBar") + ReAction.RegisterCallback(self, "OnConfigModeChanged") end function module:OnEnable() @@ -59,27 +67,26 @@ ReAction:UnregisterBarType(L["Possess Bar"]) end -function module:ApplyToBar(bar) +function module:OnCreateBar(event, bar, name) if bar.config.type == moduleID then bar:GetFrame():SetParent(PossessBarFrame) bar.config.parent = "PossessBarFrame" self:CreatePossessControlButtons(bar) end - self:RefreshBar(bar) + self:OnRefreshBar(event, bar, name) end -function module:RefreshBar(bar) +function module:OnRefreshBar(event, bar, name) if bar.config.type == moduleID then if self.buttons[bar] == nil then self.buttons[bar] = { } end local btns = self.buttons[bar] local profile = self.db.profile - local barName = bar:GetName() - if profile.buttons[barName] == nil then - profile.buttons[barName] = {} + if profile.buttons[name] == nil then + profile.buttons[name] = {} end - local btnCfg = profile.buttons[barName] + local btnCfg = profile.buttons[name] local r, c = bar:GetButtonGrid() local n = r*c @@ -107,7 +114,7 @@ end end -function module:RemoveFromBar(bar) +function module:OnDestroyBar(event, bar, name) if self.buttons[bar] then local btns = self.buttons[bar] for _,b in pairs(btns) do @@ -119,11 +126,11 @@ end end -function module:EraseBarConfig(barName) - self.db.profile.buttons[barName] = nil +function module:OnEraseBar(event, bar, name) + self.db.profile.buttons[name] = nil end -function module:RenameBarConfig(oldname, newname) +function module:OnRenameBar(event, bar, oldname, newname) local b = self.db.profile.buttons b[newname], b[oldname] = b[oldname], nil end @@ -143,8 +150,8 @@ end end -function module:ApplyConfigMode(mode,bars) - for _, bar in pairs(bars) do +function module:OnConfigModeChanged(event, mode) + for _, bar in ReAction:IterateBars() do if bar and self.buttons[bar] then for _, b in pairs(self.buttons[bar]) do if b then @@ -257,16 +264,13 @@ ---- Options ---- function module:GetBarOptions(bar) - if not self.options[bar] then - self.options[bar] = { - type = "group", - name = L["Possess Buttons"], - hidden = function() return bar.config.type ~= moduleID end, - args = { - } + return { + type = "group", + name = L["Possess Buttons"], + hidden = function() return bar.config.type ~= moduleID end, + args = { } - end - return self.options[bar] + } end