annotate 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
rev   line source
flickerstreak@28 1 --[[
flickerstreak@53 2 ReAction Pet Action button module
flickerstreak@53 3
flickerstreak@53 4 The button module implements standard action button functionality by wrapping Blizzard's
flickerstreak@53 5 PetActionButton frame and associated functions. It also provides some button layout
flickerstreak@53 6 modification tools.
flickerstreak@28 7
flickerstreak@28 8 --]]
flickerstreak@28 9
flickerstreak@28 10 -- local imports
flickerstreak@28 11 local ReAction = ReAction
flickerstreak@28 12 local L = ReAction.L
flickerstreak@28 13 local _G = _G
flickerstreak@53 14 local CreateFrame = CreateFrame
flickerstreak@28 15
flickerstreak@28 16 -- module declaration
flickerstreak@28 17 local moduleID = "PetAction"
flickerstreak@28 18 local module = ReAction:NewModule( moduleID )
flickerstreak@28 19
flickerstreak@28 20 -- module methods
flickerstreak@28 21 function module:OnInitialize()
flickerstreak@53 22 self.db = ReAction.db:RegisterNamespace( moduleID,
flickerstreak@28 23 {
flickerstreak@28 24 profile = {
flickerstreak@28 25 buttons = { }
flickerstreak@28 26 }
flickerstreak@28 27 }
flickerstreak@28 28 )
flickerstreak@53 29 self.buttons = { }
flickerstreak@63 30
flickerstreak@63 31 ReAction:RegisterBarOptionGenerator(self, "GetBarOptions")
flickerstreak@63 32
flickerstreak@63 33 ReAction.RegisterCallback(self, "OnCreateBar")
flickerstreak@63 34 ReAction.RegisterCallback(self, "OnDestroyBar")
flickerstreak@63 35 ReAction.RegisterCallback(self, "OnRefreshBar")
flickerstreak@63 36 ReAction.RegisterCallback(self, "OnEraseBar")
flickerstreak@63 37 ReAction.RegisterCallback(self, "OnRenameBar")
flickerstreak@63 38 ReAction.RegisterCallback(self, "OnConfigModeChanged")
flickerstreak@28 39 end
flickerstreak@28 40
flickerstreak@28 41 function module:OnEnable()
flickerstreak@53 42 ReAction:RegisterBarType(L["Pet Action Bar"],
flickerstreak@53 43 {
flickerstreak@53 44 type = moduleID ,
flickerstreak@53 45 defaultButtonSize = 30,
flickerstreak@53 46 defaultBarRows = 1,
flickerstreak@53 47 defaultBarCols = 10,
flickerstreak@53 48 defaultBarSpacing = 8
flickerstreak@53 49 })
flickerstreak@28 50 end
flickerstreak@28 51
flickerstreak@28 52 function module:OnDisable()
flickerstreak@53 53 ReAction:UnregisterBarType(L["Pet Action Bar"])
flickerstreak@28 54 end
flickerstreak@28 55
flickerstreak@63 56 function module:OnCreateBar(event, bar, name)
flickerstreak@53 57 if bar.config.type == moduleID then
flickerstreak@53 58 -- auto show/hide when pet exists
flickerstreak@53 59 bar:GetFrame():SetAttribute("unit","pet")
flickerstreak@53 60 RegisterUnitWatch(bar:GetFrame())
flickerstreak@63 61 self:OnRefreshBar(event, bar, name)
flickerstreak@28 62 end
flickerstreak@28 63 end
flickerstreak@28 64
flickerstreak@63 65 function module:OnRefreshBar(event, bar, name)
flickerstreak@53 66 if bar.config.type == moduleID then
flickerstreak@53 67 if self.buttons[bar] == nil then
flickerstreak@53 68 self.buttons[bar] = { }
flickerstreak@53 69 end
flickerstreak@53 70 local btns = self.buttons[bar]
flickerstreak@53 71 local profile = self.db.profile
flickerstreak@63 72 if profile.buttons[name] == nil then
flickerstreak@63 73 profile.buttons[name] = {}
flickerstreak@53 74 end
flickerstreak@63 75 local btnCfg = profile.buttons[name]
flickerstreak@53 76
flickerstreak@53 77 local r, c = bar:GetButtonGrid()
flickerstreak@53 78 local n = r*c
flickerstreak@53 79 for i = 1, n do
flickerstreak@53 80 if btnCfg[i] == nil then
flickerstreak@53 81 btnCfg[i] = {}
flickerstreak@53 82 end
flickerstreak@53 83 if btns[i] == nil then
flickerstreak@53 84 local ok, b = pcall(self.BtnClass.new, self.BtnClass, bar, i, btnCfg[i])
flickerstreak@53 85 if ok and b then
flickerstreak@53 86 btns[i] = b
flickerstreak@75 87 bar:AddButton(i,b)
flickerstreak@53 88 end
flickerstreak@53 89 else
flickerstreak@53 90 btns[i]:Refresh(bar,i)
flickerstreak@53 91 end
flickerstreak@53 92 end
flickerstreak@53 93 for i = n+1, #btns do
flickerstreak@53 94 if btns[i] then
flickerstreak@75 95 bar:RemoveButton(b)
flickerstreak@53 96 btns[i] = btns[i]:Destroy()
flickerstreak@53 97 if btnCfg[i] then
flickerstreak@53 98 btnCfg[i] = nil
flickerstreak@53 99 end
flickerstreak@53 100 end
flickerstreak@53 101 end
flickerstreak@53 102 end
flickerstreak@53 103 end
flickerstreak@53 104
flickerstreak@63 105 function module:OnDestroyBar(event, bar, name)
flickerstreak@53 106 if self.buttons[bar] then
flickerstreak@53 107 local btns = self.buttons[bar]
flickerstreak@53 108 for _,b in pairs(btns) do
flickerstreak@53 109 if b then
flickerstreak@53 110 b:Destroy()
flickerstreak@53 111 end
flickerstreak@53 112 end
flickerstreak@53 113 self.buttons[bar] = nil
flickerstreak@53 114 end
flickerstreak@53 115 end
flickerstreak@53 116
flickerstreak@63 117 function module:OnEraseBar(event, bar, name)
flickerstreak@63 118 self.db.profile.buttons[name] = nil
flickerstreak@53 119 end
flickerstreak@53 120
flickerstreak@63 121 function module:OnRenameBar(event, bar, oldname, newname)
flickerstreak@53 122 local b = self.db.profile.buttons
flickerstreak@53 123 b[newname], b[oldname] = b[oldname], nil
flickerstreak@53 124 end
flickerstreak@53 125
flickerstreak@53 126
flickerstreak@63 127 function module:OnConfigModeChanged(event, mode)
flickerstreak@63 128 for _, bar in ReAction:IterateBars() do
flickerstreak@53 129 if bar and self.buttons[bar] then
flickerstreak@53 130 for _, b in pairs(self.buttons[bar]) do
flickerstreak@53 131 if b then
flickerstreak@53 132 if mode then
flickerstreak@53 133 self:showActionIDLabel(b)
flickerstreak@53 134 else
flickerstreak@53 135 self:hideActionIDLabel(b)
flickerstreak@53 136 end
flickerstreak@53 137 end
flickerstreak@53 138 end
flickerstreak@53 139 local f = bar:GetFrame()
flickerstreak@53 140 if mode then
flickerstreak@53 141 UnregisterUnitWatch(f)
flickerstreak@53 142 f:Show()
flickerstreak@53 143 else
flickerstreak@53 144 RegisterUnitWatch(f)
flickerstreak@53 145 end
flickerstreak@53 146 end
flickerstreak@53 147 end
flickerstreak@53 148 end
flickerstreak@53 149
flickerstreak@53 150 function module:showActionIDLabel(button)
flickerstreak@53 151 -- store the action ID label in the frame due to frame recycling
flickerstreak@53 152 if not button:GetFrame().actionIDLabel and button:GetActionID() then
flickerstreak@53 153 local label = button:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
flickerstreak@53 154 label:SetAllPoints()
flickerstreak@53 155 label:SetJustifyH("CENTER")
flickerstreak@53 156 label:SetShadowColor(0,0,0,1)
flickerstreak@53 157 label:SetShadowOffset(2,-2)
flickerstreak@53 158 label:SetText(tostring(button:GetActionID()))
flickerstreak@53 159 button:GetFrame().actionIDLabel = label
flickerstreak@53 160 end
flickerstreak@53 161 button:GetFrame().actionIDLabel:Show()
flickerstreak@53 162 end
flickerstreak@53 163
flickerstreak@53 164 function module:hideActionIDLabel(button)
flickerstreak@53 165 if button:GetFrame().actionIDLabel then
flickerstreak@53 166 button:GetFrame().actionIDLabel:Hide()
flickerstreak@53 167 end
flickerstreak@53 168 end
flickerstreak@53 169
flickerstreak@60 170 ---- Options ----
flickerstreak@60 171 function module:GetBarOptions(bar)
flickerstreak@63 172 return {
flickerstreak@63 173 type = "group",
flickerstreak@63 174 name = L["Pet Buttons"],
flickerstreak@63 175 hidden = function() return bar.config.type ~= moduleID end,
flickerstreak@63 176 args = {
flickerstreak@60 177 }
flickerstreak@63 178 }
flickerstreak@59 179 end
flickerstreak@59 180
flickerstreak@53 181
flickerstreak@28 182
flickerstreak@28 183 -- use-count of action IDs
flickerstreak@53 184 local nActionIDs = NUM_PET_ACTION_SLOTS
flickerstreak@28 185 local ActionIDList = setmetatable( {}, {
flickerstreak@28 186 __index = function(self, idx)
flickerstreak@28 187 if idx == nil then
flickerstreak@53 188 for i = 1, nActionIDs do
flickerstreak@28 189 if rawget(self,i) == nil then
flickerstreak@28 190 rawset(self,i,1)
flickerstreak@28 191 return i
flickerstreak@28 192 end
flickerstreak@28 193 end
flickerstreak@53 194 error("ran out of pet action IDs")
flickerstreak@28 195 else
flickerstreak@28 196 local c = rawget(self,idx) or 0
flickerstreak@28 197 rawset(self,idx,c+1)
flickerstreak@28 198 return idx
flickerstreak@28 199 end
flickerstreak@28 200 end,
flickerstreak@28 201 __newindex = function(self,idx,value)
flickerstreak@28 202 if value == nil then
flickerstreak@28 203 value = rawget(self,idx)
flickerstreak@28 204 if value == 1 then
flickerstreak@28 205 value = nil
flickerstreak@28 206 elseif value then
flickerstreak@28 207 value = value - 1
flickerstreak@28 208 end
flickerstreak@28 209 end
flickerstreak@28 210 rawset(self,idx,value)
flickerstreak@28 211 end
flickerstreak@28 212 })
flickerstreak@28 213
flickerstreak@53 214 local frameRecycler = {}
flickerstreak@28 215
flickerstreak@53 216
flickerstreak@53 217 ------ Button class ------
flickerstreak@28 218 local Button = { }
flickerstreak@28 219
flickerstreak@28 220 local function Constructor( self, bar, idx, config )
flickerstreak@28 221 self.bar, self.idx, self.config = bar, idx, config
flickerstreak@28 222
flickerstreak@28 223 local barFrame = bar:GetFrame()
flickerstreak@28 224
flickerstreak@56 225 local name = config.name or ("ReAction_%s_Pet_%d"):format(bar:GetName(),idx)
flickerstreak@53 226 config.name = name
flickerstreak@53 227 self.name = config.name
flickerstreak@28 228 config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured
flickerstreak@28 229
flickerstreak@53 230 -- have to recycle frames with the same name:
flickerstreak@53 231 -- otherwise you either get references to old textures because named CreateFrame()
flickerstreak@53 232 -- doesn't overwrite existing globals (below)
flickerstreak@53 233 -- or, if you set them to nil in the global table, you get taint because of the
flickerstreak@53 234 -- crappy PetActionBar code.
flickerstreak@53 235 local f = frameRecycler[name]
flickerstreak@53 236 if f then
flickerstreak@53 237 f:SetParent(barFrame)
flickerstreak@53 238 f:Show()
flickerstreak@53 239 else
flickerstreak@53 240 f = CreateFrame("CheckButton", name, barFrame, "PetActionButtonTemplate")
flickerstreak@53 241 end
flickerstreak@53 242 if config.actionID then
flickerstreak@53 243 f:SetID(config.actionID) -- PetActionButtonTemplate isn't a proper SecureActionButton
flickerstreak@53 244 end
flickerstreak@53 245 f:SetFrameStrata("MEDIUM")
flickerstreak@53 246
flickerstreak@28 247 barFrame:SetAttribute("addchild",f)
flickerstreak@28 248
flickerstreak@53 249 self.frame = f
flickerstreak@53 250 self.icon = _G[("%sIcon"):format(name)]
flickerstreak@53 251 self.acTex = _G[("%sAutoCastable"):format(name)]
flickerstreak@53 252 self.acModel = _G[("%sAutoCast"):format(name)]
flickerstreak@53 253 self.cooldown = _G[("%sCooldown"):format(name)]
flickerstreak@53 254 self.hotkey = _G[("%sHotKey"):format(name)]
flickerstreak@53 255
flickerstreak@53 256 f:HookScript("OnDragStart", function() self:Update() end)
flickerstreak@53 257 f:HookScript("OnReceiveDrag", function() self:Update() end)
flickerstreak@53 258
flickerstreak@53 259 f:RegisterEvent("PLAYER_CONTROL_LOST");
flickerstreak@53 260 f:RegisterEvent("PLAYER_CONTROL_GAINED");
flickerstreak@53 261 f:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED");
flickerstreak@53 262 f:RegisterEvent("UNIT_PET");
flickerstreak@53 263 f:RegisterEvent("UNIT_FLAGS");
flickerstreak@53 264 f:RegisterEvent("UNIT_AURA");
flickerstreak@53 265 f:RegisterEvent("PET_BAR_UPDATE");
flickerstreak@53 266 f:RegisterEvent("PET_BAR_UPDATE_COOLDOWN");
flickerstreak@53 267
flickerstreak@53 268 f:SetScript("OnEvent",
flickerstreak@53 269 function(event,arg1)
flickerstreak@53 270 if event =="PET_BAR_UPDATE_COOLDOWN" then
flickerstreak@53 271 self:UpdateCooldown()
flickerstreak@53 272 elseif event == "UPDATE_BINDINGS" then
flickerstreak@53 273 self:UpdateHotkey()
flickerstreak@53 274 else
flickerstreak@53 275 self:Update()
flickerstreak@53 276 end
flickerstreak@53 277 end)
flickerstreak@28 278
flickerstreak@28 279 self:Refresh(bar,idx)
flickerstreak@28 280 end
flickerstreak@28 281
flickerstreak@28 282 function Button:Destroy()
flickerstreak@28 283 local f = self.frame
flickerstreak@28 284 f:UnregisterAllEvents()
flickerstreak@28 285 f:Hide()
flickerstreak@28 286 f:SetParent(UIParent)
flickerstreak@28 287 f:ClearAllPoints()
flickerstreak@28 288 if self.name then
flickerstreak@53 289 frameRecycler[self.name] = f
flickerstreak@28 290 _G[self.name] = nil
flickerstreak@28 291 end
flickerstreak@53 292 if self.config.actionID then
flickerstreak@53 293 ActionIDList[self.config.actionID] = nil
flickerstreak@53 294 end
flickerstreak@28 295 self.frame = nil
flickerstreak@28 296 self.config = nil
flickerstreak@28 297 self.bar = nil
flickerstreak@28 298 end
flickerstreak@28 299
flickerstreak@53 300 function Button:Refresh(bar,idx)
flickerstreak@75 301 bar:PlaceButton(self, 30, 30)
flickerstreak@53 302 self:Update()
flickerstreak@53 303 self:UpdateHotkey()
flickerstreak@53 304 end
flickerstreak@53 305
flickerstreak@53 306 function Button:GetFrame()
flickerstreak@53 307 return self.frame
flickerstreak@53 308 end
flickerstreak@53 309
flickerstreak@53 310 function Button:GetName()
flickerstreak@53 311 return self.name
flickerstreak@53 312 end
flickerstreak@53 313
flickerstreak@53 314 function Button:GetActionID()
flickerstreak@53 315 return self.config.actionID
flickerstreak@53 316 end
flickerstreak@53 317
flickerstreak@53 318 function Button:Update()
flickerstreak@53 319 local id = self.frame:GetID()
flickerstreak@53 320 local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(id);
flickerstreak@53 321 local f = self.frame
flickerstreak@53 322 --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)))
flickerstreak@53 323
flickerstreak@53 324 if isToken then
flickerstreak@53 325 self.icon:SetTexture(_G[texture]);
flickerstreak@53 326 f.tooltipName = _G[name];
flickerstreak@53 327 else
flickerstreak@53 328 self.icon:SetTexture(texture);
flickerstreak@53 329 f.tooltipName = name;
flickerstreak@53 330 end
flickerstreak@53 331
flickerstreak@53 332 f.isToken = isToken;
flickerstreak@53 333 f.tooltipSubtext = subtext;
flickerstreak@53 334 f:SetChecked( isActive and 1 or 0);
flickerstreak@53 335
flickerstreak@53 336 if autoCastAllowed then
flickerstreak@53 337 self.acTex:Show();
flickerstreak@53 338 else
flickerstreak@53 339 self.acTex:Hide();
flickerstreak@53 340 end
flickerstreak@53 341
flickerstreak@53 342 if autoCastEnabled then
flickerstreak@53 343 self.acModel:Show();
flickerstreak@53 344 else
flickerstreak@53 345 self.acModel:Hide();
flickerstreak@53 346 end
flickerstreak@53 347
flickerstreak@53 348 if texture then
flickerstreak@53 349 if GetPetActionsUsable() then
flickerstreak@53 350 SetDesaturation(self.icon,nil)
flickerstreak@53 351 else
flickerstreak@53 352 SetDesaturation(self.icon,1)
flickerstreak@53 353 end
flickerstreak@53 354 self.icon:Show();
flickerstreak@53 355 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
flickerstreak@53 356 else
flickerstreak@53 357 self.icon:Hide();
flickerstreak@53 358 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot");
flickerstreak@53 359 end
flickerstreak@53 360
flickerstreak@53 361 self:UpdateCooldown()
flickerstreak@53 362 end
flickerstreak@53 363
flickerstreak@53 364 function Button:UpdateCooldown()
flickerstreak@53 365 local start, duration, enable = GetPetActionCooldown(self.frame:GetID());
flickerstreak@53 366 CooldownFrame_SetTimer(self.cooldown, start, duration, enable);
flickerstreak@53 367 end
flickerstreak@53 368
flickerstreak@53 369 function Button:UpdateHotkey()
flickerstreak@53 370
flickerstreak@53 371 end
flickerstreak@28 372
flickerstreak@28 373 -- export as a class-factory to module
flickerstreak@28 374 module.BtnClass = {
flickerstreak@28 375 new = function(self, ...)
flickerstreak@28 376 local x = { }
flickerstreak@28 377 for k,v in pairs(Button) do
flickerstreak@28 378 x[k] = v
flickerstreak@28 379 end
flickerstreak@28 380 Constructor(x, ...)
flickerstreak@28 381 return x
flickerstreak@28 382 end
flickerstreak@28 383 }