annotate modules/ReAction_PossessBar/ReAction_PossessBar.lua @ 59:7430a8dd4e90

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