flickerstreak@1
|
1 -- private constants
|
flickerstreak@2
|
2 local namePrefix = "ReActionButton"
|
flickerstreak@1
|
3 local _G = getfenv(0)
|
flickerstreak@1
|
4 local ACTION_FREE = { }
|
flickerstreak@1
|
5 local MAX_ACTIONS = 120
|
flickerstreak@1
|
6
|
flickerstreak@1
|
7 local hotKeyDefaultColor = { r=1.0, g=1.0, b=1.0, a=1.0 }
|
flickerstreak@1
|
8 local hotKeyDisabledColor = { r=0.6, g=0.6, b=0.6, a=1.0 }
|
flickerstreak@1
|
9 local hotKeyOutOfRangeColor = { r=1.0, g=0.2, b=0.2, a=1.0 }
|
flickerstreak@1
|
10
|
flickerstreak@1
|
11 local hotKeyModifierColors = {
|
flickerstreak@1
|
12 S = { r=0.6, g=0.6, b=1.0, a=1.0 }, -- shift
|
flickerstreak@1
|
13 C = { r=1.0, g=0.82, b=0, a=1.0 }, -- ctrl
|
flickerstreak@1
|
14 A = { r=0.1, g=1.0, b=0.1, a=1.0 }, -- alt
|
flickerstreak@1
|
15 }
|
flickerstreak@1
|
16
|
flickerstreak@2
|
17 -- TODO: localize these key names with GetBindingText(KEY_)
|
flickerstreak@2
|
18 local keybindAbbreviations = {
|
flickerstreak@2
|
19 ["Mouse Button "] = "M-",
|
flickerstreak@2
|
20 ["Spacebar"] = "Sp",
|
flickerstreak@2
|
21 ["Num Pad "] = "Num-",
|
flickerstreak@2
|
22 ["Page Up"] = "PgUp",
|
flickerstreak@2
|
23 ["Page Down"] = "PgDn",
|
flickerstreak@2
|
24 [" Arrow"] = "",
|
flickerstreak@2
|
25 }
|
flickerstreak@2
|
26
|
flickerstreak@1
|
27 local equippedActionBorderColor = { r=0, g=1.0, b=0, a=0.35 }
|
flickerstreak@1
|
28
|
flickerstreak@1
|
29 local actionUsableColor = { r=1.0, g=1.0, b=1.0, a=1.0 }
|
flickerstreak@1
|
30 local actionNotUsableColor = { r=0.4, g=0.4, b=0.4, a=1.0 }
|
flickerstreak@1
|
31 local actionNotEnoughManaColor = { r=0.2, g=0.2, b=0.7, a=1.0 }
|
flickerstreak@1
|
32 local actionOutOfRangeColor = { r=1.0, g=0.2, b=0.2, a=1.0 }
|
flickerstreak@1
|
33
|
flickerstreak@1
|
34 -- private variables
|
flickerstreak@1
|
35 local kbValidate = AceLibrary("AceConsole-2.0").keybindingValidateFunc
|
flickerstreak@1
|
36 local actionButtonTbl = { }
|
flickerstreak@1
|
37
|
flickerstreak@1
|
38
|
flickerstreak@1
|
39
|
flickerstreak@1
|
40 -- ReActionButton is a class prototype object.
|
flickerstreak@1
|
41 ReActionButton = AceLibrary("AceOO-2.0").Class("AceEvent-2.0")
|
flickerstreak@1
|
42
|
flickerstreak@1
|
43 -------------------
|
flickerstreak@1
|
44 -- Class methods
|
flickerstreak@1
|
45 -------------------
|
flickerstreak@1
|
46
|
flickerstreak@1
|
47 -- In addition to supporting the 'new' creation method (in which case an action ID must be specified directly),
|
flickerstreak@1
|
48 -- ReActionButton supports the 'acquire'/'release' creation method, which recycles objects and manages actionID assignment.
|
flickerstreak@1
|
49
|
flickerstreak@1
|
50 function ReActionButton:acquire(parent, config, barIdx)
|
flickerstreak@1
|
51 local id = nil
|
flickerstreak@1
|
52 for i = 1, MAX_ACTIONS do
|
flickerstreak@1
|
53 if actionButtonTbl[i] == nil or actionButtonTbl[i].inUse == false then
|
flickerstreak@1
|
54 id = i
|
flickerstreak@1
|
55 break
|
flickerstreak@1
|
56 end
|
flickerstreak@1
|
57 end
|
flickerstreak@1
|
58
|
flickerstreak@1
|
59 if id == nil then return nil end -- all buttons and action ids are in use
|
flickerstreak@1
|
60
|
flickerstreak@1
|
61 local hint = config.actionIDs[barIdx]
|
flickerstreak@1
|
62 if hint and (actionButtonTbl[hint] == nil or actionButtonTbl[hint].inUse == false) then
|
flickerstreak@1
|
63 id = hint
|
flickerstreak@1
|
64 end
|
flickerstreak@1
|
65
|
flickerstreak@1
|
66 if actionButtonTbl[id] == nil then
|
flickerstreak@1
|
67 actionButtonTbl[id] = { }
|
flickerstreak@1
|
68 end
|
flickerstreak@1
|
69 local t = actionButtonTbl[id]
|
flickerstreak@1
|
70
|
flickerstreak@1
|
71 t.inUse = true
|
flickerstreak@1
|
72 if t.button then
|
flickerstreak@2
|
73 t.button:Configure(parent,config,barIdx)
|
flickerstreak@1
|
74 else
|
flickerstreak@1
|
75 t.button = self:new(parent,config,barIdx,id)
|
flickerstreak@1
|
76 end
|
flickerstreak@1
|
77
|
flickerstreak@2
|
78 -- fix screwy config with overlapping IDs
|
flickerstreak@2
|
79 config.actionIDs[barIdx] = id
|
flickerstreak@1
|
80 return t.button
|
flickerstreak@1
|
81 end
|
flickerstreak@1
|
82
|
flickerstreak@1
|
83 function ReActionButton:release( b )
|
flickerstreak@1
|
84 if b then
|
flickerstreak@1
|
85 actionButtonTbl[b:GetActionID()].inUse = false
|
flickerstreak@1
|
86 b:Recycle()
|
flickerstreak@1
|
87 end
|
flickerstreak@1
|
88 end
|
flickerstreak@1
|
89
|
flickerstreak@1
|
90
|
flickerstreak@1
|
91
|
flickerstreak@1
|
92 function ReActionButton:ShowAllActionIDs()
|
flickerstreak@1
|
93 for _, b in ipairs(actionButtonTbl) do
|
flickerstreak@1
|
94 b:ShowActionID()
|
flickerstreak@1
|
95 end
|
flickerstreak@1
|
96 end
|
flickerstreak@1
|
97
|
flickerstreak@1
|
98 function ReActionButton:HideAllActionIDs()
|
flickerstreak@1
|
99 for _, b in ipairs(actionButtonTbl) do
|
flickerstreak@1
|
100 b:HideActionID()
|
flickerstreak@1
|
101 end
|
flickerstreak@1
|
102 end
|
flickerstreak@1
|
103
|
flickerstreak@1
|
104
|
flickerstreak@1
|
105 ----------------------
|
flickerstreak@1
|
106 -- Instance methods
|
flickerstreak@1
|
107 ----------------------
|
flickerstreak@1
|
108 function ReActionButton.prototype:init( parentFrame, config, barIdx, id )
|
flickerstreak@1
|
109 ReActionButton.super.prototype.init(self)
|
flickerstreak@1
|
110
|
flickerstreak@1
|
111 -- create the button widget
|
flickerstreak@2
|
112 self.name = namePrefix..id
|
flickerstreak@1
|
113 self.button = CreateFrame("CheckButton", self.name, parentFrame, "ReActionButtonTemplate")
|
flickerstreak@1
|
114
|
flickerstreak@1
|
115 -- store references to the various sub-frames so we don't have to look it up all the time
|
flickerstreak@1
|
116 self.frames = {
|
flickerstreak@1
|
117 hotkey = _G[self.name.."HotKey"],
|
flickerstreak@1
|
118 count = _G[self.name.."Count"],
|
flickerstreak@1
|
119 cooldown = _G[self.name.."Cooldown"],
|
flickerstreak@1
|
120 -- nCooldown = _G[self.name.."CooldownNumeric"],
|
flickerstreak@1
|
121 macro = _G[self.name.."Name"],
|
flickerstreak@1
|
122 icon = _G[self.name.."Icon"],
|
flickerstreak@1
|
123 border = _G[self.name.."Border"],
|
flickerstreak@1
|
124 normalTexture = _G[self.name.."NormalTexture"],
|
flickerstreak@1
|
125 flash = _G[self.name.."Flash"],
|
flickerstreak@2
|
126 actionID = _G[self.name.."ActionID"],
|
flickerstreak@1
|
127 }
|
flickerstreak@1
|
128
|
flickerstreak@1
|
129 -- provide a reference back to this object for the frame to use in event handlers
|
flickerstreak@1
|
130 self.button.rxnBtn = self
|
flickerstreak@1
|
131
|
flickerstreak@2
|
132 -- set the action ID
|
flickerstreak@2
|
133 self:SetActionID(id)
|
flickerstreak@2
|
134
|
flickerstreak@2
|
135 -- register button with ReBinder for keybinding
|
flickerstreak@2
|
136 ReBinder:AddKeybindTarget(self.button)
|
flickerstreak@2
|
137
|
flickerstreak@1
|
138 -- initialize
|
flickerstreak@2
|
139 self:Configure(parentFrame, config, barIdx)
|
flickerstreak@2
|
140 end
|
flickerstreak@2
|
141
|
flickerstreak@2
|
142 local function tcopy(t)
|
flickerstreak@2
|
143 local r = { }
|
flickerstreak@2
|
144 for k, v in pairs(t) do
|
flickerstreak@2
|
145 r[k] = (type(v) == "table" and tcopy(v) or v)
|
flickerstreak@2
|
146 end
|
flickerstreak@2
|
147 return r
|
flickerstreak@1
|
148 end
|
flickerstreak@1
|
149
|
flickerstreak@1
|
150 function ReActionButton.prototype:Recycle()
|
flickerstreak@1
|
151 local b = self.button
|
flickerstreak@1
|
152
|
flickerstreak@1
|
153 self:SetKeyBinding(nil)
|
flickerstreak@1
|
154 self:UpdateDisplay()
|
flickerstreak@1
|
155 b:UnregisterAllEvents()
|
flickerstreak@2
|
156 b:SetParent(ReActionButtonRecycleFrame)
|
flickerstreak@2
|
157 b:ClearAllPoints()
|
flickerstreak@2
|
158 b:SetPoint("TOPLEFT",0,0)
|
flickerstreak@1
|
159 b:Hide()
|
flickerstreak@2
|
160 self.config = tcopy(self.config) -- ew, but necessary
|
flickerstreak@1
|
161 end
|
flickerstreak@1
|
162
|
flickerstreak@2
|
163 function ReActionButton.prototype:BarUnlocked()
|
flickerstreak@2
|
164 self:ShowGridTmp()
|
flickerstreak@2
|
165 end
|
flickerstreak@2
|
166
|
flickerstreak@2
|
167 function ReActionButton.prototype:BarLocked()
|
flickerstreak@2
|
168 self:HideGridTmp()
|
flickerstreak@2
|
169 end
|
flickerstreak@1
|
170
|
flickerstreak@1
|
171
|
flickerstreak@1
|
172 -- set the button location
|
flickerstreak@1
|
173 function ReActionButton.prototype:PlaceButton(point, x, y, sz)
|
flickerstreak@1
|
174 local b = self.button
|
flickerstreak@1
|
175 local scale = sz / 36
|
flickerstreak@1
|
176 b:ClearAllPoints()
|
flickerstreak@1
|
177 b:SetScale( scale )
|
flickerstreak@1
|
178 b:SetPoint(point,x/scale,y/scale)
|
flickerstreak@1
|
179 end
|
flickerstreak@1
|
180
|
flickerstreak@1
|
181
|
flickerstreak@1
|
182 function ReActionButton.prototype:ShowActionID()
|
flickerstreak@1
|
183 self.frames.actionID:Show()
|
flickerstreak@1
|
184 end
|
flickerstreak@1
|
185
|
flickerstreak@1
|
186 function ReActionButton.prototype:HideActionID()
|
flickerstreak@1
|
187 self.frames.actionID:Hide()
|
flickerstreak@1
|
188 end
|
flickerstreak@1
|
189
|
flickerstreak@1
|
190
|
flickerstreak@1
|
191
|
flickerstreak@1
|
192 -- configuration and setup
|
flickerstreak@2
|
193 function ReActionButton.prototype:Configure( parentFrame, config, barIdx )
|
flickerstreak@1
|
194 self.config = config
|
flickerstreak@1
|
195 self.barIdx = barIdx
|
flickerstreak@2
|
196 self.showGridTmp_ = 0
|
flickerstreak@1
|
197
|
flickerstreak@1
|
198 self.button:ClearAllPoints()
|
flickerstreak@1
|
199 self.button:SetParent(parentFrame)
|
flickerstreak@1
|
200
|
flickerstreak@1
|
201 self:SetupAttributes()
|
flickerstreak@1
|
202 self:RegisterStaticEvents()
|
flickerstreak@1
|
203
|
flickerstreak@1
|
204 self:ApplyLayout()
|
flickerstreak@1
|
205 self:ApplyStyle()
|
flickerstreak@1
|
206
|
flickerstreak@1
|
207 self:UpdateDisplay()
|
flickerstreak@1
|
208 end
|
flickerstreak@1
|
209
|
flickerstreak@1
|
210 function ReActionButton.prototype:SetupAttributes()
|
flickerstreak@1
|
211 local b = self.button
|
flickerstreak@1
|
212 b:SetAttribute("type", "action")
|
flickerstreak@1
|
213 b:SetAttribute("shift-type*", ATTRIBUTE_NOOP)
|
flickerstreak@1
|
214 b:SetAttribute("checkselfcast", true)
|
flickerstreak@1
|
215 b:SetAttribute("useparent-unit", true)
|
flickerstreak@1
|
216 end
|
flickerstreak@1
|
217
|
flickerstreak@1
|
218 function ReActionButton.prototype:RegisterStaticEvents()
|
flickerstreak@1
|
219 self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
flickerstreak@1
|
220 self:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
flickerstreak@1
|
221 self:RegisterEvent("UPDATE_BINDINGS")
|
flickerstreak@1
|
222 self:RegisterEvent("ACTIONBAR_SHOWGRID")
|
flickerstreak@1
|
223 self:RegisterEvent("ACTIONBAR_HIDEGRID")
|
flickerstreak@1
|
224 end
|
flickerstreak@1
|
225
|
flickerstreak@1
|
226 function ReActionButton.prototype:RegisterActionEvents()
|
flickerstreak@1
|
227 self:RegisterEvent("ACTIONBAR_UPDATE_STATE")
|
flickerstreak@1
|
228 self:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
229 self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
230 self:RegisterEvent("UPDATE_INVENTORY_ALERTS", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
231 self:RegisterEvent("PLAYER_AURAS_CHANGED", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
232 self:RegisterEvent("PLAYER_TARGET_CHANGED", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
233 self:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
flickerstreak@1
|
234 self:RegisterEvent("CRAFT_SHOW")
|
flickerstreak@1
|
235 self:RegisterEvent("CRAFT_CLOSE", "CRAFT_SHOW")
|
flickerstreak@1
|
236 self:RegisterEvent("TRADE_SKILL_SHOW", "CRAFT_SHOW")
|
flickerstreak@1
|
237 self:RegisterEvent("TRADE_SKILL_CLOSE", "CRAFT_SHOW")
|
flickerstreak@1
|
238 self:RegisterEvent("PLAYER_ENTER_COMBAT", "CRAFT_SHOW")
|
flickerstreak@1
|
239 self:RegisterEvent("PLAYER_LEAVE_COMBAT")
|
flickerstreak@1
|
240 self:RegisterEvent("START_AUTOREPEAT_SPELL")
|
flickerstreak@1
|
241 self:RegisterEvent("STOP_AUTOREPEAT_SPELL")
|
flickerstreak@1
|
242
|
flickerstreak@1
|
243 self.button:SetScript("OnUpdate", function() self:OnUpdate(arg1) end)
|
flickerstreak@1
|
244 self.actionEventsRegistered = true
|
flickerstreak@1
|
245 end
|
flickerstreak@1
|
246
|
flickerstreak@1
|
247 function ReActionButton.prototype:UnregisterActionEvents()
|
flickerstreak@1
|
248 self:UnregisterEvent("ACTIONBAR_UPDATE_STATE")
|
flickerstreak@1
|
249 self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@1
|
250 self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
|
flickerstreak@1
|
251 self:UnregisterEvent("UPDATE_INVENTORY_ALERTS")
|
flickerstreak@1
|
252 self:UnregisterEvent("PLAYER_AURAS_CHANGED")
|
flickerstreak@1
|
253 self:UnregisterEvent("PLAYER_TARGET_CHANGED")
|
flickerstreak@1
|
254 self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
|
flickerstreak@1
|
255 self:UnregisterEvent("CRAFT_SHOW")
|
flickerstreak@1
|
256 self:UnregisterEvent("CRAFT_CLOSE")
|
flickerstreak@1
|
257 self:UnregisterEvent("TRADE_SKILL_SHOW")
|
flickerstreak@1
|
258 self:UnregisterEvent("TRADE_SKILL_CLOSE")
|
flickerstreak@1
|
259 self:UnregisterEvent("PLAYER_ENTER_COMBAT")
|
flickerstreak@1
|
260 self:UnregisterEvent("PLAYER_LEAVE_COMBAT")
|
flickerstreak@1
|
261 self:UnregisterEvent("START_AUTOREPEAT_SPELL")
|
flickerstreak@1
|
262 self:UnregisterEvent("STOP_AUTOREPEAT_SPELL")
|
flickerstreak@1
|
263
|
flickerstreak@1
|
264 self.button:SetScript("OnUpdate", nil)
|
flickerstreak@1
|
265 self.actionEventsRegistered = false
|
flickerstreak@1
|
266 end
|
flickerstreak@1
|
267
|
flickerstreak@1
|
268
|
flickerstreak@1
|
269 -- event handlers
|
flickerstreak@1
|
270 function ReActionButton.prototype:ACTIONBAR_SLOT_CHANGED()
|
flickerstreak@1
|
271 if arg1 == 0 or arg1 == self:GetActionID() then
|
flickerstreak@1
|
272 self:UpdateDisplay()
|
flickerstreak@1
|
273 end
|
flickerstreak@1
|
274 end
|
flickerstreak@1
|
275
|
flickerstreak@1
|
276 function ReActionButton.prototype:PLAYER_ENTERING_WORLD()
|
flickerstreak@1
|
277 self:UpdateDisplay()
|
flickerstreak@1
|
278 end
|
flickerstreak@1
|
279
|
flickerstreak@1
|
280 function ReActionButton.prototype:UPDATE_BINDINGS()
|
flickerstreak@1
|
281 self:UpdateDisplay()
|
flickerstreak@1
|
282 end
|
flickerstreak@1
|
283
|
flickerstreak@1
|
284 function ReActionButton.prototype:ACTIONBAR_SHOWGRID()
|
flickerstreak@1
|
285 self:ShowGridTmp()
|
flickerstreak@1
|
286 end
|
flickerstreak@1
|
287
|
flickerstreak@1
|
288 function ReActionButton.prototype:ACTIONBAR_HIDEGRID()
|
flickerstreak@1
|
289 self:HideGridTmp()
|
flickerstreak@1
|
290 end
|
flickerstreak@1
|
291
|
flickerstreak@1
|
292 function ReActionButton.prototype:ACTIONBAR_UPDATE_STATE()
|
flickerstreak@1
|
293 self:UpdateCheckedState()
|
flickerstreak@1
|
294 end
|
flickerstreak@1
|
295
|
flickerstreak@1
|
296 function ReActionButton.prototype:ACTIONBAR_UPDATE_USABLE()
|
flickerstreak@1
|
297 self:UpdateUsable()
|
flickerstreak@1
|
298 self:UpdateCooldown()
|
flickerstreak@1
|
299 self:ColorHotKey()
|
flickerstreak@1
|
300 end
|
flickerstreak@1
|
301
|
flickerstreak@1
|
302 function ReActionButton.prototype:UNIT_INVENTORY_CHANGED()
|
flickerstreak@1
|
303 if arg1 == "player" then
|
flickerstreak@1
|
304 self:UpdateDisplay()
|
flickerstreak@1
|
305 end
|
flickerstreak@1
|
306 end
|
flickerstreak@1
|
307
|
flickerstreak@1
|
308 function ReActionButton.prototype:CRAFT_SHOW()
|
flickerstreak@1
|
309 self:UpdateCheckedState()
|
flickerstreak@1
|
310 end
|
flickerstreak@1
|
311
|
flickerstreak@1
|
312 function ReActionButton.prototype:PLAYER_ENTER_COMBAT()
|
flickerstreak@1
|
313 if IsAttackAction(self:GetActionID()) then
|
flickerstreak@1
|
314 self:StartFlash()
|
flickerstreak@1
|
315 end
|
flickerstreak@1
|
316 end
|
flickerstreak@1
|
317
|
flickerstreak@1
|
318 function ReActionButton.prototype:PLAYER_LEAVE_COMBAT()
|
flickerstreak@1
|
319 if IsAttackAction(self:GetActionID()) then
|
flickerstreak@1
|
320 self:StopFlash()
|
flickerstreak@1
|
321 end
|
flickerstreak@1
|
322 end
|
flickerstreak@1
|
323
|
flickerstreak@1
|
324 function ReActionButton.prototype:START_AUTOREPEAT_SPELL()
|
flickerstreak@1
|
325 if IsAutoRepeatAction(self:GetActionID()) then
|
flickerstreak@1
|
326 self:StartFlash()
|
flickerstreak@1
|
327 end
|
flickerstreak@1
|
328 end
|
flickerstreak@1
|
329
|
flickerstreak@1
|
330 function ReActionButton.prototype:STOP_AUTOREPEAT_SPELL()
|
flickerstreak@1
|
331 if self:IsFlashing() and not IsAttackAction(self:GetActionID()) then
|
flickerstreak@1
|
332 self:StopFlash()
|
flickerstreak@1
|
333 end
|
flickerstreak@1
|
334 end
|
flickerstreak@1
|
335
|
flickerstreak@1
|
336
|
flickerstreak@1
|
337 -- OnUpdate handler
|
flickerstreak@1
|
338 function ReActionButton.prototype:OnUpdate(elapsed)
|
flickerstreak@1
|
339 local action = self:GetActionID()
|
flickerstreak@1
|
340 local f = self.frames
|
flickerstreak@1
|
341
|
flickerstreak@1
|
342 -- handle flashing
|
flickerstreak@1
|
343 if self:IsFlashing() then
|
flickerstreak@1
|
344 self.flashtime = self.flashtime - elapsed
|
flickerstreak@1
|
345 if self.flashtime <= 0 then
|
flickerstreak@1
|
346 local overtime = -self.flashtime
|
flickerstreak@1
|
347 if overtime >= ATTACK_BUTTON_FLASH_TIME then
|
flickerstreak@1
|
348 overtime = 0
|
flickerstreak@1
|
349 end
|
flickerstreak@1
|
350 self.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
|
flickerstreak@1
|
351
|
flickerstreak@1
|
352 if f.flash:IsVisible() then
|
flickerstreak@1
|
353 f.flash:Hide()
|
flickerstreak@1
|
354 else
|
flickerstreak@1
|
355 f.flash:Show()
|
flickerstreak@1
|
356 end
|
flickerstreak@1
|
357 end
|
flickerstreak@1
|
358 end
|
flickerstreak@1
|
359
|
flickerstreak@1
|
360 -- Handle range indicator
|
flickerstreak@1
|
361 if self.rangeTimer then
|
flickerstreak@1
|
362 self.rangeTimer = self.rangeTimer - elapsed
|
flickerstreak@1
|
363 if self.rangeTimer <= 0 then
|
flickerstreak@1
|
364 self:ColorHotKey()
|
flickerstreak@1
|
365 self:UpdateUsable()
|
flickerstreak@1
|
366 self.rangeTimer = TOOLTIP_UPDATE_TIME
|
flickerstreak@1
|
367 end
|
flickerstreak@1
|
368 end
|
flickerstreak@1
|
369
|
flickerstreak@1
|
370 -- handle toltip update
|
flickerstreak@1
|
371 if self.tooltipTime then
|
flickerstreak@1
|
372 self.tooltipTime = self.tooltipTime - elapsed
|
flickerstreak@1
|
373 if self.tooltipTime <= 0 then
|
flickerstreak@1
|
374 if GameTooltip:IsOwned(self.button) then
|
flickerstreak@1
|
375 self:UpdateTooltip()
|
flickerstreak@1
|
376 else
|
flickerstreak@1
|
377 self.tooltipTime = nil
|
flickerstreak@1
|
378 end
|
flickerstreak@1
|
379 end
|
flickerstreak@1
|
380 end
|
flickerstreak@1
|
381 end
|
flickerstreak@1
|
382
|
flickerstreak@1
|
383
|
flickerstreak@1
|
384
|
flickerstreak@1
|
385
|
flickerstreak@1
|
386 -- keybinding functions
|
flickerstreak@1
|
387 function ReActionButton.prototype:SetKeyBinding( k )
|
flickerstreak@1
|
388 if k == nil or kbValidate(k) then
|
flickerstreak@1
|
389 local current = self:GetKeyBinding()
|
flickerstreak@1
|
390 ClearOverrideBindings(self.button)
|
flickerstreak@1
|
391 if current then
|
flickerstreak@1
|
392 SetBinding(current,nil)
|
flickerstreak@1
|
393 end
|
flickerstreak@1
|
394 if k then
|
flickerstreak@1
|
395 SetBindingClick(k, self.name, "LeftButton")
|
flickerstreak@1
|
396 end
|
flickerstreak@1
|
397 end
|
flickerstreak@1
|
398 end
|
flickerstreak@1
|
399
|
flickerstreak@1
|
400 function ReActionButton.prototype:GetKeyBinding()
|
flickerstreak@1
|
401 return GetBindingKey("CLICK "..self.name..":LeftButton")
|
flickerstreak@1
|
402 end
|
flickerstreak@1
|
403
|
flickerstreak@1
|
404 -- action ID functions
|
flickerstreak@1
|
405 function ReActionButton.prototype:SetActionID( id )
|
flickerstreak@2
|
406 self.actionID = tonumber(id) -- force data integrity
|
flickerstreak@1
|
407 self:ApplyActionID()
|
flickerstreak@1
|
408 end
|
flickerstreak@1
|
409
|
flickerstreak@1
|
410 function ReActionButton.prototype:GetActionID()
|
flickerstreak@2
|
411 return self.actionID
|
flickerstreak@1
|
412 end
|
flickerstreak@1
|
413
|
flickerstreak@1
|
414 function ReActionButton.prototype:ApplyActionID()
|
flickerstreak@1
|
415 local action = tonumber(self:GetActionID())
|
flickerstreak@2
|
416 self.button:SetAttribute("action",action)
|
flickerstreak@1
|
417 self.frames.actionID:SetText(action or "")
|
flickerstreak@1
|
418 end
|
flickerstreak@1
|
419
|
flickerstreak@1
|
420 function ReActionButton.prototype:ShowActionID()
|
flickerstreak@1
|
421 self.frames.actionID:Show()
|
flickerstreak@1
|
422 end
|
flickerstreak@1
|
423
|
flickerstreak@1
|
424 function ReActionButton.prototype:HideActionID()
|
flickerstreak@1
|
425 self.frames.actionID:Hide()
|
flickerstreak@1
|
426 end
|
flickerstreak@1
|
427
|
flickerstreak@1
|
428 function ReActionButton:ShowAllActionIDs() -- class-wide function
|
flickerstreak@1
|
429 for _, tbl in pairs(actionButtonTbl) do
|
flickerstreak@1
|
430 if tbl.button then tbl.button:ShowActionID() end
|
flickerstreak@1
|
431 end
|
flickerstreak@1
|
432 end
|
flickerstreak@1
|
433
|
flickerstreak@1
|
434 function ReActionButton:HideAllActionIDs() -- class-wide function
|
flickerstreak@1
|
435 for _, tbl in pairs(actionButtonTbl) do
|
flickerstreak@1
|
436 if tbl.button then tbl.button:HideActionID() end
|
flickerstreak@1
|
437 end
|
flickerstreak@1
|
438 end
|
flickerstreak@1
|
439
|
flickerstreak@1
|
440
|
flickerstreak@1
|
441 -- action transfer functions
|
flickerstreak@1
|
442 function ReActionButton.prototype:ShouldPickupAction(mouseButton)
|
flickerstreak@1
|
443 return IsShiftKeyDown() and not SecureButton_GetModifiedAttribute(self.button, "type", mouseButton)
|
flickerstreak@1
|
444 end
|
flickerstreak@1
|
445
|
flickerstreak@1
|
446 function ReActionButton.prototype:ShowGridTmp()
|
flickerstreak@2
|
447 self.showGridTmp_ = self.showGridTmp_ + 1
|
flickerstreak@1
|
448 self:UpdateVisibility()
|
flickerstreak@1
|
449 end
|
flickerstreak@1
|
450
|
flickerstreak@1
|
451 function ReActionButton.prototype:HideGridTmp()
|
flickerstreak@2
|
452 self.showGridTmp_ = self.showGridTmp_ - 1
|
flickerstreak@1
|
453 self:UpdateVisibility()
|
flickerstreak@1
|
454 end
|
flickerstreak@1
|
455
|
flickerstreak@1
|
456 function ReActionButton.prototype:ShowGrid()
|
flickerstreak@1
|
457 self.config.showGrid = true
|
flickerstreak@2
|
458 self:UpdateVisibility()
|
flickerstreak@1
|
459 end
|
flickerstreak@1
|
460
|
flickerstreak@1
|
461 function ReActionButton.prototype:HideGrid()
|
flickerstreak@1
|
462 self.config.showGrid = false
|
flickerstreak@2
|
463 self:UpdateVisibility()
|
flickerstreak@1
|
464 end
|
flickerstreak@1
|
465
|
flickerstreak@1
|
466
|
flickerstreak@1
|
467
|
flickerstreak@1
|
468 -- layout & style functions
|
flickerstreak@1
|
469 function ReActionButton.prototype:ApplyLayout()
|
flickerstreak@1
|
470 local f = self.frames
|
flickerstreak@1
|
471
|
flickerstreak@1
|
472 if self.config.keyBindLoc then
|
flickerstreak@1
|
473 local h = f.hotkey
|
flickerstreak@1
|
474 local loc = self.config.keyBindLoc
|
flickerstreak@2
|
475 local top = string.match(loc,"TOP")
|
flickerstreak@2
|
476 local bottom = string.match(loc, "BOTTOM")
|
flickerstreak@1
|
477 h:ClearAllPoints()
|
flickerstreak@2
|
478 h:SetWidth(40)
|
flickerstreak@2
|
479 h:SetPoint(top or bottom,0,top and 2 or -2)
|
flickerstreak@1
|
480 local j
|
flickerstreak@1
|
481 if string.match(loc,"LEFT") then
|
flickerstreak@1
|
482 j = "LEFT"
|
flickerstreak@1
|
483 elseif string.match(loc,"RIGHT") then
|
flickerstreak@1
|
484 j = "RIGHT"
|
flickerstreak@1
|
485 else
|
flickerstreak@1
|
486 j = "CENTER"
|
flickerstreak@1
|
487 end
|
flickerstreak@1
|
488 h:SetJustifyH(j)
|
flickerstreak@1
|
489 end
|
flickerstreak@1
|
490
|
flickerstreak@1
|
491 if self.config.stackCountLoc then
|
flickerstreak@1
|
492 local c = f.count
|
flickerstreak@1
|
493 local loc = self.config.stackCountLoc
|
flickerstreak@2
|
494 local top = string.match(loc,"TOP")
|
flickerstreak@2
|
495 local bottom = string.match(loc, "BOTTOM")
|
flickerstreak@1
|
496 c:ClearAllPoints()
|
flickerstreak@2
|
497 c:SetWidth(40)
|
flickerstreak@2
|
498 c:SetPoint(top or bottom,0,top and 2 or -2)
|
flickerstreak@1
|
499 local j
|
flickerstreak@1
|
500 if string.match(loc,"LEFT") then
|
flickerstreak@1
|
501 j = "LEFT"
|
flickerstreak@1
|
502 elseif string.match(loc,"RIGHT") then
|
flickerstreak@1
|
503 j = "RIGHT"
|
flickerstreak@1
|
504 else
|
flickerstreak@1
|
505 j = "CENTER"
|
flickerstreak@1
|
506 end
|
flickerstreak@1
|
507 c:SetJustifyH(j)
|
flickerstreak@1
|
508 end
|
flickerstreak@1
|
509
|
flickerstreak@1
|
510 if self.config.showKeyBind then
|
flickerstreak@1
|
511 f.hotkey:Show()
|
flickerstreak@1
|
512 else
|
flickerstreak@1
|
513 f.hotkey:Hide()
|
flickerstreak@1
|
514 end
|
flickerstreak@1
|
515
|
flickerstreak@1
|
516 if self.config.showStackCount then
|
flickerstreak@1
|
517 f.count:Show()
|
flickerstreak@1
|
518 else
|
flickerstreak@1
|
519 f.count:Hide()
|
flickerstreak@1
|
520 end
|
flickerstreak@1
|
521
|
flickerstreak@1
|
522 --[[
|
flickerstreak@1
|
523 if self.config.showNumericCooldown then
|
flickerstreak@1
|
524 f.nCooldown:Show()
|
flickerstreak@1
|
525 else
|
flickerstreak@1
|
526 f.nCooldown:Hide()
|
flickerstreak@1
|
527 end
|
flickerstreak@1
|
528 ]]
|
flickerstreak@1
|
529
|
flickerstreak@1
|
530 if self.config.showMacroName then
|
flickerstreak@1
|
531 f.macro:Show()
|
flickerstreak@1
|
532 else
|
flickerstreak@1
|
533 f.macro:Hide()
|
flickerstreak@1
|
534 end
|
flickerstreak@1
|
535 end
|
flickerstreak@1
|
536
|
flickerstreak@1
|
537 function ReActionButton.prototype:ApplyStyle()
|
flickerstreak@1
|
538 local f = self.frames
|
flickerstreak@1
|
539 -- for now, just a static style
|
flickerstreak@1
|
540 f.hotkey:SetFontObject(NumberFontNormal)
|
flickerstreak@1
|
541 f.count:SetFontObject(NumberFontNormalYellow)
|
flickerstreak@1
|
542 end
|
flickerstreak@1
|
543
|
flickerstreak@1
|
544
|
flickerstreak@1
|
545
|
flickerstreak@1
|
546 -- start/stop flashing
|
flickerstreak@1
|
547 function ReActionButton.prototype:StartFlash()
|
flickerstreak@1
|
548 self.flashing = true
|
flickerstreak@1
|
549 self.flashtime = 0
|
flickerstreak@1
|
550 self:UpdateCheckedState()
|
flickerstreak@1
|
551 end
|
flickerstreak@1
|
552
|
flickerstreak@1
|
553 function ReActionButton.prototype:StopFlash()
|
flickerstreak@1
|
554 self.flashing = false
|
flickerstreak@1
|
555 self.frames.flash:Hide()
|
flickerstreak@1
|
556 self:UpdateCheckedState()
|
flickerstreak@1
|
557 end
|
flickerstreak@1
|
558
|
flickerstreak@1
|
559 function ReActionButton.prototype:IsFlashing()
|
flickerstreak@1
|
560 return self.flashing
|
flickerstreak@1
|
561 end
|
flickerstreak@1
|
562
|
flickerstreak@1
|
563
|
flickerstreak@1
|
564
|
flickerstreak@1
|
565
|
flickerstreak@1
|
566
|
flickerstreak@1
|
567 -- set the tooltip
|
flickerstreak@1
|
568 function ReActionButton.prototype:SetTooltip()
|
flickerstreak@1
|
569 GameTooltip_SetDefaultAnchor(GameTooltip, self.button)
|
flickerstreak@1
|
570 self:UpdateTooltip()
|
flickerstreak@1
|
571 end
|
flickerstreak@1
|
572
|
flickerstreak@1
|
573 function ReActionButton.prototype:ClearTooltip()
|
flickerstreak@1
|
574 tooltipTime = nil
|
flickerstreak@1
|
575 GameTooltip:Hide()
|
flickerstreak@1
|
576 end
|
flickerstreak@1
|
577
|
flickerstreak@1
|
578
|
flickerstreak@1
|
579
|
flickerstreak@1
|
580 -- colorize the hotkey
|
flickerstreak@1
|
581 function ReActionButton.prototype:ColorHotKey()
|
flickerstreak@1
|
582 local action = self:GetActionID()
|
flickerstreak@1
|
583 local c = hotKeyDefaultColor
|
flickerstreak@1
|
584
|
flickerstreak@1
|
585 if action and HasAction(action) then
|
flickerstreak@1
|
586 if IsActionInRange(action) == 0 then
|
flickerstreak@1
|
587 c = hotKeyOutOfRangeColor
|
flickerstreak@1
|
588 elseif self.config.keyBindColorCode then
|
flickerstreak@1
|
589 local modKey = string.match( self.frames.hotkey:GetText() or "", "([ACS])%-")
|
flickerstreak@1
|
590 c = modKey and hotKeyModifierColors[modKey] or c
|
flickerstreak@1
|
591 end
|
flickerstreak@1
|
592 else
|
flickerstreak@1
|
593 c = hotKeyDisabledColor
|
flickerstreak@1
|
594 end
|
flickerstreak@1
|
595
|
flickerstreak@1
|
596 self.frames.hotkey:SetTextColor(c.r, c.g, c.b)
|
flickerstreak@1
|
597 end
|
flickerstreak@1
|
598
|
flickerstreak@1
|
599
|
flickerstreak@1
|
600
|
flickerstreak@1
|
601
|
flickerstreak@1
|
602 -- display update functions
|
flickerstreak@1
|
603 function ReActionButton.prototype:UpdateDisplay()
|
flickerstreak@1
|
604 self:UpdateIcon()
|
flickerstreak@1
|
605 self:UpdateHotkey()
|
flickerstreak@1
|
606 self:UpdateCount()
|
flickerstreak@1
|
607 self:UpdateMacroText()
|
flickerstreak@1
|
608 self:UpdateUsable()
|
flickerstreak@1
|
609 self:UpdateCooldown()
|
flickerstreak@1
|
610 self:UpdateFlash()
|
flickerstreak@1
|
611 self:UpdateEvents()
|
flickerstreak@1
|
612 self:UpdateVisibility()
|
flickerstreak@1
|
613 self:UpdateTooltip()
|
flickerstreak@1
|
614 end
|
flickerstreak@1
|
615
|
flickerstreak@1
|
616 function ReActionButton.prototype:UpdateIcon()
|
flickerstreak@1
|
617 local f = self.frames
|
flickerstreak@1
|
618 local b = self.button
|
flickerstreak@1
|
619
|
flickerstreak@1
|
620 local action = self:GetActionID()
|
flickerstreak@1
|
621 local texture = action and GetActionTexture(action)
|
flickerstreak@1
|
622
|
flickerstreak@1
|
623 if action and texture then
|
flickerstreak@1
|
624 f.icon:SetTexture(texture)
|
flickerstreak@1
|
625 f.icon:Show()
|
flickerstreak@1
|
626 self.rangeTimer = -1
|
flickerstreak@1
|
627 b:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
|
flickerstreak@1
|
628 else
|
flickerstreak@1
|
629 f.icon:Hide()
|
flickerstreak@1
|
630 f.cooldown:Hide()
|
flickerstreak@1
|
631 self.rangeTimer = nil
|
flickerstreak@1
|
632 b:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
|
flickerstreak@1
|
633 end
|
flickerstreak@1
|
634
|
flickerstreak@1
|
635 self:UpdateCheckedState()
|
flickerstreak@1
|
636
|
flickerstreak@1
|
637 -- Add a green border if action is an equipped item
|
flickerstreak@1
|
638 if action and IsEquippedAction(action) then
|
flickerstreak@1
|
639 local c = equippedActionBorderColor
|
flickerstreak@1
|
640 f.border:SetVertexColor(c.r, c.g, c.b, c.a or 1)
|
flickerstreak@1
|
641 f.border:Show()
|
flickerstreak@1
|
642 else
|
flickerstreak@1
|
643 f.border:Hide()
|
flickerstreak@1
|
644 end
|
flickerstreak@1
|
645 end
|
flickerstreak@1
|
646
|
flickerstreak@1
|
647 function ReActionButton.prototype:UpdateCheckedState()
|
flickerstreak@1
|
648 local action = self:GetActionID()
|
flickerstreak@1
|
649 if action and (IsCurrentAction(action) or IsAutoRepeatAction(action)) then
|
flickerstreak@1
|
650 self.button:SetChecked(1)
|
flickerstreak@1
|
651 else
|
flickerstreak@1
|
652 self.button:SetChecked(0)
|
flickerstreak@1
|
653 end
|
flickerstreak@1
|
654 end
|
flickerstreak@1
|
655
|
flickerstreak@1
|
656
|
flickerstreak@1
|
657 function ReActionButton.prototype:UpdateHotkey()
|
flickerstreak@1
|
658 local action = self:GetActionID()
|
flickerstreak@1
|
659 local b = self.button
|
flickerstreak@1
|
660 local f = self.frames
|
flickerstreak@1
|
661 local key = self:GetKeyBinding()
|
flickerstreak@1
|
662 local txt = GetBindingText(key, "KEY_",1)
|
flickerstreak@1
|
663
|
flickerstreak@2
|
664 -- abbreviate long key names
|
flickerstreak@2
|
665 for pat, rep in pairs(keybindAbbreviations) do
|
flickerstreak@2
|
666 txt = string.gsub(txt,pat,rep)
|
flickerstreak@2
|
667 end
|
flickerstreak@2
|
668
|
flickerstreak@1
|
669 if txt then
|
flickerstreak@1
|
670 f.hotkey:SetText(string.upper(txt))
|
flickerstreak@1
|
671 self:ColorHotKey()
|
flickerstreak@1
|
672 else
|
flickerstreak@1
|
673 f.hotkey:SetText("")
|
flickerstreak@1
|
674 end
|
flickerstreak@1
|
675 end
|
flickerstreak@1
|
676
|
flickerstreak@1
|
677 function ReActionButton.prototype:UpdateCount()
|
flickerstreak@1
|
678 local action = self:GetActionID()
|
flickerstreak@1
|
679 if action and (IsConsumableAction(action) or IsStackableAction(action)) then
|
flickerstreak@1
|
680 self.frames.count:SetText(GetActionCount(action))
|
flickerstreak@1
|
681 else
|
flickerstreak@1
|
682 self.frames.count:SetText("")
|
flickerstreak@1
|
683 end
|
flickerstreak@1
|
684 end
|
flickerstreak@1
|
685
|
flickerstreak@1
|
686 function ReActionButton.prototype:UpdateMacroText()
|
flickerstreak@1
|
687 local action = self:GetActionID()
|
flickerstreak@1
|
688 self.frames.macro:SetText(action and GetActionText(action) or "")
|
flickerstreak@1
|
689 end
|
flickerstreak@1
|
690
|
flickerstreak@1
|
691 function ReActionButton.prototype:UpdateUsable()
|
flickerstreak@1
|
692 local f = self.frames
|
flickerstreak@1
|
693 local action = self:GetActionID()
|
flickerstreak@1
|
694 local isUsable, notEnoughMana
|
flickerstreak@1
|
695 if action then
|
flickerstreak@1
|
696 isUsable, notEnoughMana = IsUsableAction(action)
|
flickerstreak@1
|
697 end
|
flickerstreak@1
|
698 if isUsable then
|
flickerstreak@1
|
699 local c = actionUsableColor
|
flickerstreak@1
|
700 if IsActionInRange(action) == 0 then
|
flickerstreak@1
|
701 c = actionOutOfRangeColor
|
flickerstreak@1
|
702 else
|
flickerstreak@1
|
703 f.normalTexture:SetVertexColor(c.r, c.g, c.b, c.a)
|
flickerstreak@1
|
704 end
|
flickerstreak@1
|
705 f.icon:SetVertexColor(c.r, c.g, c.b, c.a)
|
flickerstreak@1
|
706 elseif notEnoughMana then
|
flickerstreak@1
|
707 local c = actionNotEnoughManaColor
|
flickerstreak@1
|
708 f.icon:SetVertexColor(c.r, c.g, c.b, c.a)
|
flickerstreak@1
|
709 f.normalTexture:SetVertexColor(c.r, c.g, c.b, c.a)
|
flickerstreak@1
|
710 else
|
flickerstreak@1
|
711 local c = actionNotUsableColor
|
flickerstreak@1
|
712 f.icon:SetVertexColor(c.r, c.g, c.b, c.a)
|
flickerstreak@1
|
713 f.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
|
flickerstreak@1
|
714 end
|
flickerstreak@1
|
715 end
|
flickerstreak@1
|
716
|
flickerstreak@1
|
717 function ReActionButton.prototype:UpdateCooldown()
|
flickerstreak@1
|
718 local action = self:GetActionID()
|
flickerstreak@1
|
719 if action then
|
flickerstreak@1
|
720 local start, duration, enable = GetActionCooldown(self:GetActionID())
|
flickerstreak@1
|
721 CooldownFrame_SetTimer(self.frames.cooldown, start, duration, enable)
|
flickerstreak@1
|
722 -- do numeric cooldown stuff here
|
flickerstreak@1
|
723 end
|
flickerstreak@1
|
724 end
|
flickerstreak@1
|
725
|
flickerstreak@1
|
726 function ReActionButton.prototype:UpdateFlash()
|
flickerstreak@1
|
727 local b = self.button
|
flickerstreak@1
|
728 local action = self:GetActionID()
|
flickerstreak@1
|
729 if action and ((IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action)) then
|
flickerstreak@1
|
730 self:StartFlash()
|
flickerstreak@1
|
731 else
|
flickerstreak@1
|
732 self:StopFlash()
|
flickerstreak@1
|
733 end
|
flickerstreak@1
|
734 end
|
flickerstreak@1
|
735
|
flickerstreak@1
|
736 function ReActionButton.prototype:UpdateVisibility()
|
flickerstreak@1
|
737 local action = self:GetActionID()
|
flickerstreak@1
|
738 local b = self.button
|
flickerstreak@1
|
739
|
flickerstreak@1
|
740 if b:GetAttribute("statehidden") then
|
flickerstreak@1
|
741 b:Hide()
|
flickerstreak@1
|
742 elseif action and HasAction(action) then
|
flickerstreak@1
|
743 b:GetNormalTexture():SetAlpha(1.0)
|
flickerstreak@1
|
744 b:Show()
|
flickerstreak@2
|
745 elseif self.showGridTmp_ > 0 or self.config.showGrid then
|
flickerstreak@1
|
746 b:GetNormalTexture():SetAlpha(0.5)
|
flickerstreak@1
|
747 self.frames.cooldown:Hide()
|
flickerstreak@1
|
748 b:Show()
|
flickerstreak@1
|
749 else
|
flickerstreak@1
|
750 b:Hide()
|
flickerstreak@1
|
751 end
|
flickerstreak@1
|
752 end
|
flickerstreak@1
|
753
|
flickerstreak@1
|
754 function ReActionButton.prototype:UpdateEvents()
|
flickerstreak@1
|
755 local action = self:GetActionID()
|
flickerstreak@1
|
756 if action and HasAction(action) then
|
flickerstreak@1
|
757 self:RegisterActionEvents()
|
flickerstreak@1
|
758 elseif self.actionEventsRegistered then
|
flickerstreak@1
|
759 self:UnregisterActionEvents()
|
flickerstreak@1
|
760 end
|
flickerstreak@1
|
761 end
|
flickerstreak@1
|
762
|
flickerstreak@1
|
763 function ReActionButton.prototype:UpdateTooltip()
|
flickerstreak@1
|
764 local action = self:GetActionID()
|
flickerstreak@2
|
765 if GameTooltip:IsOwned(self.button) and action and GameTooltip:SetAction(action) then
|
flickerstreak@1
|
766 self.tooltipTime = TOOLTIP_UPDATE_TIME
|
flickerstreak@1
|
767 else
|
flickerstreak@1
|
768 self.tooltipTime = nil
|
flickerstreak@1
|
769 end
|
flickerstreak@1
|
770 end
|
flickerstreak@1
|
771
|
flickerstreak@1
|
772
|
flickerstreak@1
|
773
|