annotate modules/ReAction_PetAction/ReAction_PetAction.lua @ 91:c2504a8b996c

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