| 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 |