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