annotate PetActionButton.lua @ 292:276165a0e860 1.1 beta 10

Don't stash CooldownFrame_SetTimer, to support mods such as 'Cooldowns' which hook it in an event handler.
author Flick
date Fri, 05 Aug 2011 16:25:41 -0700
parents 499ca4edf033
children f7a5676c9517
rev   line source
Flick@276 1 local _, ns = ...
Flick@276 2 local ReAction = ns.ReAction
flickerstreak@130 3 local L = ReAction.L
flickerstreak@130 4 local _G = _G
flickerstreak@130 5 local CreateFrame = CreateFrame
flickerstreak@130 6 local format = string.format
flickerstreak@130 7 local GetCVar = GetCVar
flickerstreak@130 8 local InCombatLockdown = InCombatLockdown
flickerstreak@130 9 local GetPetActionInfo = GetPetActionInfo
flickerstreak@130 10 local GetPetActionSlotUsable = GetPetActionSlotUsable
flickerstreak@130 11 local GetPetActionCooldown = GetPetActionCooldown
flickerstreak@130 12 local AutoCastShine_AutoCastStart = AutoCastShine_AutoCastStart
flickerstreak@130 13 local AutoCastShine_AutoCastStop = AutoCastShine_AutoCastStop
flickerstreak@130 14 local SetDesaturation = SetDesaturation
Flick@292 15 -- local CooldownFrame_SetTimer = CooldownFrame_SetTimer -- don't stash this API, look it up every time to support some mods that hook it, e.g. Cooldowns
flickerstreak@130 16 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor
flickerstreak@130 17
flickerstreak@130 18 --
flickerstreak@130 19 -- Secure snippets
flickerstreak@130 20 -- These are run within the context of the bar's sandbox, as the
flickerstreak@130 21 -- buttons themselves do not have their own sandbox.
flickerstreak@130 22 --
flickerstreak@130 23 local _onDragStart = -- function(self, button, kind, value, ...)
flickerstreak@130 24 [[
flickerstreak@130 25 if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then
flickerstreak@130 26 return kind, value, ...
flickerstreak@130 27 else
flickerstreak@130 28 return "petaction", self:GetAttribute("action")
flickerstreak@130 29 end
flickerstreak@130 30 ]]
flickerstreak@130 31
flickerstreak@130 32 local _onReceiveDrag = -- function(self, button, kind, value, ...)
flickerstreak@130 33 [[
Flick@284 34 if kind == "petaction" then
Flick@284 35 return "petaction", self:GetAttribute("action")
Flick@284 36 else
flickerstreak@130 37 return kind, value, ...
flickerstreak@130 38 end
flickerstreak@130 39 ]]
flickerstreak@130 40
flickerstreak@130 41 --
flickerstreak@130 42 -- private
flickerstreak@130 43 --
flickerstreak@130 44 local eventList = {
flickerstreak@130 45 "PLAYER_CONTROL_LOST",
flickerstreak@130 46 "PLAYER_CONTROL_GAINED",
flickerstreak@130 47 "PLAYER_FARSIGHT_FOCUS_CHANGED",
flickerstreak@130 48 "UNIT_PET",
flickerstreak@130 49 "UNIT_FLAGS",
flickerstreak@130 50 "UNIT_AURA",
flickerstreak@130 51 "PET_BAR_UPDATE",
flickerstreak@130 52 "PET_BAR_UPDATE_COOLDOWN",
flickerstreak@165 53 "PET_BAR_UPDATE_USABLE",
flickerstreak@130 54 "UPDATE_BINDINGS",
flickerstreak@130 55 }
flickerstreak@130 56
flickerstreak@130 57 --
flickerstreak@130 58 -- Pet Action Button class
flickerstreak@130 59 --
flickerstreak@218 60 local buttonTypeID = "PetAction"
flickerstreak@130 61 local Super = ReAction.Button
flickerstreak@218 62 local Pet = setmetatable(
flickerstreak@218 63 {
flickerstreak@218 64 defaultBarConfig = {
flickerstreak@218 65 type = buttonTypeID,
flickerstreak@218 66 btnWidth = 30,
flickerstreak@218 67 btnHeight = 30,
flickerstreak@218 68 btnRows = 1,
flickerstreak@218 69 btnColumns = 10,
flickerstreak@222 70 spacing = 8,
flickerstreak@222 71 buttons = { }
flickerstreak@218 72 },
flickerstreak@218 73
flickerstreak@218 74 barType = L["Pet Action Bar"],
Flick@231 75 buttonTypeID = buttonTypeID
flickerstreak@218 76 },
flickerstreak@218 77 { __index = Super } )
flickerstreak@223 78
flickerstreak@130 79 ReAction.Button.PetAction = Pet
flickerstreak@223 80 ReAction:RegisterBarType(Pet)
flickerstreak@130 81
Flick@234 82 function Pet:New( config, bar, idx, idHint )
Flick@277 83 self = Super.New(self, config, bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" )
flickerstreak@130 84
Flick@280 85 local name = self:GetFrame():GetName()
Flick@278 86
flickerstreak@130 87 local f = self:GetFrame()
flickerstreak@130 88 if not f.autoCastTexture then
flickerstreak@131 89 -- store autocast stuff with the frame for recycling
flickerstreak@130 90 local tex = f:CreateTexture(nil,"OVERLAY")
flickerstreak@130 91 tex:SetTexture([[Interface\Buttons\UI-AutoCastableOverlay]])
flickerstreak@130 92 tex:SetHeight(58)
flickerstreak@130 93 tex:SetWidth(58)
flickerstreak@130 94 tex:SetPoint("CENTER")
flickerstreak@130 95 f.autoCastTexture = tex
flickerstreak@158 96 f.autoCastShine = CreateFrame("Frame",name.."Shine",f,"AutoCastShineTemplate") -- create after autocast texture so it's on top
flickerstreak@131 97 -- move the cooldown around
flickerstreak@131 98 local cd = self.frames.cooldown
flickerstreak@131 99 cd:ClearAllPoints()
flickerstreak@131 100 cd:SetWidth(33)
flickerstreak@131 101 cd:SetHeight(33)
flickerstreak@131 102 cd:SetPoint("CENTER", f, "CENTER", -2, -1)
flickerstreak@131 103 -- resize to 30x30
flickerstreak@131 104 f:SetHeight(30)
flickerstreak@131 105 f:SetWidth(30)
flickerstreak@142 106 local nt = _G[name.."NormalTexture"]
flickerstreak@142 107 nt:SetHeight(54)
flickerstreak@142 108 nt:SetWidth(54)
flickerstreak@130 109 end
flickerstreak@130 110 local barFrame = bar:GetFrame()
flickerstreak@130 111
flickerstreak@130 112 -- set up the base action ID
flickerstreak@130 113 self:SetActionIDPool("pet",10)
flickerstreak@130 114 config.actionID = self:AcquireActionID(config.actionID, idHint, true)
flickerstreak@130 115
flickerstreak@130 116 -- attribute setup
flickerstreak@131 117 -- There's no secure way to do PetAutoCastToggle by actionID, so use
flickerstreak@131 118 -- a click-through proxy to the Blizzard pet buttons for right-click
flickerstreak@131 119 -- Note that technically this doesn't do PetStopAttack() when
flickerstreak@131 120 -- IsPetAttackActive() is true: however that's only true when using
flickerstreak@131 121 -- Eyes of the Beast and appears not to really do anything (at least
flickerstreak@131 122 -- I can't find any difference)
flickerstreak@130 123 f:SetAttribute("type","pet")
flickerstreak@130 124 f:SetAttribute("type2","click")
flickerstreak@130 125 f:SetAttribute("clickbutton2",_G["PetActionButton"..config.actionID])
flickerstreak@130 126 f:SetAttribute("action",config.actionID)
flickerstreak@130 127 f:SetAttribute("checkselfcast", true)
flickerstreak@130 128 f:SetAttribute("checkfocuscast", true)
flickerstreak@130 129
flickerstreak@130 130 -- non secure scripts
flickerstreak@130 131 f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end)
flickerstreak@130 132 f:SetScript("OnEnter", function(frame) self:OnEnter() end)
flickerstreak@130 133 f:SetScript("OnLeave", function(frame) self:OnLeave() end)
flickerstreak@130 134 f:SetScript("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end)
flickerstreak@130 135 f:SetScript("PreClick", function(frame) self:PreClick() end)
flickerstreak@130 136 f:SetScript("OnDragStart", function(frame) self:OnDragStart() end)
flickerstreak@130 137 f:SetScript("OnReceiveDrag", function(frame) self:OnReceiveDrag() end)
flickerstreak@130 138
flickerstreak@130 139 -- secure handlers
flickerstreak@130 140 barFrame:WrapScript(f, "OnDragStart", _onDragStart)
flickerstreak@130 141 barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag)
flickerstreak@130 142
flickerstreak@130 143 -- event registration
flickerstreak@130 144 f:RegisterForDrag("LeftButton", "RightButton")
flickerstreak@130 145 for _, evt in pairs(eventList) do
flickerstreak@130 146 f:RegisterEvent(evt)
flickerstreak@130 147 end
flickerstreak@130 148
flickerstreak@130 149 -- attach to skinner
flickerstreak@130 150 bar:SkinButton(self,
flickerstreak@130 151 {
flickerstreak@130 152 AutoCast = f.autoCastShine,
flickerstreak@130 153 AutoCastable = f.autoCastTexture
flickerstreak@130 154 })
flickerstreak@130 155
flickerstreak@130 156 self:Refresh()
flickerstreak@130 157 f:Show()
flickerstreak@130 158
flickerstreak@130 159 return self
flickerstreak@130 160 end
flickerstreak@130 161
Flick@234 162 function Pet:SetupBar(bar)
Flick@234 163 Super.SetupBar(self,bar)
Flick@234 164
Flick@234 165 -- auto show/hide when pet exists
Flick@279 166 bar:RegisterUnitWatch("pet",not ReAction:GetConfigMode())
Flick@234 167
Flick@234 168 self:UpdateButtonLock(bar)
Flick@234 169 end
Flick@234 170
Flick@234 171 function Pet:UpdateButtonLock(bar)
Flick@234 172 local f = bar:GetFrame()
Flick@234 173 f:SetAttribute("lockbuttons",bar.config.lockButtons)
Flick@234 174 f:SetAttribute("lockbuttonscombat",bar.config.lockButtonsCombat)
Flick@234 175 f:Execute(
Flick@234 176 [[
Flick@234 177 lockButtons = self:GetAttribute("lockbuttons")
Flick@234 178 lockButtonsCombat = self:GetAttribute("lockbuttonscombat")
Flick@234 179 ]])
Flick@234 180 end
Flick@234 181
flickerstreak@130 182 function Pet:Refresh()
flickerstreak@130 183 Super.Refresh(self)
flickerstreak@130 184 self:Update()
flickerstreak@130 185 self:UpdateHotkey()
flickerstreak@130 186 end
flickerstreak@130 187
flickerstreak@130 188 function Pet:GetActionID()
flickerstreak@130 189 return self.config.actionID
flickerstreak@130 190 end
flickerstreak@130 191
flickerstreak@130 192 function Pet:SetActionID(id)
flickerstreak@130 193 if not InCombatLockdown() then
flickerstreak@130 194 if id < 0 or id > 10 then
flickerstreak@130 195 ReAction:UserError(L["Pet action ID range is 1-10"])
flickerstreak@130 196 return
flickerstreak@130 197 end
flickerstreak@130 198 self.config.actionID = id
flickerstreak@130 199 f:SetAttribute("clickbutton2",_G["PetActionButton"..id])
flickerstreak@130 200 f:SetAttribute("action",id)
flickerstreak@130 201 self:Update()
flickerstreak@130 202 self:UpdateHotkey()
flickerstreak@130 203 end
flickerstreak@130 204 end
flickerstreak@130 205
flickerstreak@130 206 function Pet:Update()
flickerstreak@130 207 local action = self.config.actionID
flickerstreak@130 208 local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(action)
flickerstreak@130 209 local f = self:GetFrame()
flickerstreak@130 210 local icon = self.frames.icon
flickerstreak@130 211
flickerstreak@130 212 if isToken then
flickerstreak@130 213 icon:SetTexture(_G[texture])
flickerstreak@130 214 self.tooltipName = _G[name]
flickerstreak@130 215 else
flickerstreak@130 216 icon:SetTexture(texture)
flickerstreak@130 217 self.tooltipName = name
flickerstreak@130 218 end
flickerstreak@130 219
flickerstreak@130 220 self.isToken = isToken
flickerstreak@130 221 self.tooltipSubtext = subtext
flickerstreak@130 222 f:SetChecked( isActive and 1 or 0 )
flickerstreak@130 223
flickerstreak@130 224 if autoCastAllowed then
flickerstreak@130 225 f.autoCastTexture:Show()
flickerstreak@130 226 else
flickerstreak@130 227 f.autoCastTexture:Hide()
flickerstreak@130 228 end
flickerstreak@130 229
flickerstreak@130 230 if autoCastEnabled then
flickerstreak@130 231 AutoCastShine_AutoCastStart(f.autoCastShine)
flickerstreak@130 232 else
flickerstreak@130 233 AutoCastShine_AutoCastStop(f.autoCastShine)
flickerstreak@130 234 end
flickerstreak@130 235
flickerstreak@130 236 if texture then
flickerstreak@130 237 if GetPetActionSlotUsable(action) then
flickerstreak@130 238 SetDesaturation(icon,nil)
flickerstreak@130 239 else
flickerstreak@130 240 SetDesaturation(icon,1)
flickerstreak@130 241 end
flickerstreak@130 242 icon:Show()
flickerstreak@130 243 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
flickerstreak@130 244 else
flickerstreak@130 245 icon:Hide()
flickerstreak@130 246 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
flickerstreak@130 247 end
flickerstreak@130 248
flickerstreak@130 249 self:UpdateCooldown()
flickerstreak@130 250 end
flickerstreak@130 251
flickerstreak@130 252 function Pet:UpdateCooldown()
flickerstreak@130 253 CooldownFrame_SetTimer(self.frames.cooldown, GetPetActionCooldown(self.config.actionID))
flickerstreak@130 254 end
flickerstreak@130 255
flickerstreak@130 256 function Pet:SetTooltip()
flickerstreak@130 257 if self.tooltipName then
flickerstreak@130 258 local f = self:GetFrame()
flickerstreak@130 259 local uber = GetCVar("UberTooltips")
flickerstreak@130 260 if self.isToken or (uber == "0") then
flickerstreak@130 261 if uber == "0" then
flickerstreak@130 262 GameTooltip:SetOwner(f, "ANCHOR_RIGHT")
flickerstreak@130 263 else
flickerstreak@130 264 GameTooltip_SetDefaultAnchor(GameTooltip, f)
flickerstreak@130 265 end
flickerstreak@130 266 GameTooltip:SetText(self.tooltipName)
flickerstreak@130 267 if self.tooltipSubtext then
flickerstreak@130 268 GameTooltip:AddLine(self.tooltipSubtext, "", 0.5, 0.5, 0.5)
flickerstreak@130 269 end
flickerstreak@130 270 GameTooltip:Show()
flickerstreak@130 271 else
flickerstreak@130 272 GameTooltip_SetDefaultAnchor(GameTooltip, f)
flickerstreak@130 273 GameTooltip:SetPetAction(self.config.actionID)
flickerstreak@130 274 end
flickerstreak@130 275 else
flickerstreak@130 276 GameTooltip:Hide()
flickerstreak@130 277 end
flickerstreak@130 278 end
flickerstreak@130 279
flickerstreak@130 280 function Pet:OnEvent(event, unit)
flickerstreak@130 281 if event =="PET_BAR_UPDATE_COOLDOWN" then
flickerstreak@130 282 self:UpdateCooldown()
flickerstreak@130 283 elseif event == "UPDATE_BINDINGS" then
flickerstreak@130 284 self:UpdateHotkey()
flickerstreak@130 285 elseif event == "UNIT_PET" then
flickerstreak@130 286 if unit == "player" then
flickerstreak@130 287 self:Update()
flickerstreak@130 288 end
flickerstreak@130 289 elseif event == "UNIT_FLAGS" or event == "UNIT_AURA" then
flickerstreak@130 290 if unit == "pet" then
flickerstreak@130 291 self:Update()
flickerstreak@130 292 end
flickerstreak@130 293 else
flickerstreak@130 294 self:Update()
flickerstreak@130 295 end
flickerstreak@130 296 end
flickerstreak@130 297
flickerstreak@130 298 function Pet:OnEnter()
flickerstreak@130 299 self:SetTooltip()
flickerstreak@130 300 end
flickerstreak@130 301
flickerstreak@130 302 function Pet:OnLeave()
flickerstreak@130 303 GameTooltip:Hide()
flickerstreak@130 304 end
flickerstreak@130 305
flickerstreak@130 306 function Pet:OnAttributeChanged(attr,value)
flickerstreak@130 307 self:Update()
flickerstreak@130 308 end
flickerstreak@130 309
flickerstreak@130 310 function Pet:PreClick()
flickerstreak@130 311 self:GetFrame():SetChecked(0)
flickerstreak@130 312 end
flickerstreak@130 313
flickerstreak@130 314 function Pet:OnDragStart()
flickerstreak@130 315 self:SetChecked(0)
flickerstreak@130 316 self:Update()
flickerstreak@130 317 end
flickerstreak@130 318
flickerstreak@130 319 function Pet:OnReceiveDrag()
flickerstreak@130 320 self:SetChecked(0)
flickerstreak@130 321 self:Update()
flickerstreak@130 322 end
flickerstreak@130 323