You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

999 lines
32 KiB

local _, addon = ...
local DataProvider = addon.TalentTreeDataProvider;
local strtrim = strtrim;
local GetCursorInfo = GetCursorInfo;
local ClearCursor = ClearCursor;
local InCombatLockdown = InCombatLockdown;
local PickupMacro = PickupMacro;
local GetCursorPosition = GetCursorPosition;
local GetNumMacros = GetNumMacros;
local GetActionInfo = GetActionInfo;
local GetMacroInfo = GetMacroInfo;
local match = string.match;
local ipairs = ipairs;
local pairs = pairs;
local _G = _G;
local L = Narci.L;
local RootFrame;
local MainFrame;
local ActionBarUtil = {};
ActionBarUtil.listener = CreateFrame("Frame");
addon.TalentTreeActionBarUtil = ActionBarUtil;
local function SetBorderColor(border, colorIndex)
if colorIndex == 1 then
--border:SetVertexColor(1, 0.82, 0);
--border:SetVertexColor(0.05, 0.41, 0.85);
border:SetVertexColor(0.33, 0.66, 1);
elseif colorIndex == 2 then
border:SetVertexColor(1, 1, 1);
elseif colorIndex == 3 then
border:SetVertexColor(0.45, 0.80, 0.48);
end
end
local function ClearCursorSafely()
if not InCombatLockdown() then
ClearCursor();
end
end
local ReceptorScripts = {};
function ReceptorScripts.OnEnter(self)
SetBorderColor(self.Border, 2);
SetBorderColor(MainFrame.SubIconButton.Border, 2);
end
function ReceptorScripts.OnLeave(self)
if MainFrame.isFinalStep then
SetBorderColor(self.Border, 3);
SetBorderColor(MainFrame.SubIconButton.Border, 3);
else
SetBorderColor(self.Border, 1);
end
end
function ReceptorScripts.OnEnable(self)
self.Icon:SetDesaturation(0);
self.Icon:SetVertexColor(1, 1, 1);
ReceptorScripts.OnLeave(self);
end
function ReceptorScripts.OnDisable(self)
self.Icon:SetDesaturation(0.5);
self.Icon:SetVertexColor(0.67, 0.67, 0.67);
self.Border:SetVertexColor(0.25, 0.25, 0.25);
end
function ReceptorScripts.OnDragStart(self)
if MainFrame.pendingMacroID then
if not InCombatLockdown() then
PickupMacro(MainFrame.pendingMacroID);
end
else
end
end
function ReceptorScripts.OnDragStop(self)
end
function ReceptorScripts.OnMouseDown(self, button)
if button == "RightButton" then
MainFrame:HideFrame();
ClearCursorSafely();
end
end
local function GetCursorEquipmentSetID()
local infoType, name = GetCursorInfo();
if infoType == "equipmentset" then
return C_EquipmentSet.GetEquipmentSetID(name);
end
end
local function SetupReceptorFromCursor()
if MainFrame.isFinalStep then
ClearCursorSafely();
return
end
local infoType, name = GetCursorInfo();
if infoType == "equipmentset" then
local setID = C_EquipmentSet.GetEquipmentSetID(name);
if setID then
local _, icon = C_EquipmentSet.GetEquipmentSetInfo(setID);
local specIndex = C_EquipmentSet.GetEquipmentSetAssignedSpec(setID);
if specIndex and (specIndex ~= DataProvider:GetCurrentSpecIndex()) then
MainFrame:SetInstruction(L["Create Macro Wrong Spec"]);
return
else
MainFrame.gearSetName = name;
MainFrame.step = 2;
MainFrame:UpdateStep();
MainFrame:SetPrimaryIcon(icon);
end
MainFrame.gearSetID = setID;
end
end
ClearCursorSafely();
end
function ReceptorScripts.OnReceiveDrag(self)
if self:IsEnabled() then
SetupReceptorFromCursor();
else
ClearCursorSafely();
end
end
function ReceptorScripts.OnClick(self)
if self:IsEnabled() then
SetupReceptorFromCursor();
end
end
local SubIconButtonScripts = {};
function SubIconButtonScripts.OnEnter(self)
SetBorderColor(self.Border, 2);
end
function SubIconButtonScripts.OnLeave(self)
SetBorderColor(self.Border, 1);
end
function SubIconButtonScripts.OnClick(self)
MainFrame:ShowIconSelect();
end
function SubIconButtonScripts.OnEnable(self)
self:SetHitRectInsets(0, 0, 0, 0);
end
function SubIconButtonScripts.OnDisable(self)
self:SetHitRectInsets(40, 40, 40, 40);
SetBorderColor(self.Border, 3);
end
local NameEditBoxScripts = {};
function NameEditBoxScripts.OnEnter(self)
if not self:HasFocus() then
self:SetTextColor(0.92, 0.92, 0.92);
end
end
function NameEditBoxScripts.OnLeave(self)
if not self:HasFocus() then
--self:SetTextColor(0.8, 0.8, 0.8);
self:SetTextColor(0.33, 0.66, 1);
end
end
function NameEditBoxScripts.OnEditFocusGained(self)
self:HighlightText();
self:SetTextColor(0.92, 0.92, 0.92);
end
function NameEditBoxScripts.OnEditFocusLost(self)
self:HighlightText(0, 0);
if self:IsMouseOver() then
NameEditBoxScripts.OnEnter(self);
else
NameEditBoxScripts.OnLeave(self);
end
local text = strtrim(self:GetText());
if text ~= "" then
MainFrame.customName = text;
else
MainFrame.customName = nil;
self:SetText(MainFrame.gearSetName or "Unnamed");
end
end
function NameEditBoxScripts.OnEscapePressed(self)
self:ClearFocus();
end
function NameEditBoxScripts.OnEnterPressed(self)
self:ClearFocus();
MainFrame:UpdateStep();
C_Timer.After(0, function()
MainFrame.NextButton:Click();
end);
end
local NextButtonScripts = {};
function NextButtonScripts.OnEnter(self)
self.ButtonText:SetTextColor(1, 1, 1);
end
function NextButtonScripts.OnLeave(self)
self.ButtonText:SetTextColor(0.67, 0.67, 0.67);
self.Border.Blink:Play();
end
function NextButtonScripts.OnClick(self)
MainFrame.step = MainFrame.step + 1;
MainFrame:UpdateStep();
end
function NextButtonScripts.OnEnable(self)
self.Border:Show();
end
function NextButtonScripts.OnDisable(self)
self.Border:Hide();
self.Border:SetPoint("CENTER", 0, 0);
end
function NextButtonScripts.OnMouseDown(self)
if self:IsEnabled() then
self.Border:SetPoint("CENTER", 0, self.pushOffset or -1);
end
end
function NextButtonScripts.OnMouseUp(self)
self.Border:SetPoint("CENTER", 0, 0);
end
function NextButtonScripts.OnShow(self)
self.Border.Blink:Play();
end
local function CreateCombinedMacro(macroName, loadoutConfigID, equipmentSetName, equipmentSetID, primaryIcon, secondaryIcon)
if InCombatLockdown() then return end;
local f = MacroFrame;
if f and f:IsShown() then
HideUIPanel(f); --create macro while MarcoFrame is active can cause issues
end
--local body = string.format("/equipset %s;\n/script local g=%d;if Narci and Narci.AC then Narci.AC(g) else local C=C_ClassTalents;local d=PlayerUtil.GetCurrentSpecID();local r=C.LoadConfig(g,true);if r~= 0 then C.UpdateLastSelectedSavedConfigID(d,g); end end;", equipmentSetName, loadoutConfigID); --too long
local body = string.format("/equipset %s;\n/script local g=%d;if Narci and Narci.AC then Narci.AC(g) else C_ClassTalents.LoadConfig(g,true) end;--(%d,%d)", equipmentSetName, loadoutConfigID, equipmentSetID, secondaryIcon or 0);
local macroID;
local _, numCharacterMacros = GetNumMacros();
local _, _, _, macroConfigID, macroSetID;
for existingMacroID = 121, 121 + numCharacterMacros - 1 do
_, _, _, macroConfigID, macroSetID = ActionBarUtil:ProcessMacro(existingMacroID);
if macroSetID and macroSetID == equipmentSetID and loadoutConfigID == macroConfigID then
macroID = existingMacroID;
break
end
end
if macroID then
macroID = EditMacro(macroID, macroName, primaryIcon, body);
else
local perCharacter = true;
macroID = CreateMacro(macroName, primaryIcon, body, perCharacter);
end
if macroID then
return macroID
else
return false --max char specific macros: 18
end
end
local function InstructionFrame_DynamicTransparency_OnUpdate(self, elapsed)
self.t = self.t + elapsed;
if self.t > 0.0167 then
self.t = 0;
local x, y = GetCursorPosition();
if y > self.bottom then
local alpha = 1 - (y - self.bottom)/48;
if alpha < 0 then
alpha = 0;
end
self:SetAlpha(alpha);
else
self:SetAlpha(1);
end
end
end
local function InstructionFrame_SetDynamicTransparency(self)
self.bottom = self.Instruction:GetBottom() - 32;
self.t = 0;
self:SetScript("OnUpdate", InstructionFrame_DynamicTransparency_OnUpdate);
end
local function InstructionFrame_FadeOutIn(self, elapsed)
self.alpha = self.alpha + elapsed * self.delta;
if self.alpha < 0 then
self.alpha = 0;
self.delta = -self.delta;
self.Instruction:SetText(self.pendingText);
end
if self.alpha > 1 then
self.alpha = 1;
self:SetScript("OnUpdate", nil);
if self.callback then
self.callback(self);
self.callback = nil;
end
end
self:SetAlpha(self.alpha);
end
NarciMiniTalentTreeMacroForgeMixin = {};
function NarciMiniTalentTreeMacroForgeMixin:OnLoad()
MainFrame = self;
RootFrame = self:GetParent();
self.step = 1;
self.Instruction = self.InstructionFrame.Instruction;
for name, script in pairs(ReceptorScripts) do
self.Receptor:SetScript(name, script);
end
ReceptorScripts.OnLeave(self.Receptor);
self.Receptor:RegisterForDrag("LeftButton");
for name, script in pairs(SubIconButtonScripts) do
self.SubIconButton:SetScript(name, script);
end
for name, script in pairs(NextButtonScripts) do
self.NextButton:SetScript(name, script);
end
for name, script in pairs(NameEditBoxScripts) do
self.NameEditBox:SetScript(name, script);
end
self.NameEditBox:SetHighlightColor(0.05, 0.41, 0.85);
self.NameEditBox:SetMaxLetters(30);
local basicLevel = self:GetFrameLevel();
self.Receptor:SetFrameLevel(basicLevel + 6);
self.SubIconButton:SetFrameLevel(basicLevel + 10);
self.InstructionFrame:SetFrameLevel(basicLevel + 4);
self.NodeHighlight:SetFrameLevel(basicLevel + 6);
self.NameEditBox:SetFrameLevel(basicLevel + 6);
self.CombatBlocker:SetFrameLevel(basicLevel + 20);
self.LeftArrow:SetVertexColor(0.4, 0.4, 0.4);
self.RightArrow:SetVertexColor(0.4, 0.4, 0.4);
self.LeftArrowLight:SetVertexColor(0.8, 0.8, 0.8);
self.RightArrowLight:SetVertexColor(0.8, 0.8, 0.8);
addon.TalentTreeNodeUtil:AssignHandler(self);
end
function NarciMiniTalentTreeMacroForgeMixin:HighlightButton(node)
if node then
self.NodeHighlight:ClearAllPoints();
self.NodeHighlight:SetPoint("CENTER", node, "CENTER", 0, 0);
if node.typeID == 0 then --square
self.NodeHighlight.Border:SetTexCoord(0.5, 1, 0, 0.5);
elseif node.typeID == 1 then --circle
self.NodeHighlight.Border:SetTexCoord(0, 0.5, 0, 0.5);
elseif node.typeID == 2 then --oct
self.NodeHighlight.Border:SetTexCoord(0, 0.5, 0.5, 1);
else
self.NodeHighlight.Border:SetTexCoord(0.5, 1, 0.5, 1);
end
self.NodeHighlight:Show();
else
self.NodeHighlight:Hide();
end
end
function NarciMiniTalentTreeMacroForgeMixin:SetInstruction(text, instant)
if instant then
self.InstructionFrame.Instruction:SetText(text);
self.InstructionFrame.pendingText = nil;
self.InstructionFrame:SetScript("OnUpdate", nil);
self.InstructionFrame:SetAlpha(1);
return
end
if text == self.InstructionFrame.pendingText then return end;
self.InstructionFrame.alpha = self.Instruction:GetAlpha();
self.InstructionFrame.delta = -5;
self.InstructionFrame.pendingText = text;
self.InstructionFrame:SetScript("OnUpdate", InstructionFrame_FadeOutIn);
end
function NarciMiniTalentTreeMacroForgeMixin:OnCursorChanged(isDefault, newCursorType, oldCursorType)
if newCursorType == 13 then
self:ShowFrame();
else
if not self.gearSetName then
self:HideFrame();
end
end
end
local function FadeIn_OnUpdate(self, elapsed)
self.alpha = self.alpha + 5 * elapsed;
if self.alpha > 1 then
self.alpha = 1;
self:SetScript("OnUpdate", nil);
end
self:SetAlpha(self.alpha);
end
local function FadeOut_OnUpdate(self, elapsed)
self.alpha = self.alpha - 5 * elapsed;
if self.alpha < 0 then
self.alpha = 0;
self:SetScript("OnUpdate", nil);
self:Hide();
end
self:SetAlpha(self.alpha);
end
function NarciMiniTalentTreeMacroForgeMixin:ShowFrame()
self:ResetSteps();
self:Show();
self.alpha = self:GetAlpha();
self:SetScript("OnUpdate", FadeIn_OnUpdate);
if InCombatLockdown() then
self.CombatBlocker:Show();
end
end
function NarciMiniTalentTreeMacroForgeMixin:HideFrame(fadeOut)
if fadeOut then
if self:IsVisible() then
self.alpha = self:GetAlpha();
self:SetScript("OnUpdate", FadeOut_OnUpdate);
end
else
self:Hide();
end
end
function NarciMiniTalentTreeMacroForgeMixin:OnShow()
self:RegisterEvent("PLAYER_REGEN_DISABLED");
self:RegisterEvent("PLAYER_REGEN_ENABLED");
end
function NarciMiniTalentTreeMacroForgeMixin:OnHide()
self:UnregisterEvent("PLAYER_REGEN_DISABLED");
self:UnregisterEvent("PLAYER_REGEN_ENABLED");
self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED");
self:Hide();
self.CombatBlocker:Hide();
self:SetAlpha(0);
RootFrame:RaiseActiveNodesFrameLevel(false);
end
function NarciMiniTalentTreeMacroForgeMixin:OnEvent(event, ...)
if event == "PLAYER_REGEN_DISABLED" then
self.NextButton:Disable();
self.CombatBlocker:Show();
elseif event == "PLAYER_REGEN_ENABLED" then
if not self.isFinalStep then
self.NextButton:Enable();
end
self.CombatBlocker:Hide();
elseif event == "ACTIONBAR_SLOT_CHANGED" then
local slot = ...
local actionType, id, subType = GetActionInfo(slot);
if actionType == "macro" then
if id == self.pendingMacroID then
self:UnregisterEvent(event);
self.pendingMacroID = nil;
self:HideFrame(true);
--ActionBarUtil:UpdateListenerStatus();
ActionBarUtil:OnMacroUpdated()
end
end
end
end
function NarciMiniTalentTreeMacroForgeMixin:UpdatePixel(px)
self.Receptor:SetSize(64*px, 64*px);
self.Receptor.Icon:SetSize(48*px, 48*px);
self.Receptor.Background:SetSize(96*px, 96*px);
self.Receptor.Highlight:SetSize(128*px, 128*px);
self.Receptor:ClearAllPoints();
self.Receptor:SetPoint("CENTER", self, "CENTER", 0, 0);
self.SubIconButton:SetSize(32*px, 32*px);
self.SubIconButton.Icon:SetSize(20*px, 20*px);
self.SubIconButton:ClearAllPoints();
self.SubIconButton:SetPoint("CENTER", self.Receptor, "CENTER", -18*px, 18*px);
self.LeftArrow:SetSize(32*px, 16*px);
self.LeftArrow:ClearAllPoints();
self.LeftArrow:SetPoint("RIGHT", self, "CENTER", -40*px, 0);
self.RightArrow:SetSize(32*px, 16*px);
self.RightArrow:ClearAllPoints();
self.RightArrow:SetPoint("LEFT", self, "CENTER", 40*px, 0);
self.LeftArrowLight:SetSize(24*px, 16*px);
self.LeftArrowLight.Anim.MoveRight:SetOffset(56*px, 0);
self.RightArrowLight:SetSize(24*px, 16*px);
self.RightArrowLight.Anim.MoveLeft:SetOffset(-56*px, 0);
self.NodeHighlight:SetSize(64*px, 64*px);
self.SubIconButton.Highlight:SetSize(64*px, 64*px);
local font, _, _ = self.Instruction:GetFont();
self.Instruction:SetFont(font, 16*px, "OUTLINE");
self.Instruction:SetWidth(190 * px);
self.Instruction:ClearAllPoints();
self.Instruction:SetPoint("BOTTOM", self, "CENTER", 0, 80*px);
self.NextButton.ButtonText:SetFont(font, 16*px, "OUTLINE");
self.NextButton:SetSize(96*px, 36*px);
self.NextButton.Border:SetSize(96*px, 36*px);
self.NextButton.pushOffset = -px;
self.NextButton:ClearAllPoints();
self.NextButton:SetPoint("TOP", self, "CENTER", 0, -80*px);
self.NextButton.Exclusion:ClearAllPoints();
self.NextButton.Exclusion:SetPoint("TOPLEFT", self.NextButton.Border, "TOPLEFT", 2*px, -2*px);
self.NextButton.Exclusion:SetPoint("BOTTOMRIGHT", self.NextButton.Border, "BOTTOMRIGHT", -2*px, 2*px);
self.NextButton.Exclusion:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Exclusion", "CLAMPTOWHITE", "CLAMPTOWHITE", "NEAREST");
self.NameEditBox:SetFont(font, 20*px, "");
self.NameEditBox:SetSize(160*px, 40*px);
self.NameEditBox:ClearAllPoints();
self.NameEditBox:SetPoint("BOTTOM", self, "CENTER", 0, 64*px);
self.CombatBlocker.AlertText:SetFont(font, 16*px, "OUTLINE");
self.CombatBlocker.AlertText:ClearAllPoints();
self.CombatBlocker.AlertText:SetPoint("BOTTOM", self, "BOTTOM", 0, 32*px);
self.CombatBlocker.AlertText:SetText(L["Create Macro In Combat"]);
self.MotionBlocker:SetScript("OnMouseDown", function(f, button)
ClearCursorSafely();
if button == "RightButton" then
self:HideFrame();
end
end)
end
function NarciMiniTalentTreeMacroForgeMixin:SetSecondaryIcon(icon, viaClick)
self.secondaryIcon = icon;
self.SubIconButton.Icon:SetTexture(icon);
self.SubIconButton.Highlight.Glow:Stop();
if icon then
self.SubIconButton.Highlight.Glow:Play();
end
if viaClick then
self:HighlightButton();
end
end
function NarciMiniTalentTreeMacroForgeMixin:SetPrimaryIcon(icon)
self.primaryIcon = icon;
self.Receptor.Icon:SetTexture(icon);
end
function NarciMiniTalentTreeMacroForgeMixin:ResetSteps()
self.step = 1;
self.configID = nil;
self.gearSetName = nil;
self.customName = nil;
self.pendingMacroID = nil;
self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED");
self:SetPrimaryIcon(nil);
self:SetSecondaryIcon(nil);
self.NameEditBox:SetText("");
self.SubIconButton.Icon:SetTexture(nil);
self.Receptor.Highlight:Hide();
self:ShowReceptor();
end
function NarciMiniTalentTreeMacroForgeMixin:UpdateStep()
if self.step == 2 then
self:ShowIconSelect()
elseif self.step == 3 then
self:ShowRename();
elseif self.step == 4 then
self:ShowComplete();
else
self:ShowReceptor();
end
end
function NarciMiniTalentTreeMacroForgeMixin:ShowReceptor()
local setID = GetCursorEquipmentSetID();
local configID = DataProvider:GetSelecetdConfigID();
local _, numCharacterMacros = GetNumMacros();
local macroName, macroIcon1, macroIcon2, macroConfigID, macroSetID;
local oldMacroID;
if setID then
for macroID = 121, 121 + numCharacterMacros - 1 do
macroName, macroIcon1, macroIcon2, macroConfigID, macroSetID = ActionBarUtil:ProcessMacro(macroID);
if macroSetID and macroSetID == setID and configID == macroConfigID then
oldMacroID = macroID;
break
end
end
end
self.step = 1;
self.isFinalStep = nil;
self:UpdateWidgetStates();
self.LeftArrowLight.Anim:Stop();
self.RightArrowLight.Anim:Stop();
if not oldMacroID then
if (not numCharacterMacros) or numCharacterMacros >= 18 then
self:SetInstruction(L["Create Marco No Slot"], true);
self.Receptor:Disable();
self.Receptor.Border:SetVertexColor(1, 0.2, 0.2);
return
else
local loadoutName = DataProvider:GetActiveLoadoutName();
self:SetInstruction(string.format(L["Create Macro Instruction 1"], loadoutName), true);
end
else --edit a existing macro
self:SetInstruction(string.format(L["Create Macro Instruction Edit"], macroName), true);
self.customName = macroName;
self:SetPrimaryIcon(macroIcon1);
self:SetSecondaryIcon(macroIcon2);
end
self.configID = configID;
SetBorderColor(self.Receptor.Border, 1);
self.LeftArrowLight.Anim:Play();
self.RightArrowLight.Anim:Play();
end
function NarciMiniTalentTreeMacroForgeMixin:ShowIconSelect()
self.step = 2;
self.isFinalStep = nil;
SetBorderColor(self.SubIconButton.Border, 1);
self.InstructionFrame.callback = InstructionFrame_SetDynamicTransparency;
self:SetInstruction(L["Create Macro Instruction 2"]);
self.NextButton.ButtonText:SetText(L["Create Macro Next"]);
self:UpdateWidgetStates();
end
function NarciMiniTalentTreeMacroForgeMixin:ShowRename()
self.step = 3;
self.isFinalStep = nil;
self:SetInstruction(L["Create Macro Instruction 3"]);
self.NextButton.ButtonText:SetText(L["Create Macro Next"]);
self:UpdateWidgetStates();
self.NameEditBox:SetText(self.customName or self.gearSetName or "");
self.NameEditBox:SetFocus();
end
function NarciMiniTalentTreeMacroForgeMixin:ShowComplete()
self.step = 4;
self.isFinalStep = true;
self:SetInstruction(L["Create Macro Instruction 4"]);
self.Receptor.Highlight:Show();
SetBorderColor(self.Receptor.Border, 3);
self.NextButton.ButtonText:SetText(L["Create Marco Created"]);
self:UpdateWidgetStates();
if self.secondaryIcon then
self.Receptor.Highlight:SetTexCoord(0.25, 0.5, 0.25, 0.5);
else
self.Receptor.Highlight:SetTexCoord(0, 0.25, 0.25, 0.5);
self.SubIconButton:Hide();
end
local macroID;
if self.gearSetName and self.configID then
local macroName = self.customName or self.gearSetName or "GearSetAndLoadout";
macroID = CreateCombinedMacro(macroName, self.configID, self.gearSetName, self.gearSetID, self.primaryIcon, self.secondaryIcon);
end
self.pendingMacroID = macroID;
self.Receptor:SetEnabled(macroID ~= nil);
self.Receptor.Highlight.Blink:Stop();
if macroID then
self.Receptor.Highlight.Blink:Play();
self:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
else
self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED");
end
end
function NarciMiniTalentTreeMacroForgeMixin:UpdateWidgetStates()
self.NextButton:SetShown(self.step > 1);
self.NameEditBox:SetShown(self.step == 3);
self.SubIconButton:SetShown(self.step > 1);
self.LeftArrow:SetShown(self.step == 1);
self.RightArrow:SetShown(self.step == 1);
self.LeftArrowLight:SetShown(self.step == 1);
self.RightArrowLight:SetShown(self.step == 1);
self.Receptor:SetEnabled(self.step == 1);
self.SubIconButton:SetEnabled(not self.isFinalStep);
self.NextButton:SetEnabled(not self.isFinalStep);
RootFrame:RaiseActiveNodesFrameLevel(self.step == 2);
end
local ActionBarNames = {
"MainMenuBar", "MultiBarBottomLeft", "MultiBarBottomRight", "MultiBarLeft", "MultiBarRight", "MultiBar5", "MultiBar6", "MultiBar7",
};
--[[
local ActionBarSlotRange = {
[1] = "MainMenuBar", --Page1 1-12 Page2 13-24, Stance 73-120
[2] = "MultiBarRight", --25-36
[3] = "MultiBarLeft", --37-48
[4] = "MultiBarBottomRight", --49-60
[5] = "MultiBarBottomLeft", --61-72
[6] = "MultiBar5", --145-156
[7] = "MultiBar6", --157-168
[8] = "MultiBar7", --169-180
};
--]]
function ActionBarUtil:GetActionButtonBySlotID(slotID)
if (not slotID) or (slotID >= 120 and slotID <= 132) then return end;
if slotID <= 12 then
return _G["ActionButton"..(slotID)];
elseif slotID <= 24 then
return _G["ActionButton"..(slotID - 12)];
elseif slotID <= 36 then
return _G["MultiBarRightButton"..(slotID - 24)];
elseif slotID <= 48 then
return _G["MultiBarLeftButton"..(slotID - 36)];
elseif slotID <= 60 then
return _G["MultiBarBottomRightButton"..(slotID - 48)];
elseif slotID <= 72 then
return _G["MultiBarBottomLeftButton"..(slotID - 60)];
elseif slotID <= 84 then
return _G["ActionButton"..(slotID - 72)];
elseif slotID <= 96 then
return _G["ActionButton"..(slotID - 84)];
elseif slotID <= 108 then
return _G["ActionButton"..(slotID - 96)];
elseif slotID <= 120 then
return _G["ActionButton"..(slotID - 108)];
elseif slotID >= 145 then
if slotID <= 156 then
return _G["MultiBar5Button"..(slotID - 144)];
elseif slotID <= 168 then
return _G["MultiBar6Button"..(slotID - 156)];
elseif slotID <= 180 then
return _G["MultiBar7Button"..(slotID - 168)];
end
end
end
ActionBarUtil.container = CreateFrame("Frame");
ActionBarUtil.overlayInSlot = {};
function ActionBarUtil:ReleaseOverlays()
if self.overlays then
for i, overlay in ipairs(self.overlays) do
overlay:Hide();
overlay:ClearAllPoints();
overlay:SetParent(self.container);
end
end
self.numOverlays = 0;
end
function ActionBarUtil:AcquireOverlay()
self.numOverlays = self.numOverlays + 1;
if not self.overlays then
self.overlays = {};
end
local overlay = self.overlays[self.numOverlays];
if not overlay then
overlay = CreateFrame("Frame", nil, self.container, "NarciMiniTalentTreeActionBarOverlayTemplate");
self.overlays[self.numOverlays] = overlay;
end
return overlay;
end
local function ActionBarUpdator_UpdateAll_OnUpdate(self, elapsed)
self.t = self.t + elapsed;
if self.t > 0.05 then
self.t = 0;
self:SetScript("OnUpdate", nil);
if InCombatLockdown() then
self:RegisterEvent("PLAYER_REGEN_ENABLED");
return
else
ActionBarUtil:ProcessAllButtons();
self:UnregisterEvent("PLAYER_REGEN_ENABLED");
end
end
end
local function ActionBarUpdator_CheckMacro_OnUpdate(self, elapsed)
self.t = self.t + elapsed;
if self.t > 0.1 then
self.t = 0;
self:SetScript("OnUpdate", nil);
ActionBarUtil:UpdateListenerStatus();
end
end
local function ActionBarListener_OnEvent(self, event, ...)
if event == "ACTIONBAR_SLOT_CHANGED" then
ActionBarUtil:RequestUpdate();
elseif event == "PLAYER_REGEN_ENABLED" then
self:SetScript("OnUpdate", nil);
self:UnregisterEvent(event);
ActionBarUtil:ProcessAllButtons();
elseif event == "ACTIONBAR_PAGE_CHANGED" then
ActionBarUtil:RequestUpdate();
elseif event == "UPDATE_MACROS" then
ActionBarUtil:OnMacroUpdated();
end
end
function ActionBarUtil:RequestUpdate()
self.listener.t = 0;
self.listener:SetScript("OnUpdate", ActionBarUpdator_UpdateAll_OnUpdate);
end
function ActionBarUtil:OnMacroUpdated()
self.numCombinedMacros = nil;
self.listener.t = 0;
self.listener:SetScript("OnUpdate", ActionBarUpdator_CheckMacro_OnUpdate);
end
function ActionBarUtil:Monitor(state)
if state then
self.listener:SetScript("OnEvent", ActionBarListener_OnEvent);
self.listener:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
self.listener:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
self.listener:RegisterEvent("UPDATE_MACROS");
else
self.listener:SetScript("OnEvent", nil);
self.listener:SetScript("OnUpdate", nil);
self.listener:UnregisterEvent("ACTIONBAR_SLOT_CHANGED");
self.listener:UnregisterEvent("ACTIONBAR_PAGE_CHANGED");
self.listener:UnregisterEvent("UPDATE_MACROS");
end
end
ActionBarUtil.listener:RegisterEvent("PLAYER_ENTERING_WORLD");
ActionBarUtil.listener:SetScript("OnEvent", function(self, event, ...)
--Initialization
self:UnregisterEvent(event);
ActionBarUtil:UpdateListenerStatus();
end);
function ActionBarUtil:ProcessMacro(macroID)
local name, icon, body = GetMacroInfo(macroID);
if body then
local setName = match(body, "/equipset (%C+);");
local configID = match(body, "local g=(%d+)");
if setName and configID then
configID = tonumber(configID);
if not DataProvider:IsConfigIDValid(configID) then
--print(configID.. " No longer exists.")
return
end
local setID, secondaryIcon = match(body, "--%((%d+),(%d+)%)");
if setID and secondaryIcon then
secondaryIcon = tonumber(secondaryIcon);
setID = tonumber(setID);
if secondaryIcon == 0 then
secondaryIcon = nil;
end
return name, icon, secondaryIcon, configID, setID
end
end
end
end
function ActionBarUtil:UpdateListenerStatus()
local numCombinedMacros = self:GetCombinedMacro(true);
if numCombinedMacros > 0 then
ActionBarUtil:Monitor(true);
ActionBarUtil:RequestUpdate();
else
ActionBarUtil:Monitor(false);
self:ReleaseOverlays();
end
end
function ActionBarUtil:GetCombinedMacro(onlyCounting)
if onlyCounting then
if not self.numCombinedMacros then
local _, perChar = GetNumMacros();
local total = 0;
local name;
for macroID = 121, 121 + perChar - 1 do
name = self:ProcessMacro(macroID);
if name then
total = total + 1;
end
end
self.numCombinedMacros = total;
end
return self.numCombinedMacros
else
if not self.macroData then
self.macroData = {};
local _, perChar = GetNumMacros();
local total = 0;
local name, icon1, icon2, configID, setID;
for macroID = 121, 121 + perChar - 1 do
name, icon1, icon2, configID, setID = self:ProcessMacro(macroID);
if name then
total = total + 1;
self.macroData[total] = {name, icon1, icon2, configID, setID};
end
end
end
return self.macroData
end
end
function ActionBarUtil:ProcessAllButtons()
ActionBarUtil:ReleaseOverlays();
local _G = _G;
local GetActionInfo = GetActionInfo;
local bar;
local slot;
local actionType, id, subType;
local _, secondaryIcon, configID;
local overlay;
local activeConfigID = DataProvider:GetPlayerActiveConfigID();
for i = 1, #ActionBarNames do
bar = _G[ActionBarNames[i]];
if bar and bar:IsVisible() and bar.actionButtons then
for index, button in ipairs(bar.actionButtons) do
slot = button.action;
if slot then
actionType, id, subType = GetActionInfo(slot);
if actionType and actionType == "macro" and id and id > 120 then
_, _, secondaryIcon, configID = self:ProcessMacro(id);
if secondaryIcon then
overlay = ActionBarUtil:AcquireOverlay();
overlay.Icon:SetTexture(secondaryIcon);
overlay:ClearAllPoints();
overlay:SetPoint("TOPLEFT", button, "TOPLEFT", -2, 2);
overlay:Show();
overlay:SetParent(button);
overlay.slot = slot;
if configID and configID == activeConfigID then
overlay.Border:SetTexCoord(0.5, 1, 0, 1);
else
overlay.Border:SetTexCoord(0, 0.5, 0, 1);
end
end
end
end
end
end
end
end