Mercurial > wow > reaction
view modules/ReAction_PossessBar/ReAction_PossessBar.lua @ 59:7430a8dd4e90
Added modular per-bar options
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Mon, 28 Apr 2008 23:34:17 +0000 |
parents | b85118b61564 |
children | 44649a10378d |
line wrap: on
line source
--[[ ReAction Possess Bar (Mind Control/etc) button module. Wraps the standard Action buttons 121-132 with an automatic show/hide when mind control (etc) is active --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local CreateFrame = CreateFrame -- module declaration local moduleID = "PossessBar" local module = ReAction:NewModule( moduleID ) -- module methods function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID, { profile = { buttons = { } } } ) self.buttons = { } ReAction:RegisterOptions("global", self, { hideEmptyPossess = { type = "toggle", name = L["Hide Empty Possess Bar Buttons"], get = function() return self.db.profile.hideEmptyButtons end, set = function(info, val) module:SetHideEmptyButtons(val) end, } }) ReAction:RegisterOptions("bar", self, { type = "group", name = L["Possess Buttons"], hidden = "BarOptionsHidden", args = { } }) end function module:OnEnable() ReAction:RegisterBarType(L["Possess Bar"], { type = moduleID, defaultButtonSize = 36, defaultBarRows = 1, defaultBarCols = 12, defaultBarSpacing = 3 }) end function module:OnDisable() ReAction:UnregisterBarType(L["Possess Bar"]) end function module:ApplyToBar(bar) if bar.config.type == moduleID then bar:GetFrame():SetParent(PossessBarFrame) bar.config.parent = "PossessBarFrame" self:CreatePossessControlButtons(bar) end self:RefreshBar(bar) end function module:RefreshBar(bar) 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] = {} end local btnCfg = profile.buttons[barName] local r, c = bar:GetButtonGrid() local n = r*c for i = 1, n do if btnCfg[i] == nil then 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 end else btns[i]:Refresh(bar,i) end end for i = n+1, #btns do if btns[i] then btns[i] = btns[i]:Destroy() if btnCfg[i] then btnCfg[i] = nil end end end end end function module:RemoveFromBar(bar) if self.buttons[bar] then local btns = self.buttons[bar] for _,b in pairs(btns) do if b then b:Destroy() end end self.buttons[bar] = nil end end function module:EraseBarConfig(barName) self.db.profile.buttons[barName] = nil end function module:RenameBarConfig(oldname, newname) local b = self.db.profile.buttons 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:ApplyConfigMode(mode,bars) for _, bar in pairs(bars) 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 local f = bar:GetFrame() if mode then f:SetParent(UIParent) f:Show() else f:SetParent(PossessBarFrame) end end end end function module:showActionIDLabel(button) if not button.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.actionIDLabel = label end button.actionIDLabel:Show() end function module:hideActionIDLabel(button) if button.actionIDLabel then button.actionIDLabel:Hide() end end -- possess-bar control buttons (shows buff, cancel buff) function module:CreatePossessControlButton(bar,id,name) -- guard against taint by reusing global variable frames -- instead of nilling them out (e.g. create bar, delete bar, create bar with same name) name = name or ("ReAction_%s_PossessCtrlButton%d"):format(bar:GetName(),id) local b = name and _G[name] if b then b:SetParent(bar:GetFrame()) else b = CreateFrame("CheckButton", name, bar:GetFrame(), "PossessButtonTemplate") end b:SetID(id) b:RegisterEvent("PLAYER_AURAS_CHANGED"); local icon = _G[("%sIcon"):format(name)] local cooldown = _G[("%sCooldown"):format(name)] local nTex = _G[("%sNormalTexture"):format(name)] nTex:SetWidth(54) nTex:SetHeight(54) local function update() local texture = GetPossessInfo(id); icon:SetTexture(texture); icon:Show() cooldown:Hide(); b:SetChecked(0); icon:SetVertexColor(1.0, 1.0, 1.0); end update() b:HookScript("OnClick", function() b:SetChecked(0) end) b:SetScript("OnEvent", update) b:SetScript("OnShow", update) return b end function module:CreatePossessControlButtons(bar) if not bar.possessButtons then bar.possessButtons = { } bar.config.possessFrameNames = bar.config.possessFrameNames or { } local previous local n = NUM_POSSESS_SLOTS for i = 1, n do local name = bar.config.possessFrameNames[i] local f = self:CreatePossessControlButton(bar,i,name) bar.possessButtons[i] = f bar.config.possessFrameNames[i] = f:GetName() local r, c, s = bar:GetButtonGrid() local w, h = bar:GetButtonSize() local scale = ((h - (n-1)*s)/n)/30 f:SetScale(scale) if previous then f:SetPoint("TOP", previous, "BOTTOM", 0, -s/scale) else f:SetPoint("TOPRIGHT", bar:GetFrame(), "TOPLEFT", -s/scale, 0) end f:Show() previous = f end end end ---- Options handlers ---- function module:BarOptionsHidden(bar) return bar.config.type ~= moduleID end -- use-count of action IDs local minActionID = 121 local maxActionID = 132 local ActionIDList = setmetatable( {}, { __index = function(self, idx) if idx == nil then for i = minActionID, maxActionID do if rawget(self,i) == nil then rawset(self,i,1) return i end end error("ran out of action IDs") else local c = rawget(self,idx) or 0 rawset(self,idx,c+1) return idx end end, __newindex = function(self,idx,value) if value == nil then value = rawget(self,idx) if value == 1 then value = nil elseif value then value = value - 1 end end rawset(self,idx,value) end }) ------ Button class ------ local Button = { } local function Constructor( self, bar, idx, config ) self.bar, self.idx, self.config = bar, idx, config local barFrame = bar:GetFrame() config.name = config.name or ("ReAction_%s_Possess_%d"):format(bar:GetName(),idx) self.name = config.name config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured local f = CreateFrame("CheckButton", self.name, barFrame, "BonusActionButtonTemplate") -- TODO: re-implement ActionButton event handlers that don't do secure stuff -- this will probably cause taint, using right now for display/debugging purposes f:SetScript("OnAttributeChanged", ActionButton_UpdateAction) f:SetAttribute("action", config.actionID) barFrame:SetAttribute("addchild",f) self.frame = f self:Refresh(bar,idx) if not module.db.profile.hideEmptyButtons then ActionButton_ShowGrid(self.frame) end if ReAction.configMode then ActionButton_ShowGrid(self.frame) module:showActionIDLabel(self) end end function Button:Destroy() local f = self.frame f:UnregisterAllEvents() f:Hide() f:SetParent(UIParent) f:ClearAllPoints() if self.name then _G[self.name] = nil end if self.config.actionID then ActionIDList[self.config.actionID] = nil end self.frame = nil self.config = nil self.bar = nil end function Button:Refresh(bar,idx) bar:PlaceButton(self.frame, idx, 36, 36) end function Button:GetFrame() return self.frame end function Button:GetName() return self.name end function Button:GetActionID() return self.config.actionID 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 end Constructor(x, ...) return x end }