4 local format = string.format;
5 local ssub = string.sub;
6 local GetActionInfo, GetActionTexture = GetActionInfo, GetActionTexture;
7 local GetActionLossOfControlCooldown = GetActionLossOfControlCooldown;
8 local GetActionCooldown, GetActionCharges = GetActionCooldown, GetActionCharges;
9 local IsConsumableAction, IsStackableAction = IsConsumableAction, IsStackableAction;
10 local IsItemAction, GetActionCount = IsItemAction, GetActionCount;
11 local IsSpellOverlayed, GetMacroSpell = IsSpellOverlayed, GetMacroSpell;
12 local IsMounted = IsMounted;
13 local HasAction, IsUsableAction = HasAction, IsUsableAction;
14 local IsCurrentAction, IsAutoRepeatAction = IsCurrentAction, IsAutoRepeatAction;
15 local CreateFrame = CreateFrame;
16 local RegisterStateDriver = RegisterStateDriver;
17 local CooldownFrame_Set, CooldownFrame_Clear = CooldownFrame_Set, CooldownFrame_Clear;
18 local CTimerAfter = C_Timer.After;
19 local GameTooltip = GameTooltip;
20 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor;
21 local COOLDOWN_TYPE_LOSS_OF_CONTROL = COOLDOWN_TYPE_LOSS_OF_CONTROL;
22 local COOLDOWN_TYPE_NORMAL = COOLDOWN_TYPE_NORMAL;
23 local CDTexture = "Interface\\Cooldown\\edge";
24 local locCDTexture = "Interface\\Cooldown\\edge-LoC";
26 local BUTTONLOCK = true; -- change to lock button dragging
81 -- used as bonus bars for some classes
112 local usingBonusbars = {
113 --["WARRIOR"] = {[7]=true, [8]=true, [9]=true}, -- not using stance separated actionbars
114 ["DRUID"] = {[7]=true, [8]=true, [9]=true}, -- moonkin form page is usable anyway
115 --["DRUID"] = {[7]=true, [8]=true, [9]=true,[10]=true},
116 ["ROGUE"] = {[7]=true},
117 --["PRIEST"] = {[7]=true}, -- shadowform doesn't change abilities
122 ["Vildan"] = {1, 2, 3, 4,},
123 ["Gedren"] = {1, 2, 3, 4,},
124 ["Gazden"] = {1, 2, 3, 4,},
129 local activeButtons = {};
131 local ActionBars = CreateFrame("Frame", "OmaActionBars", UIParent);
132 local inheritedFrames =
133 "SecureActionButtonTemplate,SecureHandlerDragTemplate,SecureHandlerStateTemplate";
135 local function showTooltip(secure)
136 GameTooltip_SetDefaultAnchor(GameTooltip, secure);
137 GameTooltip:SetAction(secure:GetAttribute("action"));
140 local function hideTooltip()
144 local numChargeCDs = 0;
145 local function createChargeCD(parent)
146 numChargeCDs = numChargeCDs + 1;
147 local frame = CreateFrame("Cooldown", "OmaChargeCD"..numChargeCDs, parent, "CooldownFrameTemplate");
148 frame:SetHideCountdownNumbers(false);
149 frame:SetDrawSwipe(false);
150 frame:SetAllPoints(parent);
151 frame:SetFrameStrata("TOOLTIP");
155 local function clearChargeCD(parent)
156 if parent.chargecd then CooldownFrame_Clear(parent.chargecd) end
159 local function startChargeCD(parent, start, duration, modrate)
161 return clearChargeCD(parent);
163 parent.chargecd = parent.chargecd or createChargeCD(parent);
164 CooldownFrame_Set(parent.chargecd, start, duration, true, true, modrate);
169 local function updateCooldown(button, slot)
170 -- CD update from FrameXML/ActionButton.lua
171 local locstart, locduration = GetActionLossOfControlCooldown(slot);
172 local start, duration, enable, modrate = GetActionCooldown(slot);
173 local charges, maxcharges, chargestart, chargeduration, chargemodrate = GetActionCharges(slot);
174 if (locstart + locduration) > (start + duration) then
175 if button.cd.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
176 button.cd:SetEdgeTexture(locCDTexture);
177 button.cd:SetSwipeColor(0.17, 0, 0);
178 button.cd:SetHideCountdownNumbers(true);
179 button.cd.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL;
182 CooldownFrame_Set(button.cd, locstart, locduration, true, true, modrate);
183 clearChargeCD(button);
185 if button.cd.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
186 button.cd:SetEdgeTexture(CDTexture);
187 button.cd:SetSwipeColor(0, 0, 0);
188 button.cd:SetHideCountdownNumbers(false);
189 button.cd.currentCooldownType = COOLDOWN_TYPE_NORMAL;
193 button.cd:SetScript("OnCooldownDone", redoCooldown);
195 if charges and maxcharges and maxcharges > 1 and charges < maxcharges then
196 startChargeCD(button, chargestart, chargeduration, chargemodrate);
198 clearChargeCD(button);
200 CooldownFrame_Set(button.cd, start, duration, enable, false, modrate);
204 local function redoCooldown(cd)
205 local button = cd:GetParent();
206 cd:SetScript("OnCooldownDone", nil);
207 updateCooldown(button, button.slot);
210 local function updateCount(button, slot)
211 if IsConsumableAction(slot) or IsStackableAction(slot) or
212 (not IsItemAction(slot) and GetActionCount(slot) > 0) then
213 local count = GetActionCount(slot);
215 button.count:SetText("*");
217 button.count:SetText(count);
221 local charges, maxcharges = GetActionCharges(slot);
222 if maxcharges > 1 then
223 button.count:SetText(charges);
231 local function updateUsable(button, slot)
232 local isUsable, noMana = IsUsableAction(slot);
234 button.icon:SetVertexColor(1, 1, 1);
236 button.icon:SetVertexColor(0, 0.5, 1);
238 button.icon:SetVertexColor(0.4, 0.4, 0.4);
242 local function updateState(button, slot)
243 button:SetChecked(IsCurrentAction(slot) or IsAutoRepeatAction(slot));
246 local function updateGlow(button, slot)
247 local stype, id, _ = GetActionInfo(slot);
248 if stype == "spell" and IsSpellOverlayed(id) then
250 elseif stype == "macro" then
251 local _, _, macroid = GetMacroSpell(id);
252 if macroid and IsSpellOverlayed(macroid) then
257 else -- TODO FlyoutHasSpell glow
262 local function startGlow(button, slot, spell)
263 local stype, id, _ = GetActionInfo(slot);
264 if stype == "spell" and id == spell then
266 elseif stype == "macro" then
267 local _, _, macroid = GetMacroSpell(id);
268 if macroid and macroid == spell then
272 -- TODO FlyoutHasSpell glow
275 local function stopGlow(button, slot, spell)
276 local stype, id, _ = GetActionInfo(slot);
277 if stype == "spell" and id == spell then
279 elseif stype == "macro" then
280 local _, _, macroid = GetMacroSpell(id);
281 if macroid and macroid == spell then
285 -- TODO FlyoutHasSpell glow
288 local function updateButton(button, slot)
289 if HasAction(slot) then
290 activeButtons[slot] = button;
292 button.icon:SetTexture(GetActionTexture(slot));
293 updateCooldown(button, slot);
294 updateUsable(button, slot);
295 updateState(button, slot);
296 updateCount(button, slot);
297 updateGlow(button, slot);
298 if not IsConsumableAction(slot) and not IsStackableAction(slot) then
299 button.text:SetText(ssub(GetActionText(slot) or "", 1, 4));
302 if button.hotkey.shown then button.hotkey:Show() end
304 activeButtons[slot] = nil;
305 if not button.grid then button.base:Hide() end
306 button.icon:SetTexture(nil);
309 button.hotkey:Hide();
312 button:SetChecked(false);
316 local function updateHotkeys(button)
317 local key = GetBindingKey(format("CLICK %s:LeftButton", button:GetName()));
318 if key and key ~= "" then
319 -- from LibKeyBound-1.0
321 key = key:gsub(" ", "");
322 key = key:gsub("ALT%-", "a");
323 key = key:gsub("CTRL%-", "c");
324 key = key:gsub("SHIFT%-", "s");
325 key = key:gsub("NUMPAD", "n");
326 button.hotkey:SetText(key);
327 button.hotkey.shown = true;
328 button.hotkey:Show();
330 button.hotkey.shown = nil;
331 button.hotkey:Hide();
335 local mainbartoggle = "[overridebar][possessbar][shapeshift]possess;";
336 mainbartoggle = mainbartoggle.."[bonusbar:1,stealth:1]bonusbar2;"; -- prowl
337 mainbartoggle = mainbartoggle.."[bonusbar:1]bonusbar1;[bonusbar:2]bonusbar2;"; -- cat form, unused
338 mainbartoggle = mainbartoggle.."[bonusbar:3]bonusbar3;[bonusbar:4]bonusbar4;"; -- bear form, moonkin form
339 mainbartoggle = mainbartoggle.."normal";
340 local function setupSnippets(secure, slot)
341 -- FrameXML/SecureHandlers.lua has arguments and return value
342 -- args: self, button, kind, value, ... (kind, value, ... from GetCursorInfo())
343 -- returns: kind, target, detail
344 -- or: "clear", kind, target, detail
345 -- used for Pickup* functions
346 -- some of these snippets based on LibActionButton-1.0
347 secure:SetAttribute("_ondragstart", [=[
348 return "action", self:GetAttribute("action");
350 secure:SetAttribute("_onreceivedrag", [=[
351 if not kind or not value then return nil end
352 return "action", self:GetAttribute("action");
354 -- pre-wrapper can pass a message to post-wrapper
355 secure:WrapScript(secure, "OnDragStart", [=[
356 local kind, value = GetActionInfo(self:GetAttribute("action"));
357 return "message", format("%s|%s", tostring(kind), tostring(value));
359 local kind, value = GetActionInfo(self:GetAttribute("action"));
360 if message ~= format("%s|%s", tostring(kind), tostring(value)) then
361 self:CallMethod("ActionChanged");
364 secure:WrapScript(secure, "OnReceiveDrag", [=[
365 local kind, value = GetActionInfo(self:GetAttribute("action"));
366 return "message", format("%s|%s", tostring(kind), tostring(value));
368 local kind, value = GetActionInfo(self:GetAttribute("action"));
369 if message ~= format("%s|%s", tostring(kind), tostring(value)) then
370 self:CallMethod("ActionChanged");
373 function secure:UpdateState()
374 return updateState(self, self.slot);
376 secure:WrapScript(secure, "OnClick", [=[
377 local kind, value = GetActionInfo(self:GetAttribute("action"));
378 return nil, format("%s|%s", tostring(kind), tostring(value));
380 local kind, value = GetActionInfo(self:GetAttribute("action"));
381 if message ~= format("%s|%s", tostring(kind), tostring(value)) then
382 self:CallMethod("ActionChanged");
384 self:CallMethod("UpdateState");
388 -- first action bar has possible states based on vehicle/possess etc.
389 secure:SetAttribute("origaction", slot);
390 secure:SetAttribute("_onstate-possess", [=[
391 local oldslot = self:GetAttribute("action");
392 if newstate == "possess" then
394 if HasVehicleActionBar() then
395 slot = (GetVehicleBarIndex()-1)*12+self:GetAttribute("origaction");
396 elseif HasOverrideActionBar() then
397 slot = (GetOverrideBarIndex()-1)*12+self:GetAttribute("origaction");
398 elseif HasTempShapeshiftActionBar() then
399 slot = (GetTempShapeshiftBarIndex()-1)*12+self:GetAttribute("origaction");
401 -- something wrong, just revert to normal
402 print("Possess bar index not found");
403 slot = self:GetAttribute("origaction");
405 self:SetAttribute("action", slot);
406 elseif newstate == "bonusbar1" then
407 self:SetAttribute("action", 72+self:GetAttribute("origaction"));
408 elseif newstate == "bonusbar2" then
409 self:SetAttribute("action", 84+self:GetAttribute("origaction"));
410 elseif newstate == "bonusbar3" then
411 self:SetAttribute("action", 96+self:GetAttribute("origaction"));
412 elseif newstate == "bonusbar4" then
413 --self:SetAttribute("action", 108+self:GetAttribute("origaction"));
414 -- moonkin form, don't change actionbar
415 self:SetAttribute("action", self:GetAttribute("origaction"));
417 self:SetAttribute("action", self:GetAttribute("origaction"));
419 self:CallMethod("ActionChanged", oldslot);
421 RegisterStateDriver(secure, "possess", mainbartoggle);
423 function secure:ShowButton() if HasAction(slot) then activeButtons[slot] = self end end
424 function secure:HideButton() activeButtons[slot] = nil end
425 -- all other action bar are hidden if with overridebar or vehicleui (not shapeshift, possessbar)
426 -- default Bartender4 options
427 secure:SetAttribute("_onstate-possess", [=[
428 if newstate == "possess" then
430 self:CallMethod("HideButton");
433 self:CallMethod("ShowButton");
436 RegisterStateDriver(secure, "possess", "[overridebar][vehicleui] possess; normal");
440 local function createActionBar(parent, config)
443 local bar = CreateFrame("Frame", "OmaBTBar"..config.bar, parent, "SecureFrameTemplate");
444 bar:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y);
447 if config.hidden then
450 for slot = config.start, config.start+config.length-1 do
451 local secure = CreateFrame("CheckButton", "OmaBT"..slot, bar, inheritedFrames);
453 if slot == config.start then
454 secure:SetPoint("TOPLEFT");
455 elseif config.columns and i % config.columns == 0 then
456 secure:SetPoint("TOPLEFT", _G["OmaBT"..(slot-config.columns)], "BOTTOMLEFT");
458 secure:SetPoint("TOPLEFT", prev, "TOPRIGHT");
460 secure:RegisterForClicks("AnyUp");
461 if not BUTTONLOCK then
462 secure:RegisterForDrag("LeftButton", "RightButton");
464 if config.nomouse then
465 secure:EnableMouse(false);
467 -- only show tooltips for bars with mouse interaction
468 secure:SetScript("OnEnter", showTooltip);
469 secure:SetScript("OnLeave", hideTooltip);
471 secure:SetWidth(config.size or 32);
472 secure:SetHeight(config.size or 32);
473 secure.base = secure:CreateTexture(nil, "BACKGROUND");
474 secure.base:SetAllPoints();
475 secure.base:SetColorTexture(0, 0, 0, 0.5);
476 secure.iconbase = secure:CreateTexture(nil, "BORDER");
477 secure.iconbase:SetPoint("TOPLEFT", secure.base, "TOPLEFT", 1, -1);
478 secure.iconbase:SetPoint("BOTTOMRIGHT", secure.base, "BOTTOMRIGHT", -1, 1);
479 secure.iconbase:SetColorTexture(0, 0, 0, 0.5);
480 secure.iconbase:Hide();
481 secure.icon = secure:CreateTexture(nil, "ARTWORK");
482 secure.icon:SetPoint("TOPLEFT", secure.iconbase, "TOPLEFT");
483 secure.icon:SetPoint("BOTTOMRIGHT", secure.iconbase, "BOTTOMRIGHT");
484 secure.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
485 secure:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight");
486 secure.autocastable = secure:CreateTexture(nil, "OVERLAY");
487 secure.autocastable:SetPoint("CENTER");
488 secure.autocastable:SetWidth(58);
489 secure.autocastable:SetHeight(58);
490 secure.autocastable:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay");
491 secure.autocastable:Hide();
492 secure.glow = secure:CreateTexture(nil, "OVERLAY", nil, 1);
493 secure.glow:SetPoint("CENTER");
494 secure.glow:SetWidth(config.size and config.size+26 or 53);
495 secure.glow:SetHeight(config.size and config.size+26 or 53);
496 secure.glow:SetTexture("Interface\\SpellActivationOverlay\\IconAlert");
497 secure.glow:SetTexCoord(0.00781250, 0.50781250, 0.27734375, 0.52634375);
499 secure.hotkey = secure:CreateFontString(nil, "OVERLAY", "NumberFontNormalGray");
500 secure.hotkey:SetPoint("TOPRIGHT", secure, "TOPRIGHT", 2, -1);
501 secure.count = secure:CreateFontString(nil, "OVERLAY", "NumberFontNormal");
502 secure.count:SetPoint("BOTTOMRIGHT", secure, "BOTTOMRIGHT", 2, -1);
503 secure.text = secure:CreateFontString(nil, "OVERLAY", "NumberFontNormal");
504 secure.text:SetPoint("BOTTOMLEFT", secure, "BOTTOMLEFT", 2, -1);
506 secure.cd = CreateFrame("Cooldown", "OmaBTCD"..slot, secure, "CooldownFrameTemplate");
507 secure.cd:SetAllPoints();
508 secure:SetAttribute("type", "action");
509 secure:SetAttribute("action", slot);
510 if config.flyout then
511 secure:SetAttribute("flyoutDirection", config.flyout);
513 function secure:ActionChanged(oldslot)
514 if oldslot then activeButtons[oldslot] = nil end
515 self.slot = self:GetAttribute("action");
516 return updateButton(self, self.slot);
518 secure:ActionChanged(); -- initial update
519 setupSnippets(secure, slot);
520 updateHotkeys(secure);
521 buttons[slot] = secure;
527 local function initialize()
528 local _, class = UnitClass("player");
529 local name, realm = UnitFullName("player");
530 ActionBars:SetFrameStrata("LOW");
531 ActionBars:SetPoint("BOTTOMLEFT");
532 ActionBars:SetWidth(1);
533 ActionBars:SetHeight(1);
534 for _, config in pairs(settings) do
535 if (not usingBonusbars[class] or not usingBonusbars[class][config.bar]) and
536 (not chars[realm] or not chars[realm][name] or chars[realm][name][config.bar]) then
537 createActionBar(ActionBars, config);
542 local function setupBindings()
543 BINDING_HEADER_OmaAB = "Oma Action Bar";
545 _G["BINDING_HEADER_OMAABBLANK"..i] = "Bar "..i;
547 _G[format("BINDING_NAME_CLICK OmaBT%d:LeftButton", (i-1)*12+j)] = format("Bar %d Button %d", i, j);
552 local mounted = false;
553 -- throttleCD 3-state, nil -> false -> true -> nil
554 -- this way there's not double update each time the first
555 -- update event comes, instead the extra throttled update comes
556 -- if there are >2 ACTIONBAR_UPDATE_COOLDOWN events in one frame
557 local throttleCD = nil;
558 local function throttleCDDone()
559 -- update CD once more to confirm newest CD change is taken in even with some throttling
560 for _, button in pairs(activeButtons) do
561 updateCooldown(button, button.slot);
564 local function throttleCDReset()
569 ["ACTIONBAR_UPDATE_COOLDOWN"] = function()
570 if not throttleCD then -- only update at most once/frame
571 throttleCD = throttleCD == false and true or false;
573 CTimerAfter(0.01, throttleCDDone); -- wait one frame
575 for _, button in pairs(activeButtons) do
576 updateCooldown(button, button.slot);
578 CTimerAfter(0.01, throttleCDReset); -- wait one frame
582 ["SPELL_UPDATE_CHARGES"] = function()
583 for _, button in pairs(activeButtons) do
584 updateCount(button, button.slot);
587 ["ACTIONBAR_SLOT_CHANGED"] = function(slot)
588 if buttons[slot] then buttons[slot]:ActionChanged() end
590 ["ACTIONBAR_SHOWGRID"] = function()
591 for _, button in pairs(buttons) do
593 button.iconbase:Show();
594 if not activeButtons[button.slot] then button.base:Show() end
597 ["ACTIONBAR_HIDEGRID"] = function()
598 for _, button in pairs(buttons) do
600 button.iconbase:Hide();
601 if not activeButtons[button.slot] then button.base:Hide() end
604 ["ACTIONBAR_UPDATE_STATE"] = function()
605 for _, button in pairs(activeButtons) do
606 updateState(button, button.slot);
609 ["ACTIONBAR_UPDATE_USABLE"] = function()
610 for _, button in pairs(activeButtons) do
611 updateUsable(button, button.slot);
614 ["UPDATE_OVERRIDE_ACTIONBAR"] = function()
615 if buttons[1] then -- called before PLAYER_LOGIN
616 for _, button in pairs(buttons) do
617 updateButton(button, button.slot);
621 ["START_AUTOREPEAT_SPELL"] = function()
622 for _, button in pairs(activeButtons) do
623 if IsAutoRepeatAction(button.slot) then
624 button.autorepeating = true;
625 button.icon:SetVertexColor(0, 1, 0.5);
629 ["STOP_AUTOREPEAT_SPELL"] = function()
630 for _, button in pairs(activeButtons) do
631 if button.autorepeating then
632 button.autorepeating = nil;
633 updateUsable(button, button.slot);
637 ["SPELL_ACTIVATION_OVERLAY_GLOW_SHOW"] = function(spell)
638 -- TODO create mapping from spellIDs to buttons
639 for _, button in pairs(activeButtons) do
640 startGlow(button, button.slot, spell);
643 ["SPELL_ACTIVATION_OVERLAY_GLOW_HIDE"] = function(spell)
644 -- TODO create mapping from spellIDs to buttons
645 for _, button in pairs(activeButtons) do
646 stopGlow(button, button.slot, spell);
649 ["UPDATE_BINDINGS"] = function()
650 for _, button in pairs(buttons) do
651 updateHotkeys(button);
654 ["UNIT_AURA"] = function(unit)
655 -- using UNIT_AURA instead of COMPANION_UPDATE to not update every time
656 -- someone mounts, tracking player mount status with COMPANION_UPDATE is
658 if (not mounted and IsMounted()) or (mounted and not IsMounted()) then
659 mounted = not mounted;
660 for _, button in pairs(activeButtons) do
661 updateState(button, button.slot);
665 ["UPDATE_ALL_BUTTONS"] = function()
666 for _, button in pairs(buttons) do
667 updateButton(button, button.slot);
670 ["PLAYER_LOGIN"] = function()
671 GameTooltip = _G["GameTooltip"];
674 ["ADDON_LOADED"] = function(addon)
675 if addon == "OmaAB" then
677 ActionBars:UnregisterEvent("ADDON_LOADED");
681 events["LOSS_OF_CONTROL_ADDED"] = events["ACTIONBAR_UPDATE_COOLDOWN"];
682 events["LOSS_OF_CONTROL_UPDATE"] = events["ACTIONBAR_UPDATE_COOLDOWN"]; -- TODO might change once tooltips are in
683 events["PLAYER_MOUNT_DISPLAY_CHANGED"] = events["ACTIONBAR_UPDATE_USABLE"];
684 events["TRADE_SKILL_SHOW"] = events["ACTIONBAR_UPDATE_STATE"];
685 events["TRADE_SKILL_CLOSE"] = events["ACTIONBAR_UPDATE_STATE"];
686 events["ARCHAEOLOGY_CLOSED"] = events["ACTIONBAR_UPDATE_STATE"];
687 events["PLAYER_ENTERING_WORLD"] = events["UPDATE_ALL_BUTTONS"];
688 events["UPDATE_VEHICLE_ACTIONBAR"] = events["UPDATE_ALL_BUTTONS"];
689 events["UPDATE_SHAPESHIFT_FORM"] = events["UPDATE_ALL_BUTTONS"];
690 events["SPELL_UPDATE_ICON"] = events["UPDATE_ALL_BUTTONS"];
691 events["PET_STABLE_UPDATE"] = events["UPDATE_ALL_BUTTONS"];
692 events["PET_STABLE_SHOW"] = events["UPDATE_ALL_BUTTONS"];
693 events["PLAYER_SPECIALIZATION_CHANGED"] = events["UPDATE_ALL_BUTTONS"];
694 events["UNIT_ENTERED_VEHICLE"] = function(unit)
695 if unit == "player" then events["ACTIONBAR_UPDATE_STATE"]() end
697 events["UNIT_EXITED_VEHICLE"] = events["UNIT_ENTERED_VEHICLE"];
699 ActionBars:RegisterEvent("ADDON_LOADED");
700 ActionBars:RegisterEvent("PLAYER_LOGIN");
701 ActionBars:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
702 ActionBars:RegisterEvent("ACTIONBAR_UPDATE_USABLE");
703 ActionBars:RegisterEvent("ACTIONBAR_UPDATE_STATE");
704 ActionBars:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
705 ActionBars:RegisterEvent("ACTIONBAR_SHOWGRID");
706 ActionBars:RegisterEvent("ACTIONBAR_HIDEGRID");
707 ActionBars:RegisterEvent("SPELL_UPDATE_ICON");
708 ActionBars:RegisterEvent("SPELL_UPDATE_CHARGES");
709 ActionBars:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW");
710 ActionBars:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE");
711 ActionBars:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR");
712 ActionBars:RegisterEvent("UPDATE_OVERRIDE_ACTIONBAR");
713 ActionBars:RegisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED");
714 ActionBars:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
715 ActionBars:RegisterEvent("UNIT_ENTERED_VEHICLE");
716 ActionBars:RegisterEvent("UNIT_EXITED_VEHICLE");
717 ActionBars:RegisterEvent("PET_STABLE_UPDATE");
718 ActionBars:RegisterEvent("PET_STABLE_SHOW");
719 ActionBars:RegisterEvent("UPDATE_BINDINGS");
720 ActionBars:RegisterUnitEvent("UNIT_AURA", "player");
721 ActionBars:SetScript("OnEvent", function(self, event, arg1)