annotate modules/ReAction_PossessBar/ReAction_PossessBar.lua @ 60:44649a10378d

Fixed options handling to create a separate table for each bar instead of a shared table with proxy handler. Also simplified options registration and moved some options around.
author Flick <flickerstreak@gmail.com>
date Sat, 10 May 2008 00:08:01 +0000
parents 7430a8dd4e90
children 768be7eb22a0
rev   line source
flickerstreak@54 1 --[[
flickerstreak@54 2 ReAction Possess Bar (Mind Control/etc) button module.
flickerstreak@54 3
flickerstreak@54 4 Wraps the standard Action buttons 121-132 with an automatic show/hide
flickerstreak@54 5 when mind control (etc) is active
flickerstreak@54 6
flickerstreak@54 7 --]]
flickerstreak@54 8
flickerstreak@54 9 -- local imports
flickerstreak@54 10 local ReAction = ReAction
flickerstreak@54 11 local L = ReAction.L
flickerstreak@54 12 local _G = _G
flickerstreak@54 13 local CreateFrame = CreateFrame
flickerstreak@54 14
flickerstreak@54 15 -- module declaration
flickerstreak@54 16 local moduleID = "PossessBar"
flickerstreak@54 17 local module = ReAction:NewModule( moduleID )
flickerstreak@54 18
flickerstreak@54 19 -- module methods
flickerstreak@54 20 function module:OnInitialize()
flickerstreak@54 21 self.db = ReAction.db:RegisterNamespace( moduleID,
flickerstreak@54 22 {
flickerstreak@54 23 profile = {
flickerstreak@54 24 buttons = { }
flickerstreak@54 25 }
flickerstreak@54 26 }
flickerstreak@54 27 )
flickerstreak@54 28 self.buttons = { }
flickerstreak@60 29 self.options = setmetatable({},{__mode="k"})
flickerstreak@54 30
flickerstreak@60 31 ReAction:RegisterOptions(self, {
flickerstreak@60 32 [moduleID] = {
flickerstreak@60 33 type = "group",
flickerstreak@60 34 name = L["Possess Bar"],
flickerstreak@60 35 args = {
flickerstreak@60 36 hideEmptyPossess = {
flickerstreak@60 37 type = "toggle",
flickerstreak@60 38 name = L["Hide Empty Possess Bar Buttons"],
flickerstreak@60 39 get = function() return self.db.profile.hideEmptyButtons end,
flickerstreak@60 40 set = function(info, val) module:SetHideEmptyButtons(val) end,
flickerstreak@60 41 }
flickerstreak@60 42 }
flickerstreak@60 43 }
flickerstreak@60 44 })
flickerstreak@54 45 end
flickerstreak@54 46
flickerstreak@54 47 function module:OnEnable()
flickerstreak@54 48 ReAction:RegisterBarType(L["Possess Bar"],
flickerstreak@54 49 {
flickerstreak@54 50 type = moduleID,
flickerstreak@54 51 defaultButtonSize = 36,
flickerstreak@54 52 defaultBarRows = 1,
flickerstreak@54 53 defaultBarCols = 12,
flickerstreak@54 54 defaultBarSpacing = 3
flickerstreak@54 55 })
flickerstreak@54 56 end
flickerstreak@54 57
flickerstreak@54 58 function module:OnDisable()
flickerstreak@54 59 ReAction:UnregisterBarType(L["Possess Bar"])
flickerstreak@54 60 end
flickerstreak@54 61
flickerstreak@54 62 function module:ApplyToBar(bar)
flickerstreak@54 63 if bar.config.type == moduleID then
flickerstreak@54 64 bar:GetFrame():SetParent(PossessBarFrame)
flickerstreak@54 65 bar.config.parent = "PossessBarFrame"
flickerstreak@57 66 self:CreatePossessControlButtons(bar)
flickerstreak@54 67 end
flickerstreak@54 68 self:RefreshBar(bar)
flickerstreak@54 69 end
flickerstreak@54 70
flickerstreak@54 71 function module:RefreshBar(bar)
flickerstreak@54 72 if bar.config.type == moduleID then
flickerstreak@54 73 if self.buttons[bar] == nil then
flickerstreak@54 74 self.buttons[bar] = { }
flickerstreak@54 75 end
flickerstreak@54 76 local btns = self.buttons[bar]
flickerstreak@54 77 local profile = self.db.profile
flickerstreak@54 78 local barName = bar:GetName()
flickerstreak@54 79 if profile.buttons[barName] == nil then
flickerstreak@54 80 profile.buttons[barName] = {}
flickerstreak@54 81 end
flickerstreak@54 82 local btnCfg = profile.buttons[barName]
flickerstreak@54 83
flickerstreak@54 84 local r, c = bar:GetButtonGrid()
flickerstreak@54 85 local n = r*c
flickerstreak@54 86 for i = 1, n do
flickerstreak@54 87 if btnCfg[i] == nil then
flickerstreak@54 88 btnCfg[i] = {}
flickerstreak@54 89 end
flickerstreak@54 90 if btns[i] == nil then
flickerstreak@54 91 local ok, b = pcall(self.BtnClass.new, self.BtnClass, bar, i, btnCfg[i])
flickerstreak@54 92 if ok and b then
flickerstreak@54 93 btns[i] = b
flickerstreak@54 94 end
flickerstreak@54 95 else
flickerstreak@54 96 btns[i]:Refresh(bar,i)
flickerstreak@54 97 end
flickerstreak@54 98 end
flickerstreak@54 99 for i = n+1, #btns do
flickerstreak@54 100 if btns[i] then
flickerstreak@54 101 btns[i] = btns[i]:Destroy()
flickerstreak@54 102 if btnCfg[i] then
flickerstreak@54 103 btnCfg[i] = nil
flickerstreak@54 104 end
flickerstreak@54 105 end
flickerstreak@54 106 end
flickerstreak@54 107 end
flickerstreak@54 108 end
flickerstreak@54 109
flickerstreak@54 110 function module:RemoveFromBar(bar)
flickerstreak@54 111 if self.buttons[bar] then
flickerstreak@54 112 local btns = self.buttons[bar]
flickerstreak@54 113 for _,b in pairs(btns) do
flickerstreak@54 114 if b then
flickerstreak@54 115 b:Destroy()
flickerstreak@54 116 end
flickerstreak@54 117 end
flickerstreak@54 118 self.buttons[bar] = nil
flickerstreak@54 119 end
flickerstreak@54 120 end
flickerstreak@54 121
flickerstreak@54 122 function module:EraseBarConfig(barName)
flickerstreak@54 123 self.db.profile.buttons[barName] = nil
flickerstreak@54 124 end
flickerstreak@54 125
flickerstreak@54 126 function module:RenameBarConfig(oldname, newname)
flickerstreak@54 127 local b = self.db.profile.buttons
flickerstreak@54 128 b[newname], b[oldname] = b[oldname], nil
flickerstreak@54 129 end
flickerstreak@54 130
flickerstreak@54 131 function module:SetHideEmptyButtons(hide)
flickerstreak@54 132 if hide ~= self.db.profile.hideEmptyButtons then
flickerstreak@54 133 for _, bar in pairs(self.buttons) do
flickerstreak@54 134 for _, b in pairs(bar) do
flickerstreak@54 135 if hide then
flickerstreak@54 136 ActionButton_HideGrid(b.frame)
flickerstreak@54 137 else
flickerstreak@54 138 ActionButton_ShowGrid(b.frame)
flickerstreak@54 139 end
flickerstreak@54 140 end
flickerstreak@54 141 end
flickerstreak@54 142 self.db.profile.hideEmptyButtons = hide
flickerstreak@54 143 end
flickerstreak@54 144 end
flickerstreak@54 145
flickerstreak@54 146 function module:ApplyConfigMode(mode,bars)
flickerstreak@54 147 for _, bar in pairs(bars) do
flickerstreak@54 148 if bar and self.buttons[bar] then
flickerstreak@54 149 for _, b in pairs(self.buttons[bar]) do
flickerstreak@54 150 if b then
flickerstreak@54 151 if mode then
flickerstreak@54 152 ActionButton_ShowGrid(b.frame)
flickerstreak@54 153 self:showActionIDLabel(b)
flickerstreak@54 154 else
flickerstreak@54 155 ActionButton_HideGrid(b.frame)
flickerstreak@54 156 self:hideActionIDLabel(b)
flickerstreak@54 157 end
flickerstreak@54 158 end
flickerstreak@54 159 end
flickerstreak@54 160 local f = bar:GetFrame()
flickerstreak@54 161 if mode then
flickerstreak@54 162 f:SetParent(UIParent)
flickerstreak@54 163 f:Show()
flickerstreak@54 164 else
flickerstreak@54 165 f:SetParent(PossessBarFrame)
flickerstreak@54 166 end
flickerstreak@54 167 end
flickerstreak@54 168 end
flickerstreak@54 169 end
flickerstreak@54 170
flickerstreak@54 171 function module:showActionIDLabel(button)
flickerstreak@54 172 if not button.actionIDLabel and button:GetActionID() then
flickerstreak@54 173 local label = button:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
flickerstreak@54 174 label:SetAllPoints()
flickerstreak@54 175 label:SetJustifyH("CENTER")
flickerstreak@54 176 label:SetShadowColor(0,0,0,1)
flickerstreak@54 177 label:SetShadowOffset(2,-2)
flickerstreak@54 178 label:SetText(tostring(button:GetActionID()))
flickerstreak@54 179 button.actionIDLabel = label
flickerstreak@54 180 end
flickerstreak@54 181 button.actionIDLabel:Show()
flickerstreak@54 182 end
flickerstreak@54 183
flickerstreak@54 184 function module:hideActionIDLabel(button)
flickerstreak@54 185 if button.actionIDLabel then
flickerstreak@54 186 button.actionIDLabel:Hide()
flickerstreak@54 187 end
flickerstreak@54 188 end
flickerstreak@54 189
flickerstreak@54 190
flickerstreak@57 191 -- possess-bar control buttons (shows buff, cancel buff)
flickerstreak@57 192 function module:CreatePossessControlButton(bar,id,name)
flickerstreak@57 193 -- guard against taint by reusing global variable frames
flickerstreak@57 194 -- instead of nilling them out (e.g. create bar, delete bar, create bar with same name)
flickerstreak@57 195 name = name or ("ReAction_%s_PossessCtrlButton%d"):format(bar:GetName(),id)
flickerstreak@57 196 local b = name and _G[name]
flickerstreak@57 197 if b then
flickerstreak@57 198 b:SetParent(bar:GetFrame())
flickerstreak@57 199 else
flickerstreak@57 200 b = CreateFrame("CheckButton", name, bar:GetFrame(), "PossessButtonTemplate")
flickerstreak@57 201 end
flickerstreak@57 202 b:SetID(id)
flickerstreak@57 203
flickerstreak@57 204 b:RegisterEvent("PLAYER_AURAS_CHANGED");
flickerstreak@57 205
flickerstreak@57 206 local icon = _G[("%sIcon"):format(name)]
flickerstreak@57 207 local cooldown = _G[("%sCooldown"):format(name)]
flickerstreak@57 208 local nTex = _G[("%sNormalTexture"):format(name)]
flickerstreak@57 209 nTex:SetWidth(54)
flickerstreak@57 210 nTex:SetHeight(54)
flickerstreak@57 211
flickerstreak@57 212 local function update()
flickerstreak@57 213 local texture = GetPossessInfo(id);
flickerstreak@57 214 icon:SetTexture(texture);
flickerstreak@57 215 icon:Show()
flickerstreak@57 216 cooldown:Hide();
flickerstreak@57 217 b:SetChecked(0);
flickerstreak@57 218 icon:SetVertexColor(1.0, 1.0, 1.0);
flickerstreak@57 219 end
flickerstreak@57 220 update()
flickerstreak@57 221
flickerstreak@57 222 b:HookScript("OnClick", function() b:SetChecked(0) end)
flickerstreak@57 223 b:SetScript("OnEvent", update)
flickerstreak@57 224 b:SetScript("OnShow", update)
flickerstreak@57 225
flickerstreak@57 226 return b
flickerstreak@57 227 end
flickerstreak@57 228
flickerstreak@57 229 function module:CreatePossessControlButtons(bar)
flickerstreak@57 230 if not bar.possessButtons then
flickerstreak@57 231 bar.possessButtons = { }
flickerstreak@57 232 bar.config.possessFrameNames = bar.config.possessFrameNames or { }
flickerstreak@57 233 local previous
flickerstreak@57 234 local n = NUM_POSSESS_SLOTS
flickerstreak@57 235 for i = 1, n do
flickerstreak@57 236 local name = bar.config.possessFrameNames[i]
flickerstreak@57 237 local f = self:CreatePossessControlButton(bar,i,name)
flickerstreak@57 238 bar.possessButtons[i] = f
flickerstreak@57 239 bar.config.possessFrameNames[i] = f:GetName()
flickerstreak@57 240
flickerstreak@57 241 local r, c, s = bar:GetButtonGrid()
flickerstreak@57 242 local w, h = bar:GetButtonSize()
flickerstreak@57 243
flickerstreak@57 244 local scale = ((h - (n-1)*s)/n)/30
flickerstreak@57 245 f:SetScale(scale)
flickerstreak@57 246
flickerstreak@57 247 if previous then
flickerstreak@57 248 f:SetPoint("TOP", previous, "BOTTOM", 0, -s/scale)
flickerstreak@57 249 else
flickerstreak@57 250 f:SetPoint("TOPRIGHT", bar:GetFrame(), "TOPLEFT", -s/scale, 0)
flickerstreak@57 251 end
flickerstreak@57 252 f:Show()
flickerstreak@57 253 previous = f
flickerstreak@57 254 end
flickerstreak@57 255 end
flickerstreak@57 256 end
flickerstreak@57 257
flickerstreak@60 258 ---- Options ----
flickerstreak@60 259 function module:GetBarOptions(bar)
flickerstreak@60 260 if not self.options[bar] then
flickerstreak@60 261 self.options[bar] = {
flickerstreak@60 262 type = "group",
flickerstreak@60 263 name = L["Possess Buttons"],
flickerstreak@60 264 hidden = function() return bar.config.type ~= moduleID end,
flickerstreak@60 265 args = {
flickerstreak@60 266 }
flickerstreak@60 267 }
flickerstreak@60 268 end
flickerstreak@60 269 return self.options[bar]
flickerstreak@59 270 end
flickerstreak@57 271
flickerstreak@54 272
flickerstreak@54 273 -- use-count of action IDs
flickerstreak@54 274 local minActionID = 121
flickerstreak@54 275 local maxActionID = 132
flickerstreak@54 276 local ActionIDList = setmetatable( {}, {
flickerstreak@54 277 __index = function(self, idx)
flickerstreak@54 278 if idx == nil then
flickerstreak@54 279 for i = minActionID, maxActionID do
flickerstreak@54 280 if rawget(self,i) == nil then
flickerstreak@54 281 rawset(self,i,1)
flickerstreak@54 282 return i
flickerstreak@54 283 end
flickerstreak@54 284 end
flickerstreak@54 285 error("ran out of action IDs")
flickerstreak@54 286 else
flickerstreak@54 287 local c = rawget(self,idx) or 0
flickerstreak@54 288 rawset(self,idx,c+1)
flickerstreak@54 289 return idx
flickerstreak@54 290 end
flickerstreak@54 291 end,
flickerstreak@54 292 __newindex = function(self,idx,value)
flickerstreak@54 293 if value == nil then
flickerstreak@54 294 value = rawget(self,idx)
flickerstreak@54 295 if value == 1 then
flickerstreak@54 296 value = nil
flickerstreak@54 297 elseif value then
flickerstreak@54 298 value = value - 1
flickerstreak@54 299 end
flickerstreak@54 300 end
flickerstreak@54 301 rawset(self,idx,value)
flickerstreak@54 302 end
flickerstreak@54 303 })
flickerstreak@54 304
flickerstreak@54 305
flickerstreak@54 306
flickerstreak@54 307
flickerstreak@54 308 ------ Button class ------
flickerstreak@54 309 local Button = { }
flickerstreak@54 310
flickerstreak@54 311 local function Constructor( self, bar, idx, config )
flickerstreak@54 312 self.bar, self.idx, self.config = bar, idx, config
flickerstreak@54 313
flickerstreak@54 314 local barFrame = bar:GetFrame()
flickerstreak@54 315
flickerstreak@57 316 config.name = config.name or ("ReAction_%s_Possess_%d"):format(bar:GetName(),idx)
flickerstreak@54 317 self.name = config.name
flickerstreak@54 318 config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured
flickerstreak@54 319
flickerstreak@54 320 local f = CreateFrame("CheckButton", self.name, barFrame, "BonusActionButtonTemplate")
flickerstreak@54 321
flickerstreak@54 322 -- TODO: re-implement ActionButton event handlers that don't do secure stuff
flickerstreak@54 323
flickerstreak@54 324 -- this will probably cause taint, using right now for display/debugging purposes
flickerstreak@54 325 f:SetScript("OnAttributeChanged", ActionButton_UpdateAction)
flickerstreak@54 326 f:SetAttribute("action", config.actionID)
flickerstreak@54 327
flickerstreak@54 328 barFrame:SetAttribute("addchild",f)
flickerstreak@54 329
flickerstreak@54 330 self.frame = f
flickerstreak@54 331 self:Refresh(bar,idx)
flickerstreak@54 332
flickerstreak@54 333 if not module.db.profile.hideEmptyButtons then
flickerstreak@54 334 ActionButton_ShowGrid(self.frame)
flickerstreak@54 335 end
flickerstreak@54 336
flickerstreak@54 337 if ReAction.configMode then
flickerstreak@54 338 ActionButton_ShowGrid(self.frame)
flickerstreak@54 339 module:showActionIDLabel(self)
flickerstreak@54 340 end
flickerstreak@54 341 end
flickerstreak@54 342
flickerstreak@54 343 function Button:Destroy()
flickerstreak@54 344 local f = self.frame
flickerstreak@54 345 f:UnregisterAllEvents()
flickerstreak@54 346 f:Hide()
flickerstreak@54 347 f:SetParent(UIParent)
flickerstreak@54 348 f:ClearAllPoints()
flickerstreak@54 349 if self.name then
flickerstreak@54 350 _G[self.name] = nil
flickerstreak@54 351 end
flickerstreak@54 352 if self.config.actionID then
flickerstreak@54 353 ActionIDList[self.config.actionID] = nil
flickerstreak@54 354 end
flickerstreak@54 355 self.frame = nil
flickerstreak@54 356 self.config = nil
flickerstreak@54 357 self.bar = nil
flickerstreak@54 358 end
flickerstreak@54 359
flickerstreak@54 360 function Button:Refresh(bar,idx)
flickerstreak@54 361 bar:PlaceButton(self.frame, idx, 36, 36)
flickerstreak@54 362 end
flickerstreak@54 363
flickerstreak@54 364 function Button:GetFrame()
flickerstreak@54 365 return self.frame
flickerstreak@54 366 end
flickerstreak@54 367
flickerstreak@54 368 function Button:GetName()
flickerstreak@54 369 return self.name
flickerstreak@54 370 end
flickerstreak@54 371
flickerstreak@54 372 function Button:GetActionID()
flickerstreak@54 373 return self.config.actionID
flickerstreak@54 374 end
flickerstreak@54 375
flickerstreak@54 376
flickerstreak@54 377 -- export as a class-factory to module
flickerstreak@54 378 module.BtnClass = {
flickerstreak@54 379 new = function(self, ...)
flickerstreak@54 380 local x = { }
flickerstreak@54 381 for k,v in pairs(Button) do
flickerstreak@54 382 x[k] = v
flickerstreak@54 383 end
flickerstreak@54 384 Constructor(x, ...)
flickerstreak@54 385 return x
flickerstreak@54 386 end
flickerstreak@54 387 }