Mercurial > wow > reaction
view modules/ReAction_PetAction/ReAction_PetAction.lua @ 75:06cd74bdc7da
- Cleaned up Bar interface
- Move all attribute setting from Bar into State
- Separated Moonkin and Tree of Life
- Removed PossessBar module
- Added some infrastructure for paged/mind control support to Action
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Mon, 16 Jun 2008 18:46:08 +0000 |
parents | 768be7eb22a0 |
children | da8ba8783924 |
line wrap: on
line source
--[[ 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. --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local CreateFrame = CreateFrame -- module declaration local moduleID = "PetAction" local module = ReAction:NewModule( moduleID ) -- module methods function module:OnInitialize() self.db = ReAction.db:RegisterNamespace( moduleID, { profile = { buttons = { } } } ) self.buttons = { } 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() ReAction:RegisterBarType(L["Pet Action Bar"], { type = moduleID , defaultButtonSize = 30, defaultBarRows = 1, defaultBarCols = 10, defaultBarSpacing = 8 }) end function module:OnDisable() ReAction:UnregisterBarType(L["Pet Action Bar"]) end 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:OnRefreshBar(event, bar, name) end end 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 if profile.buttons[name] == nil then profile.buttons[name] = {} end local btnCfg = profile.buttons[name] 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 bar:AddButton(i,b) end else btns[i]:Refresh(bar,i) end end for i = n+1, #btns do if btns[i] then bar:RemoveButton(b) btns[i] = btns[i]:Destroy() if btnCfg[i] then btnCfg[i] = nil end end end end end function module:OnDestroyBar(event, bar, name) 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:OnEraseBar(event, bar, name) self.db.profile.buttons[name] = nil end function module:OnRenameBar(event, bar, oldname, newname) local b = self.db.profile.buttons b[newname], b[oldname] = b[oldname], nil 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 self:showActionIDLabel(b) else self:hideActionIDLabel(b) end end end local f = bar:GetFrame() if mode then UnregisterUnitWatch(f) f:Show() else RegisterUnitWatch(f) end end 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) return { type = "group", name = L["Pet Buttons"], hidden = function() return bar.config.type ~= moduleID end, args = { } } end -- use-count of action IDs local nActionIDs = NUM_PET_ACTION_SLOTS local ActionIDList = setmetatable( {}, { __index = function(self, idx) if idx == nil then for i = 1, nActionIDs do if rawget(self,i) == nil then rawset(self,i,1) return i end end error("ran out of pet 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 }) local frameRecycler = {} ------ Button class ------ local Button = { } local function Constructor( self, bar, idx, config ) 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 config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured -- have to recycle frames with the same name: -- otherwise you either get references to old textures because named CreateFrame() -- 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 f = frameRecycler[name] if f then f:SetParent(barFrame) f:Show() else f = CreateFrame("CheckButton", name, barFrame, "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)] self.acModel = _G[("%sAutoCast"):format(name)] self.cooldown = _G[("%sCooldown"):format(name)] self.hotkey = _G[("%sHotKey"):format(name)] f:HookScript("OnDragStart", function() self:Update() end) f:HookScript("OnReceiveDrag", function() self:Update() end) f:RegisterEvent("PLAYER_CONTROL_LOST"); f:RegisterEvent("PLAYER_CONTROL_GAINED"); f:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED"); f:RegisterEvent("UNIT_PET"); f:RegisterEvent("UNIT_FLAGS"); f:RegisterEvent("UNIT_AURA"); f:RegisterEvent("PET_BAR_UPDATE"); f:RegisterEvent("PET_BAR_UPDATE_COOLDOWN"); f:SetScript("OnEvent", function(event,arg1) if event =="PET_BAR_UPDATE_COOLDOWN" then self:UpdateCooldown() elseif event == "UPDATE_BINDINGS" then self:UpdateHotkey() else self:Update() end end) self:Refresh(bar,idx) end function Button:Destroy() local f = self.frame f:UnregisterAllEvents() f:Hide() f:SetParent(UIParent) f:ClearAllPoints() if self.name then frameRecycler[self.name] = f _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, 30, 30) self:Update() self:UpdateHotkey() end function Button:GetFrame() return self.frame end function Button:GetName() return self.name end function Button:GetActionID() return self.config.actionID end function Button:Update() local id = self.frame:GetID() local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(id); local f = self.frame --ReAction:Print(("id %d: '%s', '%s', '%s', '%s', '%s', '%s', '%s'"):format(tostring(id), tostring(name),tostring(subtext),tostring(texture),tostring(isToken),tostring(isActive),tostring(autoCastAllowed),tostring(autoCastEnabled))) if isToken then self.icon:SetTexture(_G[texture]); f.tooltipName = _G[name]; else self.icon:SetTexture(texture); f.tooltipName = name; end f.isToken = isToken; f.tooltipSubtext = subtext; f:SetChecked( isActive and 1 or 0); if autoCastAllowed then self.acTex:Show(); else self.acTex:Hide(); end if autoCastEnabled then self.acModel:Show(); else self.acModel:Hide(); end if texture then if GetPetActionsUsable() then SetDesaturation(self.icon,nil) else SetDesaturation(self.icon,1) end self.icon:Show(); f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2"); else self.icon:Hide(); f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot"); end self:UpdateCooldown() end function Button:UpdateCooldown() local start, duration, enable = GetPetActionCooldown(self.frame:GetID()); CooldownFrame_SetTimer(self.cooldown, start, duration, enable); end function Button:UpdateHotkey() 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 }