Mercurial > wow > reaction
view modules/ReAction_PetAction/ReAction_PetAction.lua @ 80:42ec2938d65a
- Added Revision keyword on all .lua files (except ReAction_Action, which is under dev)
- Removed ReAction_Paging module stub
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 24 Jun 2008 23:47:27 +0000 |
parents | da8ba8783924 |
children | 913857b7e123 |
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. --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local CreateFrame = CreateFrame ReAction:UpdateRevision("$Revision$") -- 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, { 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 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(btns[i]) 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 _, 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 local f = bar:GetFrame() if mode then UnregisterUnitWatch(f) f:Show() else RegisterUnitWatch(f) end end end end ---- Options ---- function module:GetBarOptions(bar) return { type = "group", name = L["Pet Buttons"], hidden = function() return bar.config.type ~= moduleID end, args = { } } end ------ Button class ------ -- 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 = {} function Button:New( bar, idx, config ) -- create new self self = setmetatable( { }, { __index = Button } ) self.bar, self.idx, self.config = bar, idx, config local name = config.name or ("ReAction_%s_Pet_%d"):format(bar:GetName(),idx) config.name = name self.name = 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 parent = bar:GetButtonFrame() local f = frameRecycler[name] if f then f:SetParent(parent) else 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") 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() return self 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() self.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 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 self.actionIDLabel:Show() elseif self.actionIDLabel then self.actionIDLabel:Hide() end end