annotate modules/ReAction_PossessBar/ReAction_PossessBar.lua @ 57:b85118b61564

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