Mercurial > wow > reaction
changeset 77:da8ba8783924
- added revision updater to each code file
- Changed button/bar class mechanic to metatable-based
- Changed buttons to live within a sub-frame, to play nicely between show-empty-buttons and hidestates
- bar frame is now available only via accessor
- Changed some semantics with AddButton/PlaceButton
- Cleaned up action buttons options, fixed hide-when-empty option
- moved show-action-ID-label as a button method
- converted drag overlay from nested-frame to :Raise()
- fixed ReAction:SetConfigMode() to not call event when mode doesn't change
- Fixed ordering for dynamic state tab (always last)
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Mon, 23 Jun 2008 22:27:50 +0000 |
parents | c8c8610fd864 |
children | 502cdb5666e2 |
files | Bar.lua Overlay.lua ReAction.lua State.lua locale/enUS.lua modules/ReAction_Action/ReAction_Action.lua modules/ReAction_ConfigUI/ReAction_ConfigUI.lua modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua modules/ReAction_PetAction/ReAction_PetAction.lua |
diffstat | 10 files changed, 256 insertions(+), 237 deletions(-) [+] |
line wrap: on
line diff
--- a/Bar.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/Bar.lua Mon Jun 23 22:27:50 2008 +0000 @@ -7,18 +7,16 @@ local format = string.format local SecureStateHeader_Refresh = SecureStateHeader_Refresh - --- update ReAction revision if this file is newer -local revision = tonumber(("$Revision$"):match("%d+")) -if revision > ReAction.revision then - ReAction.revision = revision -end +ReAction:UpdateRevision("$Revision$") ------ BAR CLASS ------ local Bar = { _classID = {} } +ReAction.Bar = Bar -- export to ReAction -local function Constructor( self, name, config ) +function Bar:New( name, config ) + -- create new self + self = setmetatable( { }, {__index = Bar} ) if type(config) ~= "table" then error("ReAction.Bar: config table required") end @@ -32,24 +30,43 @@ local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent local f = CreateFrame("Button",name and format("ReAction-%s",name),parent,"SecureStateHeaderTemplate, SecureActionButtonTemplate") - - -- The frame itself is read-only - function self:GetFrame() - return f - end + f:SetFrameStrata("MEDIUM") + f:SetWidth(config.width) + f:SetWidth(config.height) + f:Show() -- The bar itself is also a Button derived from SecureActionButtonTemplate, so it has an OnClick handler -- which we can use as a virtual button for keybinds, which will send attribute-value changes to itself. -- However, we don't ever want the user to be able to click it directly. f:EnableMouse(false) f:SetAttribute("type","attribute") - f:SetFrameStrata("MEDIUM") - f:SetWidth(config.width) - f:SetWidth(config.height) - f:Show() + + -- Buttons are contained in an anonymous intermediate sub-frame. This arrangement is to specifically + -- address the issue of the interaction with hidestates and auto-hiding empty action buttons (the two + -- don't play nicely together). It also has the fringe benefit of making show/hide faster because a + -- single frame is shown/hidden instead of potentially dozens. Unfortunately it does add an extra layer + -- of indirection to all state changes, as a secondary (trivial) statemap must be invoked. This + -- complicates frame setup slightly. + local bf = CreateFrame("Frame", nil, f, "SecureStateHeaderTemplate") + bf:SetAllPoints() + bf:Show() + bf:SetAttribute("useparent*",true) -- this facilitates SecureButton_GetModifiedAttribute() + bf:SetAttribute("statemap-parent","*:=") -- however some methods don't use it, so propagate the state too + f:SetAttribute("addchild",bf) + + -- Both frames are read-only. Override the default accessors for this object. + function self:GetFrame() + return f + end + + function self:GetButtonFrame() + return bf + end self:ApplyAnchor() ReAction.RegisterCallback(self, "OnConfigModeChanged") + + return self end function Bar:Destroy() @@ -158,6 +175,18 @@ return self.name end +function Bar:GetFrame() + -- this method is included for documentation purposes. It is overridden + -- in the New method for each object. + error("Invalid Bar object: used without initialization") +end + +function Bar:GetButtonFrame() + -- this method is included for documentation purposes. It is overridden + -- in the New method for each object. + error("Invalid Bar object: used without initialization") +end + -- only ReAction:RenameBar() should call this function function Bar:SetName(name) self.name = name @@ -168,7 +197,9 @@ end function Bar:AddButton(idx, button) + -- store in a reverse-index array self.buttons[button] = idx + self:GetButtonFrame():SetAttribute("addchild",button:GetFrame()) SecureStateHeader_Refresh(self:GetFrame()) end @@ -234,7 +265,7 @@ end end --- Set an attribute on the frame (or its buttons if 'doButtons' = true) +-- Set an attribute on the frame (or buttonFrame if 'buttonFrame' = true) -- Either or both 'map' and 'default' can be passed: -- - If 'map' is omitted, then 'default' is set to the attribute. -- - If 'map' is provided, then it is interpreted as an unordered @@ -243,7 +274,8 @@ -- string, e.g. "<state1>:<value1>;<state2>:<value2>". If 'default' -- is also provided, then its value will be converted to a string -- and appended. -function Bar:SetStateAttribute( attribute, map, default, doButtons ) +function Bar:SetStateAttribute( attribute, map, default, buttonFrame ) + local f = buttonFrame and self:GetButtonFrame() or self:GetFrame() local value = default if map then local tmp = { } @@ -255,29 +287,6 @@ end value = table.concat(tmp,";") end - if doButtons then - for b in pairs(self.buttons) do - local f = b.GetFrame and b:GetFrame() - if f then - f:SetAttribute(attribute, value) - end - end - else - self:GetFrame():SetAttribute(attribute, value) - end - SecureStateHeader_Refresh(self:GetFrame()) + f:SetAttribute(attribute, value) + SecureStateHeader_Refresh(f) end - - ------- Export as a class-factory ------ -ReAction.Bar = { - prototype = Bar, - New = function(self, ...) - local x = { } - for k,v in pairs(Bar) do - x[k] = v - end - Constructor(x, ...) - return x - end -}
--- a/Overlay.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/Overlay.lua Mon Jun 23 22:27:50 2008 +0000 @@ -7,6 +7,8 @@ local format = string.format local GameTooltip = GameTooltip +ReAction:UpdateRevision("$Revision: 103 $") + -- Looking for a lightweight AceConfig3-struct-compatible -- replacement for Dewdrop (e.g. forthcoming AceConfigDropdown-3.0?). -- Considering Blizzard's EasyMenu/UIDropDownMenu, but that's @@ -55,7 +57,7 @@ -- Bar config overlay -- -- localize some of these for small OnUpdate performance boost -local Bar = ReAction.Bar.prototype +local Bar = ReAction.Bar local GetSize = Bar.GetSize local GetButtonSize = Bar.GetButtonSize local GetButtonGrid = Bar.GetButtonGrid @@ -413,15 +415,7 @@ f:SetResizable(true) f:SetClampedToScreen(true) - -- buttons on the bar should be direct children of the bar frame. - -- The control elements need to float on top of this, which we could - -- do with SetFrameLevel() or Raise(), but it's more reliable to do it - -- via frame nesting, hence good old foo's appearance here. - local foo = CreateFrame("Frame",nil,f) - foo:SetAllPoints() - foo:SetClampedToScreen(true) - - local control = CreateFrame("Button", nil, foo) + local control = CreateFrame("Button", nil, f) control:EnableMouse(true) control:SetToplevel(true) control:SetPoint("TOPLEFT", -4, 4) @@ -433,6 +427,7 @@ edgeSize = 16, insets = { left = 0, right = 0, top = 0, bottom = 0 }, }) + control:SetClampedToScreen(true) -- textures local bgTex = control:CreateTexture(nil,"BACKGROUND") @@ -509,11 +504,11 @@ edge:Show() end - -- corner drag handles, again nested in an anonymous frame so that they are on top - local foo2 = CreateFrame("Frame",nil,control) - foo2:SetAllPoints(true) + -- corner drag handles, nested in an anonymous frame so that they are on top + local foo = CreateFrame("Frame",nil,control) + foo:SetAllPoints(true) for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do - local corner = CreateFrame("Frame",nil,foo2) + local corner = CreateFrame("Frame",nil,foo) corner:EnableMouse(true) corner:SetWidth(12) corner:SetHeight(12) @@ -669,6 +664,7 @@ self.controlFrame = CreateControls(self) end self.controlFrame:Show() + self.controlFrame:Raise() elseif self.controlFrame then CloseMenu(self.controlFrame) self.controlFrame:Hide()
--- a/ReAction.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/ReAction.lua Mon Jun 23 22:27:50 2008 +0000 @@ -253,6 +253,13 @@ ------ API ------ +function ReAction:UpdateRevision(str) + local revision = tonumber(str:match("%d+")) + if revision and revision > ReAction.revision then + ReAction.revision = revision + end +end + function ReAction:UserError(msg) -- any user errors should be flashed to the UIErrorsFrame UIErrorsFrame:AddMessage(msg) @@ -441,8 +448,10 @@ end function ReAction:SetConfigMode( mode ) - private.configMode = mode - callbacks:Fire("OnConfigModeChanged", mode) + if mode ~= private.configMode then + private.configMode = mode + callbacks:Fire("OnConfigModeChanged", mode) + end end function ReAction:GetConfigMode()
--- a/State.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/State.lua Mon Jun 23 22:27:50 2008 +0000 @@ -10,6 +10,8 @@ local InCombatLockdown = InCombatLockdown local format = string.format +ReAction:UpdateRevision("$Revision: 103 $") + -- module declaration local moduleID = "State" local module = ReAction:NewModule( moduleID, "AceEvent-3.0" ) @@ -172,7 +174,7 @@ -- ?? button:UpdateBindingSet(kbset) end end - bar:SetStateAttribute("statebindings", map) + bar:SetStateAttribute("statebindings", map, true) -- apply to button frame, bindings only work for direct children end, enableAnchor = function( bar, states ) @@ -902,8 +904,9 @@ local private = { } local states = tbuild(module.db.profile.bars, bar:GetName(), "states") local options = { + name = L["Dynamic State"], type = "group", - name = L["Dynamic State"], + order = -1, childGroups = "tree", disabled = InCombatLockdown, args = {
--- a/locale/enUS.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/locale/enUS.lua Mon Jun 23 22:27:50 2008 +0000 @@ -123,6 +123,7 @@ "Action Bar", "Action Bars", "Hide Empty Buttons", +"Hide buttons when empty. This option is not supported for multi-state bars", "Action Buttons", -- modules/ReAction_PetAction
--- a/modules/ReAction_Action/ReAction_Action.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/modules/ReAction_Action/ReAction_Action.lua Mon Jun 23 22:27:50 2008 +0000 @@ -2,8 +2,10 @@ ReAction Action button module. The button module implements standard action button functionality by wrapping Blizzard's - ActionButton frame and associated functions. It also provides some button layout - modification tools. + ActionButton frame and associated functions. + + It also provides support for multiple pages (interacting with the State module) as well + as optional action remapping for possessed targets (mind control). --]] @@ -13,15 +15,16 @@ local _G = _G local CreateFrame = CreateFrame +ReAction:UpdateRevision("$Revision: 103 $") + -- module declaration local moduleID = "Action" local module = ReAction:NewModule( moduleID ) +-- Button class declaration +local Button = { } + -- private -- -local function GetBarConfig(bar) - return module.db.profile.bars[bar:GetName()] -end - local function RefreshLite(bar) local btns = module.buttons[bar] if btns then @@ -31,8 +34,7 @@ end end - --- module methods +-- Event handlers function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID, { @@ -44,21 +46,6 @@ ) self.buttons = { } - ReAction:RegisterOptions(self, { - [moduleID] = { - type = "group", - name = L["Action Bars"], - args = { - hideEmpty = { - type = "toggle", - name = L["Hide Empty Buttons"], - get = function() return self.db.profile.hideEmptyButtons end, - set = function(info, val) module:SetHideEmptyButtons(val) end, - } - } - } - }) - ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") ReAction.RegisterCallback(self, "OnCreateBar", "OnRefreshBar") @@ -108,11 +95,9 @@ btnCfg[i] = {} end if btns[i] == nil then - local ok, b = pcall(self.BtnClass.New, self.BtnClass, bar, i, btnCfg[i], barCfg) - if ok and b then - btns[i] = b - bar:AddButton(i,b) - end + local b = Button:New(bar, i, btnCfg[i], barCfg) + btns[i] = b + bar:AddButton(i,b) end end for i = n+1, #btns do @@ -153,77 +138,71 @@ b[newname], b[oldname] = b[oldname], nil end -function module:SetHideEmptyButtons(hide) - if hide ~= self.db.profile.hideEmptyButtons then - for _, bar in pairs(self.buttons) do - for _, b in pairs(bar) do - if hide then - ActionButton_HideGrid(b.frame) - else - ActionButton_ShowGrid(b.frame) - end - end - end - self.db.profile.hideEmptyButtons = hide - end -end - 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 - if mode then - ActionButton_ShowGrid(b.frame) - self:showActionIDLabel(b) - else - ActionButton_HideGrid(b.frame) - self:hideActionIDLabel(b) - end - end - end + for _, bar in pairs(self.buttons) do + for _, b in pairs(bar) do + b:ShowGrid(mode) + b:ShowActionIDLabel(mode) end end end -function module:showActionIDLabel(button) - if not button.actionIDLabel and button:GetActionID() then - local f = button:GetFrame() - local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") - label:SetAllPoints() - label:SetJustifyH("CENTER") - label:SetShadowColor(0,0,0,1) - label:SetShadowOffset(2,-2) - label:SetText(tostring(button:GetActionID())) - button.actionIDLabel = label - f:HookScript("OnAttributeChanged", - function(frame, attr, value) - if attr == "state-parent" then - label:SetText(tostring(button:GetActionID())) - end - end) - end - button.actionIDLabel:Show() -end - -function module:hideActionIDLabel(button) - if button.actionIDLabel then - button.actionIDLabel:Hide() - end -end - ---- Options ---- +local Handler = { } + +local options = { + hideEmpty = { + name = L["Hide Empty Buttons"], + desc = L["Hide buttons when empty. This option is not supported for multi-state bars"], + order = 1, + type = "toggle", + get = "GetHideEmpty", + set = "SetHideEmpty", + }, +} + function module:GetBarOptions(bar) return { type = "group", name = L["Action Buttons"], - hidden = function() return bar.config.type ~= moduleID end, - args = { - } + handler = Handler:New(bar), + hidden = "Hidden", + args = options } end +-- options handler private +do + local function GetBarConfig( bar ) + return module.db.profile.bars[bar:GetName()] + end + + function Handler:New(bar) + return setmetatable( { bar = bar }, { __index = Handler } ) + end + + function Handler:Hidden() + return self.bar.config.type ~= moduleID + end + + function Handler:SetHideEmpty(info, value) + local c = GetBarConfig(self.bar) + if value ~= c.hideEmpty then + for b in self.bar:IterateButtons() do + b:ShowGrid(not value) + end + c.hideEmpty = value + end + end + + function Handler:GetHideEmpty() + return GetBarConfig(self.bar).hideEmpty + end +end + + +------ Button class ------ -- use-count of action IDs local nActionIDs = 120 @@ -256,25 +235,17 @@ end }) - - - ------- Button class ------ -local Button = { } - -local function Constructor( self, bar, idx, config, barConfig ) +function Button:New( bar, idx, config, barConfig ) + -- create new self + self = setmetatable( { }, {__index = Button} ) self.bar, self.idx, self.config, self.barConfig = bar, idx, config, barConfig - local barFrame = bar:GetFrame() - config.name = config.name or ("ReAction_%s_%d"):format(bar:GetName(),idx) self.name = config.name config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured self.nPages = 1 - local f = CreateFrame("CheckButton", self.name, barFrame, "ActionBarButtonTemplate") - - -- TODO: re-implement ActionButton event handlers that don't do secure stuff + local f = CreateFrame("CheckButton", self.name, bar:GetButtonFrame(), "ActionBarButtonTemplate") -- this will probably cause taint and/or performance problems, using right now for display/debugging purposes f:SetScript("OnAttributeChanged", ActionButton_UpdateAction) @@ -285,19 +256,20 @@ f:SetAttribute("action-mc", 120 + self.idx) end - barFrame:SetAttribute("addchild",f) + self.frame = f + self.normalTexture = getglobal(format("%sNormalTexture",f:GetName())) - self.frame = f - self:Refresh() - - if not module.db.profile.hideEmptyButtons then - ActionButton_ShowGrid(self.frame) + -- initialize the hide state + self:ShowGrid(not barConfig.hideEmpty) + if ReAction:GetConfigMode() then + self:ShowGrid(true) end - if ReAction.configMode then - ActionButton_ShowGrid(self.frame) - module:showActionIDLabel(self) - end + -- show the ID label if applicable + self:ShowActionIDLabel(ReAction:GetConfigMode()) + + self:Refresh() + return self end function Button:Destroy() @@ -367,14 +339,52 @@ end end --- export as a class-factory to module -module.BtnClass = { - New = function(self, ...) - local x = { } - for k,v in pairs(Button) do - x[k] = v +function Button:ShowGrid( show ) + if not InCombatLockdown() then + -- new in 2.4.1: can't call ActionButton_ShowGrid/HideGrid because they won't update the attribute + local f = self.frame + local count = f:GetAttribute("showgrid") + if show then + count = count + 1 + else + count = count - 1 end - Constructor(x, ...) - return x + if count < 0 then + count = 0 + end + f:SetAttribute("showgrid",count) + + if count >= 1 and not f:GetAttribute("statehidden") then + self.normalTexture:SetVertexColor(1.0, 1.0, 1.0, 0.5); + f:Show() + elseif count < 1 and not HasAction(self:GetActionID()) then + f:Hide() + end end -} +end + +function Button:ShowActionIDLabel( show ) + if show then + local id = self:GetActionID() + if not self.actionIDLabel and id and id ~= 0 then + local f = self:GetFrame() + local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(2,-2) + label:SetText(tostring(id)) + self.actionIDLabel = label + f:HookScript("OnAttributeChanged", + function(frame, attr, value) + if attr == "state-parent" then + label:SetText(tostring(self:GetActionID())) + end + end) + end + self.actionIDLabel:Show() + elseif self.actionIDLabel then + self.actionIDLabel:Hide() + end +end +
--- a/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua Mon Jun 23 22:27:50 2008 +0000 @@ -11,6 +11,8 @@ local AceConfigReg = LibStub("AceConfigRegistry-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") +ReAction:UpdateRevision("$Revision: 103 $") + -- some constants local configName = "ReAction"
--- a/modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua Mon Jun 23 22:27:50 2008 +0000 @@ -10,6 +10,8 @@ local ReAction = ReAction local L = ReAction.L +ReAction:UpdateRevision("$Revision: 103 $") + -- module declaration local moduleID = "HideBlizzard" local module = ReAction:NewModule( moduleID )
--- a/modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/modules/ReAction_ModuleTemplate/ReAction_ModuleName.lua Mon Jun 23 22:27:50 2008 +0000 @@ -8,6 +8,8 @@ local L = ReAction.L local _G = _G +ReAction:UpdateRevision("$Revision: 103 $") + -- module declaration local moduleID = "MyModuleName" local module = ReAction:NewModule( moduleID,
--- a/modules/ReAction_PetAction/ReAction_PetAction.lua Thu Jun 19 17:48:57 2008 +0000 +++ b/modules/ReAction_PetAction/ReAction_PetAction.lua Mon Jun 23 22:27:50 2008 +0000 @@ -2,8 +2,7 @@ ReAction Pet Action button module The button module implements standard action button functionality by wrapping Blizzard's - PetActionButton frame and associated functions. It also provides some button layout - modification tools. + PetActionButton frame and associated functions. --]] @@ -13,10 +12,15 @@ local _G = _G local CreateFrame = CreateFrame +ReAction:UpdateRevision("$Revision: 103 $") + -- module declaration local moduleID = "PetAction" local module = ReAction:NewModule( moduleID ) +-- Button class declaration +local Button = { } + -- module methods function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID, @@ -81,18 +85,15 @@ btnCfg[i] = {} end if btns[i] == nil then - local ok, b = pcall(self.BtnClass.new, self.BtnClass, bar, i, btnCfg[i]) - if ok and b then - btns[i] = b - bar:AddButton(i,b) - end - else - btns[i]:Refresh(bar,i) + local b = Button:New(bar,i,btnCfg[i]) + btns[i] = b + bar:AddButton(i,b) end + btns[i]:Refresh() end for i = n+1, #btns do if btns[i] then - bar:RemoveButton(b) + bar:RemoveButton(btns[i]) btns[i] = btns[i]:Destroy() if btnCfg[i] then btnCfg[i] = nil @@ -125,17 +126,13 @@ function module:OnConfigModeChanged(event, mode) + for _, buttons in pairs(self.buttons) do + for _, b in pairs(buttons) do + b:ShowActionIDLabel(mode) + end + end for _, bar in ReAction:IterateBars() do if bar and self.buttons[bar] then - for _, b in pairs(self.buttons[bar]) do - if b then - if mode then - self:showActionIDLabel(b) - else - self:hideActionIDLabel(b) - end - end - end local f = bar:GetFrame() if mode then UnregisterUnitWatch(f) @@ -147,25 +144,6 @@ end end -function module:showActionIDLabel(button) - -- store the action ID label in the frame due to frame recycling - if not button:GetFrame().actionIDLabel and button:GetActionID() then - local label = button:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge") - label:SetAllPoints() - label:SetJustifyH("CENTER") - label:SetShadowColor(0,0,0,1) - label:SetShadowOffset(2,-2) - label:SetText(tostring(button:GetActionID())) - button:GetFrame().actionIDLabel = label - end - button:GetFrame().actionIDLabel:Show() -end - -function module:hideActionIDLabel(button) - if button:GetFrame().actionIDLabel then - button:GetFrame().actionIDLabel:Hide() - end -end ---- Options ---- function module:GetBarOptions(bar) @@ -180,6 +158,8 @@ +------ Button class ------ + -- use-count of action IDs local nActionIDs = NUM_PET_ACTION_SLOTS local ActionIDList = setmetatable( {}, { @@ -213,18 +193,14 @@ local frameRecycler = {} - ------- Button class ------ -local Button = { } - -local function Constructor( self, bar, idx, config ) +function Button:New( bar, idx, config ) + -- create new self + self = setmetatable( { }, { __index = Button } ) self.bar, self.idx, self.config = bar, idx, config - local barFrame = bar:GetFrame() - local name = config.name or ("ReAction_%s_Pet_%d"):format(bar:GetName(),idx) config.name = name - self.name = config.name + self.name = name config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured -- have to recycle frames with the same name: @@ -232,20 +208,17 @@ -- doesn't overwrite existing globals (below) -- or, if you set them to nil in the global table, you get taint because of the -- crappy PetActionBar code. + local parent = bar:GetButtonFrame() local f = frameRecycler[name] if f then - f:SetParent(barFrame) - f:Show() + f:SetParent(parent) else - f = CreateFrame("CheckButton", name, barFrame, "PetActionButtonTemplate") + f = CreateFrame("CheckButton", name, parent, "PetActionButtonTemplate") end if config.actionID then f:SetID(config.actionID) -- PetActionButtonTemplate isn't a proper SecureActionButton end f:SetFrameStrata("MEDIUM") - - barFrame:SetAttribute("addchild",f) - self.frame = f self.icon = _G[("%sIcon"):format(name)] self.acTex = _G[("%sAutoCastable"):format(name)] @@ -256,7 +229,7 @@ f:HookScript("OnDragStart", function() self:Update() end) f:HookScript("OnReceiveDrag", function() self:Update() end) - f:RegisterEvent("PLAYER_CONTROL_LOST"); + f:RegisterEvent("PLAYER_CONTROL_LOST"); f:RegisterEvent("PLAYER_CONTROL_GAINED"); f:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED"); f:RegisterEvent("UNIT_PET"); @@ -276,7 +249,8 @@ end end) - self:Refresh(bar,idx) + self:Refresh() + return self end function Button:Destroy() @@ -297,8 +271,8 @@ self.bar = nil end -function Button:Refresh(bar,idx) - bar:PlaceButton(self, 30, 30) +function Button:Refresh() + self.bar:PlaceButton(self, 30, 30) self:Update() self:UpdateHotkey() end @@ -370,14 +344,20 @@ end --- export as a class-factory to module -module.BtnClass = { - new = function(self, ...) - local x = { } - for k,v in pairs(Button) do - x[k] = v +function Button:ShowActionIDLabel(show) + if show then + -- store the action ID label in the frame due to frame recycling + if not self.actionIDLabel and self:GetActionID() then + local label = self.frame:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(2,-2) + label:SetText(tostring(self:GetActionID())) + self.actionIDLabel = label end - Constructor(x, ...) - return x + self.actionIDLabel:Show() + elseif self.actionIDLabel then + self.actionIDLabel:Hide() end -} +end