2122 lignes
69 Kio
Lua
2122 lignes
69 Kio
Lua
--[[
|
|
Author: Alternator (Massiner of Nathrezim)
|
|
Copyright 2010
|
|
|
|
Notes:
|
|
- Texture retrieval on Spells will not return different state textures for a spell (e.g. Wisp, when a Hunter Aspect is selected)
|
|
- Texture retrieval on Macros will however return the different state textures - I do not believe this can be leveraged to fix the above
|
|
- Index refers to the players index to a macro, spell, Companion etc...
|
|
- Id refers to the universal Id where one exists
|
|
- I would have liked to add operations to the CheckButton instances, but this may or may not be safe, so instead I create an instance with a CheckButton member
|
|
- Because Frames can be dynamically created, abandoned Frames need to be managed... This could lead to recycling them, but consider that later on
|
|
- OnClick of the SecureButtonTemplate has some subtle but important behaviour as follows
|
|
- Clears the Cursor
|
|
- If the Cursor is a Spell and the button type is spell it wont trigger the action, other situations it does (workaround is to temporarily clear the type attribute)
|
|
- Querying Companion information is dicey when the player first enters the gameworld (during a new session, or perhaps empty cache??)
|
|
- A COMPANION_UPDATE event triggers when this data is available for query, unfortunately other things can trigger the same event before this as well, making it not as useful
|
|
- A work around is to continually try to create the companion cache until it successfully runs to completetion
|
|
- Macros with Companions as the action, will return the action as though it were a spell :S
|
|
- Since basically none of the spell functions actually work with companions (even though they have a spell id!?!?) we need to detect if it really is a spell or not
|
|
- This is done by creating a reverse cache of the companions for easy lookup
|
|
- MouseOver macro conditional changed has the following considerations
|
|
- The Event CURSOR_UPDATE is not sufficient for this, since if the cursor does not change such as mousing from one enemy to the next, or moving onto the enemy name plate (cursor changes but mouseover hasn't, but now we wont get a cursor_update when they move completely off)
|
|
- The Event UPDATE_MOUSEOVER_UNIT would have done the trick, except it does not fire when the player mouses off a target to nothing
|
|
- The solution is to check the players mouseover target on a per frame basis, and put a 1 frame delay in before refreshing, so far this does not appear to incur a big penalty (i'd still like to avoid doing it however)
|
|
|
|
- Button is inherited for each Button created
|
|
- each created Button has a table entry called Widget, this is the actual button widget shown on screen
|
|
- The above is important to remember since sometimes a Button function called be called with the first parameter as the Widget (not the Button, in these cases, the : operator has not been used
|
|
and the first parameter will be Widget)... This is due to the setting of some Button functions as Scripts for events on the Widget.
|
|
]]
|
|
|
|
--Create a mapping to the needed elements (allocate the item if necessary)
|
|
|
|
local Util = BFUtil;
|
|
local Const = BFConst;
|
|
local Button = BFButton;
|
|
local UILib = BFUILib;
|
|
local CustomAction = BFCustomAction;
|
|
local KeyBinder = BFKeyBinder;
|
|
Button.__index = Button;
|
|
|
|
local IsUsableSpell = IsUsableSpell;
|
|
local SecureClickWrapperFrame = CreateFrame("FRAME", nil, nil, "SecureHandlerBaseTemplate");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------
|
|
Create a New Button
|
|
----------------------------------------------------------------]]
|
|
function Button.New(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText)
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
local NewButton = {};
|
|
setmetatable(NewButton, Button);
|
|
|
|
NewButton.Widget = Button.CreateButtonWidget(Parent);
|
|
local Name = NewButton.Widget:GetName();
|
|
NewButton.WIcon = _G[Name.."Icon"];
|
|
NewButton.WNormalTexture = _G[Name.."NormalTexture"];
|
|
NewButton.WCooldown = _G[Name.."Cooldown"];
|
|
NewButton.WCount = _G[Name.."Count"];
|
|
NewButton.WBorder = _G[Name.."Border"];
|
|
NewButton.WFlashTexture = _G[Name.."Flash"];
|
|
NewButton.WHotKey = _G[Name.."HotKey"];
|
|
NewButton.WName = _G[Name.."Name"];
|
|
NewButton.Widget.ParentButton = NewButton;
|
|
|
|
NewButton.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0, 0.5);
|
|
NewButton.WCooldown:SetEdgeTexture("Interface\\Cooldown\\edge");
|
|
NewButton.WCooldown:SetSwipeColor(0, 0, 0);
|
|
NewButton.WCooldown:SetHideCountdownNumbers(false);
|
|
NewButton.WCooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL;
|
|
|
|
NewButton.UpdateTooltip = Button.Empty;
|
|
NewButton:Configure(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText);
|
|
NewButton:SetupActionButtonClick();
|
|
|
|
return NewButton;
|
|
end
|
|
|
|
function Button.CreateButtonWidget(Parent)
|
|
local Name = Const.ButtonNaming..Const.ButtonSeq;
|
|
local Widget = CreateFrame("CheckButton", Name, Parent, "SecureActionButtonTemplate, ActionButtonTemplate");
|
|
Const.ButtonSeq = Const.ButtonSeq + 1;
|
|
Widget:SetAttribute("checkselfcast", true);
|
|
Widget:SetAttribute("checkfocuscast", true);
|
|
Widget:RegisterForDrag("LeftButton", "RightButton");
|
|
--Widget:RegisterForClicks("AnyUp");
|
|
Widget:SetScript("OnReceiveDrag", Button.OnReceiveDrag);
|
|
Widget:SetScript("OnDragStart", Button.OnDragStart);
|
|
|
|
if (Util.ForceOffCastOnKeyDown) then
|
|
Widget:SetScript("PostClick", Button.PostClickBasic);
|
|
Widget:SetScript("PreClick", Button.PreClickBasic);
|
|
else
|
|
Widget:SetScript("PostClick", Button.PostClick);
|
|
Widget:SetScript("PreClick", Button.PreClick);
|
|
end
|
|
|
|
--The ActionButtonTemplate does not include the following (which will be created here)
|
|
--FloatingBG (e.g. MultiBarButtonTemplate)
|
|
local FloatingBG = Widget:CreateTexture(Name.."FloatingBG", "BACKGROUND", nil, -1);
|
|
FloatingBG:SetTexture("Interface\\Buttons\\UI-Quickslot");
|
|
FloatingBG:SetAlpha(0.4);
|
|
FloatingBG:SetPoint("TOPLEFT", -15, 15);
|
|
FloatingBG:SetPoint("BOTTOMRIGHT", 15, -15);
|
|
|
|
--AutoCastable (e.g. PetActionButtonTemplate)
|
|
local AutoCastable = Widget:CreateTexture(Name.."AutoCastable", "OVERLAY");
|
|
AutoCastable:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay");
|
|
AutoCastable:SetSize(70, 70);
|
|
AutoCastable:SetPoint("CENTER", 0, 0);
|
|
AutoCastable:Hide();
|
|
|
|
--AutoCast
|
|
local Shine = CreateFrame("FRAME", Name.."Shine", Widget, "AutoCastShineTemplate");
|
|
Shine:SetSize(34, 34);
|
|
Shine:SetPoint("CENTER", 0, 0);
|
|
|
|
--_G[Widget:GetName().."HotKey"]:ClearAllPoints();
|
|
--_G[Widget:GetName().."HotKey"]:SetPoint("TOPLEFT", Widget, "TOPLEFT", 1, -2);
|
|
Widget.action = 10000;
|
|
if (Util.LBFMasterGroup) then
|
|
Util.LBFMasterGroup:AddButton(Widget);
|
|
end
|
|
return Widget;
|
|
end
|
|
|
|
function Button:SetupActionButtonClick()
|
|
local Widget = self.Widget;
|
|
|
|
-- This particular setting will only gets set at login (if the player changes it they must log out and back in)
|
|
if (Util.ForceOffCastOnKeyDown) then
|
|
Widget:RegisterForClicks("AnyUp");
|
|
return;
|
|
end
|
|
|
|
SecureClickWrapperFrame:UnwrapScript(Widget, "OnClick");
|
|
|
|
if (GetCVarBool("ActionButtonUseKeyDown")) then
|
|
Widget:RegisterForClicks("AnyUp", "AnyDown");
|
|
local SecurePreClickSnippet =
|
|
[[if (down and button == "KeyBind") then
|
|
return "LeftButton";
|
|
end
|
|
if ((not down) and button ~= "KeyBind") then
|
|
return;
|
|
end
|
|
return false;]];
|
|
SecureClickWrapperFrame:WrapScript(Widget, "OnClick", SecurePreClickSnippet);
|
|
|
|
else
|
|
Widget:RegisterForClicks("AnyUp");
|
|
local SecurePreClickSnippet =
|
|
[[if (button == "KeyBind") then
|
|
return "LeftButton";
|
|
end]];
|
|
SecureClickWrapperFrame:WrapScript(Widget, "OnClick", SecurePreClickSnippet);
|
|
end
|
|
|
|
end
|
|
|
|
--[[ Configure the button for use --]]
|
|
function Button:Configure(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText)
|
|
self.Widget:SetParent(Parent);
|
|
self.ButtonSave = ButtonSave;
|
|
|
|
local Mode = ButtonSave["Mode"];
|
|
if (Mode == "spell") then
|
|
self:SetCommandExplicitSpell(ButtonSave["SpellId"], ButtonSave["SpellNameRank"], ButtonSave["SpellName"], ButtonSave["SpellBook"]); --the util functions will get both the index and the book
|
|
|
|
elseif (Mode == "item") then
|
|
self:SetCommandExplicitItem(ButtonSave["ItemId"], ButtonSave["ItemName"], ButtonSave["ItemLink"]);
|
|
|
|
elseif (Mode == "macro") then
|
|
self:SetCommandExplicitMacro(ButtonSave["MacroIndex"], ButtonSave["MacroName"], ButtonSave["MacroBody"]);
|
|
|
|
--elseif (Mode == "companion") then
|
|
-- self:SetCommandExplicitCompanion(ButtonSave["CompanionId"], ButtonSave["CompanionType"], ButtonSave["CompanionIndex"], ButtonSave["CompanionName"], ButtonSave["CompanionSpellName"]);
|
|
elseif (Mode == "mount") then
|
|
self:SetCommandExplicitCompanion(ButtonSave["MountID"]);
|
|
|
|
elseif (Mode == "equipmentset") then
|
|
self:SetCommandExplicitEquipmentSet(ButtonSave["EquipmentSetId"], ButtonSave["EquipmentSetName"]);
|
|
|
|
elseif (Mode == "bonusaction") then
|
|
self:SetCommandExplicitBonusAction(ButtonSave["BonusActionId"]);
|
|
|
|
elseif (Mode == "flyout") then
|
|
self:SetCommandExplicitFlyout(ButtonSave["FlyoutId"]);
|
|
|
|
elseif (Mode == "customaction") then
|
|
self:SetCommandExplicitCustomAction(ButtonSave["CustomActionName"]);
|
|
|
|
else
|
|
self:ClearCommand();
|
|
end
|
|
|
|
if (ButtonForgeSave["RightClickSelfCast"]) then
|
|
self.Widget:SetAttribute("unit2", "player");
|
|
else
|
|
self.Widget:SetAttribute("unit2", nil);
|
|
end
|
|
self:SetButtonLock(ButtonLocked);
|
|
self:SetTooltipEnabled(TooltipEnabled);
|
|
self:SetMacroText(MacroText);
|
|
self:SetKeyBindText(KeyBindText);
|
|
self:SetKeyBind(ButtonSave["KeyBinding"]);
|
|
self:Show();
|
|
self:FullRefresh();
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------
|
|
Deallocate the Button
|
|
----------------------------------------------------------------]]
|
|
function Button:Deallocate()
|
|
self:ClearCommand();
|
|
self:SetKeyBind(nil);
|
|
self:SetOnEnter();
|
|
self:Hide();
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------
|
|
Detach the Button
|
|
----------------------------------------------------------------]]
|
|
function Button:Detach()
|
|
-- Same as Deallocate except this will first detach from its save store to leave that intact
|
|
self.ButtonSave = {};
|
|
self:Deallocate();
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------
|
|
Set functions
|
|
----------------------------------------------------------------]]
|
|
function Button:SetButtonLock(Value)
|
|
self.Locked = Value;
|
|
end
|
|
|
|
function Button:SetTooltipEnabled(Value)
|
|
self.TooltipEnabled = Value;
|
|
self:SetOnEnter();
|
|
end
|
|
|
|
function Button:SetMacroText(Value)
|
|
self.MacroTextEnabled = Value;
|
|
if (self.Mode == "macro") then
|
|
if (Value) then
|
|
self.WName:SetText(self.MacroName);
|
|
else
|
|
self.WName:SetText("");
|
|
end
|
|
end
|
|
end
|
|
|
|
function Button:SetKeyBindText(Value)
|
|
self.KeyBindTextEnabled = Value;
|
|
self:RefreshKeyBindDisplay();
|
|
end
|
|
|
|
function Button:SetKeyBind(Key)
|
|
if (InCombatLockdown()) then
|
|
return false;
|
|
end
|
|
|
|
--Each key owns it's own key binding
|
|
ClearOverrideBindings(self.Widget);
|
|
if (Key ~= "" and Key ~= nil) then
|
|
self.ButtonSave["KeyBinding"] = Key;
|
|
if (Util.ForceOffCastOnKeyDown) then
|
|
SetOverrideBindingClick(self.Widget, false, Key, self.Widget:GetName());
|
|
else
|
|
SetOverrideBindingClick(self.Widget, false, Key, self.Widget:GetName(), "KeyBind");
|
|
end
|
|
self.Widget:SetAttribute("KeyBindValue", Key);
|
|
else
|
|
--clear the binding
|
|
self.ButtonSave["KeyBinding"] = nil;
|
|
self.Widget:SetAttribute("KeyBindValue", nil);
|
|
end
|
|
|
|
self:RefreshKeyBindDisplay();
|
|
|
|
return true;
|
|
end
|
|
|
|
function Button:RefreshKeyBindDisplay()
|
|
local Key = self.ButtonSave["KeyBinding"];
|
|
if (Key ~= nil and self.KeyBindTextEnabled) then
|
|
self.WHotKey:SetText(GetBindingText(Key, "KEY_", 1));
|
|
--if not self.WHotKey.__LBF_SetPoint then
|
|
--self.WHotKey:ClearAllPoints();
|
|
--self.WHotKey:SetPoint("TOPLEFT", self.Widget, "TOPLEFT", -2, -2);
|
|
--end
|
|
self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
|
|
self.WHotKey:Show();
|
|
|
|
else
|
|
self.WHotKey:SetText(RANGE_INDICATOR);
|
|
--if not self.WHotKey.__LBF_SetPoint then
|
|
--self.WHotKey:ClearAllPoints();
|
|
--self.WHotKey:SetPoint("TOPLEFT", self.Widget, "TOPLEFT", 1, -2);
|
|
--end
|
|
self.WHotKey:Hide();
|
|
|
|
end
|
|
end
|
|
|
|
function Button:SetOnEnter(Value)
|
|
if (Value == "KeyBind") then
|
|
self.Widget:SetScript("OnEnter", Button.OnEnterKeyBind);
|
|
self.Widget:SetScript("OnLeave", Button.OnLeaveFlyout);
|
|
elseif (self.TooltipEnabled) then
|
|
self.Widget:SetScript("OnEnter", Button.OnEnterTooltip);
|
|
self.Widget:SetScript("OnLeave", Button.OnLeaveTooltip);
|
|
else
|
|
self.Widget:SetScript("OnEnter", Button.OnEnterFlyout);
|
|
self.Widget:SetScript("OnLeave", Button.OnLeaveFlyout);
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[-------------------------------------------------------------------------
|
|
OnEnter / OnLeave handlers
|
|
---------------------------------------------------------------------------]]
|
|
function Button.OnLeaveTooltip(Widget) --Includes flyout
|
|
GameTooltip:Hide();
|
|
Widget.ParentButton.UpdateTooltip = Button.Empty;
|
|
Widget.ParentButton:UpdateFlyout();
|
|
end
|
|
|
|
function Button.OnEnterTooltip(Widget) --Includes flyout!
|
|
local self = Widget.ParentButton;
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, Widget);
|
|
self.UpdateTooltip = self.UpdateTooltipFunc;
|
|
self.Widget.UpdateTooltip = self.UpdateTooltip;
|
|
self:UpdateTooltip();
|
|
self:UpdateFlyout();
|
|
end
|
|
|
|
function Button.OnEnterKeyBind(Widget)
|
|
UILib.SetMask(Widget.ParentButton, KeyBinder.ShowBindingDialog, KeyBinder.CancelButtonSelectorMode, Widget, "CAST_CURSOR","Interface/TARGETINGFRAME/UI-RaidTargetingIcon_1", {0, 1, 0, 1});
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, Widget);
|
|
end
|
|
|
|
--Noting these are the same function...
|
|
function Button.OnEnterFlyout(Widget)
|
|
local self = Widget.ParentButton;
|
|
self:UpdateFlyout();
|
|
end
|
|
|
|
function Button.OnLeaveFlyout(Widget)
|
|
local self = Widget.ParentButton;
|
|
self:UpdateFlyout();
|
|
end
|
|
|
|
|
|
|
|
--[[----------------------------------------------------------------------------------
|
|
Button Display altering functions (used when reducing cols/rows or hiding
|
|
such as when the grid is not always on, or the button is deallocated
|
|
------------------------------------------------------------------------------------]]
|
|
function Button:Fade(Value)
|
|
if (Value) then
|
|
self.Widget:SetAlpha(0.5);
|
|
else
|
|
self.Widget:SetAlpha(1);
|
|
end
|
|
end
|
|
|
|
function Button:Hide()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
self.Widget:Hide();
|
|
end
|
|
|
|
function Button:Show()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
self.Widget:Show();
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[------------------------------------------------------------------------------------------
|
|
Functions that manage setting the action for the button, including the script handlers
|
|
for the player drag/dropping actions
|
|
--------------------------------------------------------------------------------------------]]
|
|
|
|
--[[ Script Handlers --]]
|
|
function Button.PreClickBasic(Widget, Button, Down)
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
|
|
local Command, Data, Subvalue, Subsubvalue = GetCursorInfo();
|
|
if (not Command) then
|
|
Command, Data, Subvalue, Subsubvalue = UILib.GetDragInfo();
|
|
end
|
|
Util.StoreCursor(Command, Data, Subvalue, Subsubvalue); --Always store this, so that if it is nil PostClick wont try to use it
|
|
if (Command) then
|
|
Widget.BackupType = Widget:GetAttribute("type");
|
|
Widget:SetAttribute("type", ""); --Temp unset the type to prevent any action happening
|
|
end
|
|
end
|
|
function Button.PreClick(Widget, Button, Down)
|
|
if (InCombatLockdown() or Button == "KeyBind" or Down) then
|
|
return;
|
|
end
|
|
|
|
local Command, Data, Subvalue, Subsubvalue = GetCursorInfo();
|
|
if (not Command) then
|
|
Command, Data, Subvalue, Subsubvalue = UILib.GetDragInfo();
|
|
end
|
|
Util.StoreCursor(Command, Data, Subvalue, Subsubvalue); --Always store this, so that if it is nil PostClick wont try to use it
|
|
if (Command) then
|
|
Widget.BackupType = Widget:GetAttribute("type");
|
|
Widget:SetAttribute("type", ""); --Temp unset the type to prevent any action happening
|
|
end
|
|
end
|
|
|
|
function Button.PostClickBasic(Widget, Button, Down)
|
|
local self = Widget.ParentButton;
|
|
self:UpdateChecked();
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
|
|
if (self.Mode == "flyout") then
|
|
BFEventFrames["Full"].RefreshButtons = true;
|
|
BFEventFrames["Full"].RefFlyouts = true;
|
|
end
|
|
if (not InCombatLockdown()) then
|
|
local Command, Data, Subvalue, Subsubvalue = Util.GetStoredCursor();
|
|
if (Command) then
|
|
Util.StoreCursor(self:GetCursor()); --Store the info from the button for later setting the cursor
|
|
if (self:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)) then --Set the button to the cursor
|
|
Util.SetCursor(Util.GetStoredCursor()); --On success set the cursor to the stored button info
|
|
else
|
|
Util.SetCursor(Command, Data, Subvalue, Subsubvalue); --On fail set the cursor to what ever it was
|
|
self.Widget:SetAttribute("type", Widget.BackupType); --and restore the button mode
|
|
end
|
|
end
|
|
end
|
|
--self:UpdateChecked();
|
|
end
|
|
function Button.PostClick(Widget, Button, Down)
|
|
local self = Widget.ParentButton;
|
|
self:UpdateChecked();
|
|
if (InCombatLockdown() or Button == "KeyBind" or Down) then
|
|
return;
|
|
end
|
|
|
|
if (self.Mode == "flyout") then
|
|
BFEventFrames["Full"].RefreshButtons = true;
|
|
BFEventFrames["Full"].RefFlyouts = true;
|
|
end
|
|
if (not InCombatLockdown()) then
|
|
local Command, Data, Subvalue, Subsubvalue = Util.GetStoredCursor();
|
|
if (Command) then
|
|
Util.StoreCursor(self:GetCursor()); --Store the info from the button for later setting the cursor
|
|
if (self:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)) then --Set the button to the cursor
|
|
Util.SetCursor(Util.GetStoredCursor()); --On success set the cursor to the stored button info
|
|
else
|
|
Util.SetCursor(Command, Data, Subvalue, Subsubvalue); --On fail set the cursor to what ever it was
|
|
self.Widget:SetAttribute("type", Widget.BackupType); --and restore the button mode
|
|
end
|
|
end
|
|
end
|
|
--self:UpdateChecked();
|
|
end
|
|
|
|
function Button.OnReceiveDrag(Widget)
|
|
local self = Widget.ParentButton;
|
|
if (not InCombatLockdown()) then
|
|
if (GetCursorInfo()) then
|
|
Util.StoreCursor(self:GetCursor());
|
|
if (self:SetCommandFromTriplet(GetCursorInfo())) then
|
|
Util.SetCursor(Util.GetStoredCursor());
|
|
end
|
|
elseif (UILib.GetDragInfo()) then
|
|
Util.StoreCursor(self:GetCursor());
|
|
if (self:SetCommandFromTriplet(UILib.GetDragInfo())) then
|
|
Util.SetCursor(Util.GetStoredCursor());
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Button.OnDragStart(Widget)
|
|
local self = Widget.ParentButton;
|
|
if (not (InCombatLockdown() or (self.Locked and not IsShiftKeyDown()))) then
|
|
Util.StoreCursor(self:GetCursor());
|
|
if (GetCursorInfo()) then
|
|
if (self:SetCommandFromTriplet(GetCursorInfo())) then
|
|
Util.SetCursor(Util.GetStoredCursor());
|
|
end
|
|
elseif (self:SetCommandFromTriplet(UILib.GetDragInfo())) then
|
|
Util.SetCursor(Util.GetStoredCursor());
|
|
end
|
|
end
|
|
end
|
|
|
|
--[[ Set up the buttons action based on the triplet of data provided from the cursor --]]
|
|
function Button:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)
|
|
if (InCombatLockdown()) then
|
|
return false;
|
|
end
|
|
|
|
local OldMode = self.Mode;
|
|
|
|
if (Command == "spell") then
|
|
self:SetCommandSpell(Subsubvalue); --Data = Index, Subvalue = Book (spell/pet)
|
|
elseif (Command == "petaction") then
|
|
if (Data > 5) then
|
|
-- "Assist, Attack, Defensive, Passive, Follow, Move To, Stay" cause issues so lets ignore them for now. They all have their id between 0 and 5.
|
|
self:SetCommandSpell(Data);
|
|
else
|
|
return false;
|
|
end
|
|
elseif (Command == "item") then
|
|
self:SetCommandItem(Data, Subvalue); --Data = Id, Subvalue = Link
|
|
elseif (Command == "macro") then
|
|
self:SetCommandMacro(Data); --Data = Index
|
|
elseif (Command == "mount") then
|
|
self:SetCommandCompanion(Data); -- Data = MountID, Subvalue = ???
|
|
elseif (Command == "equipmentset") then
|
|
self:SetCommandEquipmentSet(Data); --Data = Name
|
|
elseif (Command == "bonusaction") then
|
|
self:SetCommandBonusAction(Data); --Data = Id (1 to 12)
|
|
elseif (Command == "flyout") then
|
|
self:SetCommandFlyout(Data); --Data = Id
|
|
elseif (Command == "customaction") then
|
|
self:SetCommandCustomAction(Data); --Data = Action
|
|
elseif (Command == nil or Command == "") then
|
|
self:ClearCommand();
|
|
else
|
|
return false;
|
|
end
|
|
|
|
self:FullRefresh();
|
|
return true;
|
|
end
|
|
|
|
--[[ Function to clear the command on the button --]]
|
|
function Button:ClearCommand()
|
|
self:SetEnvClear();
|
|
self:SetAttributes(nil, nil);
|
|
self:SaveClear();
|
|
self:ResetAppearance();
|
|
end
|
|
|
|
--[[ Set the individual types of actions including obtained any extra data they may need --]]
|
|
function Button:SetCommandSpell(Id)
|
|
local Name, Rank = GetSpellInfo(Id);
|
|
local NameRank = Util.GetFullSpellName(Name, Rank);
|
|
self:SetCommandExplicitSpell(Id, NameRank, Name, Book);
|
|
end
|
|
function Button:SetCommandItem(Id, Link)
|
|
local Name;
|
|
Name, Link = GetItemInfo(Id); --Note this will get a clean link, as the one passed in may have enchants etc encoded in it
|
|
self:SetCommandExplicitItem(Id, Name, Link);
|
|
end
|
|
function Button:SetCommandMacro(Index)
|
|
local Name, Texture, Body = GetMacroInfo(Index);
|
|
self:SetCommandExplicitMacro(Index, Name, Body or '');
|
|
end
|
|
function Button:SetCommandCompanion(MountID)
|
|
--local SpellName = GetSpellInfo(SpellId);
|
|
self:SetCommandExplicitCompanion(MountID);
|
|
end
|
|
function Button:SetCommandEquipmentSet(SetName)
|
|
local SetCount = C_EquipmentSet.GetNumEquipmentSets();
|
|
for i=0,SetCount-1 do
|
|
name, texture, setIndex, isEquipped, totalItems, equippedItems, inventoryItems, missingItems, ignoredSlots = C_EquipmentSet.GetEquipmentSetInfo(i);
|
|
if (name == SetName ) then
|
|
self:SetCommandExplicitEquipmentSet(setIndex, name);
|
|
break;
|
|
end
|
|
end;
|
|
end
|
|
function Button:SetCommandBonusAction(Id)
|
|
self:SetCommandExplicitBonusAction(Id);
|
|
end
|
|
function Button:SetCommandFlyout(Id)
|
|
self:SetCommandExplicitFlyout(Id);
|
|
end
|
|
function Button:SetCommandCustomAction(Name)
|
|
self:SetCommandExplicitCustomAction(Name);
|
|
end
|
|
|
|
--[[ Set the individual types of actions (all data needed is supplied to the functions as args) --]]
|
|
function Button:SetCommandExplicitSpell(Id, NameRank, Name, Book)
|
|
local IsTalent = Util.IsSpellIdTalent(Id);
|
|
self:SetEnvSpell(Id, NameRank, Name, Book, IsTalent);
|
|
if (IsTalent) then
|
|
-- Talents only can be triggered off the name, The API is really random as to when it works better with the name vs ID
|
|
self:SetAttributes("spell", NameRank);
|
|
else
|
|
-- Normal spells work both ways... But! some spells like Shaman Hex() have same name variants, in those cases I need to cast the specific ID
|
|
-- And yes, as it stands if Blizz do same name variant Talents, then well bugger...
|
|
self:SetAttributes("spell", Id);
|
|
end
|
|
self:SaveSpell(Id, NameRank, Name, Book);
|
|
end
|
|
function Button:SetCommandExplicitItem(Id, Name, Link)
|
|
self:SetEnvItem(Id, Name, Link);
|
|
self:SetAttributes("item", Name);
|
|
self:SaveItem(Id, Name, Link);
|
|
end
|
|
function Button:SetCommandExplicitMacro(Index, Name, Body)
|
|
self:SetEnvMacro(Index, Name, Body);
|
|
self:SetAttributes("macro", Index);
|
|
self:SaveMacro(Index, Name, Body);
|
|
end
|
|
function Button:SetCommandExplicitCompanion(MountID)
|
|
self:SetEnvCompanion(MountID);
|
|
--self:SetAttributes("companion", SpellName); mopved to set env
|
|
--self:SaveCompanion(Index, SpellID); moved to end of set env
|
|
end
|
|
function Button:SetCommandExplicitEquipmentSet(Id, Name)
|
|
self:SetEnvEquipmentSet(Id, Name);
|
|
self:SetAttributes("equipmentset", Name);
|
|
self:SaveEquipmentSet(Id, Name);
|
|
end
|
|
function Button:SetCommandExplicitBonusAction(Id)
|
|
self:SetAttributes("bonusaction", Id);
|
|
self:SetEnvBonusAction(Id);
|
|
|
|
self:SaveBonusAction(Id);
|
|
end
|
|
function Button:SetCommandExplicitFlyout(Id)
|
|
self:SetEnvFlyout(Id);
|
|
self:SetAttributes("flyout", Id);
|
|
self:SaveFlyout(Id);
|
|
end
|
|
function Button:SetCommandExplicitCustomAction(Name)
|
|
self:SetEnvCustomAction(Name);
|
|
self:SetAttributes("customaction", Name);
|
|
self:SaveCustomAction(Name);
|
|
end
|
|
|
|
--[[ The following functions will configure the button to operate correctly for the specific type of action (these functions must be able to handle the player not knowing spells/macros etc) --]]
|
|
function Button:SetEnvSpell(Id, NameRank, Name, Book, IsTalent)
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateCheckedSpell;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.UpdateCooldownSpell;
|
|
self.UpdateUsable = Button.UpdateUsableSpell;
|
|
self.UpdateTextCount = Button.UpdateTextCountSpell;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipSpell;
|
|
self.UpdateRangeTimer = Button.UpdateRangeTimerSpell;
|
|
self.CheckRangeTimer = Button.CheckRangeTimerSpell;
|
|
self.UpdateFlash = Button.UpdateFlashSpell;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorSpell;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
local Matched = false;
|
|
if (Const.WispSpellIds[Id]) then
|
|
-- This spell may update its icon to the wisp state...
|
|
self.UpdateTexture = Button.UpdateTextureWispSpell;
|
|
end
|
|
|
|
self.Mode = "spell";
|
|
self.SpellId = Id;
|
|
self.SpellNameRank = NameRank;
|
|
self.SpellName = Name;
|
|
self.SpellBook = Book;
|
|
self.SpellIsTalent = IsTalent;
|
|
self.Texture = GetSpellTexture(Id) or "Interface/Icons/INV_Misc_QuestionMark";
|
|
self.Target = "target";
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
Util.AddSpell(self);
|
|
end
|
|
function Button:SetEnvItem(Id, Name, Link)
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateCheckedItem;
|
|
self.UpdateEquipped = Button.UpdateEquippedItem;
|
|
self.UpdateCooldown = Button.UpdateCooldownItem;
|
|
self.UpdateUsable = Button.UpdateUsableItem;
|
|
self.UpdateTextCount = Button.UpdateTextCountItem;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipItem;
|
|
self.UpdateRangeTimer = Button.UpdateRangeTimerItem;
|
|
self.CheckRangeTimer = Button.CheckRangeTimerItem;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorItem;
|
|
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
self.Mode = "item";
|
|
self.ItemId = Id;
|
|
self.ItemName = Name;
|
|
self.ItemLink = Link;
|
|
self.Texture = GetItemIcon(Id) or "Interface/Icons/INV_Misc_QuestionMark"; --safe no matter what
|
|
self.Target = "target";
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
Util.AddItem(self);
|
|
end
|
|
function Button:SetEnvMacro(Index, Name, Body)
|
|
self.UpdateTexture = Button.UpdateTextureMacro;
|
|
self.UpdateChecked = Button.UpdateCheckedMacro;
|
|
self.UpdateEquipped = Button.UpdateEquippedMacro;
|
|
self.UpdateCooldown = Button.UpdateCooldownMacro;
|
|
self.UpdateUsable = Button.UpdateUsableMacro;
|
|
self.UpdateTextCount = Button.UpdateTextCountMacro;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipMacro;
|
|
self.UpdateRangeTimer = Button.UpdateRangeTimerMacro;
|
|
self.CheckRangeTimer = Button.CheckRangeTimerMacro;
|
|
self.UpdateFlash = Button.UpdateFlashMacro;
|
|
self.TranslateMacro = Button.TranslateMacro;
|
|
self.GetCursor = Button.GetCursorMacro;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.FullRefresh = Button.FullRefreshMacro;
|
|
|
|
self.Mode = "macro";
|
|
self.MacroIndex = Index;
|
|
self.MacroName = Name;
|
|
self.MacroBody = Body;
|
|
self.Texture = nil; --set in translate macro
|
|
self.Target = "target";
|
|
self.ShowTooltip = string.find(Body, "#showtooltip") ~= nil;
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
|
|
Util.AddMacro(self);
|
|
end
|
|
function Button:SetEnvCompanion(MountID)
|
|
if (not MountID) then
|
|
return self:ClearCommand();
|
|
end
|
|
-- now only handles mounts
|
|
-- This code path ultimately works - but it is a bit wonky when the Summon Random Favorite comes through
|
|
--[[if (SpellID == nil) then
|
|
-- We got the useless Index, try and map it
|
|
Index = Util.GetMountIndexFromUselessIndex(Index);
|
|
SpellID = select(2, C_MountJournal.GetDisplayedMountInfo(Index));
|
|
else
|
|
-- We got a good Index, but we should check that
|
|
-- the Mapping is still valid
|
|
if (SpellID ~= select(2, C_MountJournal.GetDisplayedMountInfo(Index))) then
|
|
-- The mapping isn't right, so update the Index
|
|
Index = Util.GetMountIndexFromSpellID(SpellID);
|
|
end
|
|
end--]]
|
|
|
|
--[[if (Index == nil) then
|
|
-- So no mount was found
|
|
self:ClearCommand();
|
|
return;]]
|
|
--local SpellID = select(2, C_MountJournal.GetDisplayedMountInfo(Index));
|
|
--if (Index == 0) then
|
|
-- It's the random favorite button
|
|
--SpellID = Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL;
|
|
|
|
--self:SetMountFavorite(BFButton);
|
|
--return;
|
|
--end
|
|
self.Widget:SetAttribute("type", nil);
|
|
self.Widget:SetAttribute("spell", nil);
|
|
self.Widget:SetAttribute("item", nil);
|
|
self.Widget:SetAttribute("macro", nil);
|
|
self.Widget:SetAttribute("macrotext", nil);
|
|
self.Widget:SetAttribute("action", nil);
|
|
self.Widget:SetAttribute("id", nil);
|
|
self.Mode = "mount";
|
|
self.MountID = MountID;
|
|
|
|
if (self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID) then
|
|
self.MountName = GetSpellInfo(Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL);
|
|
self.MountSpellID = Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL;
|
|
self.MountSpellName = self.MountName;
|
|
|
|
|
|
|
|
if (ButtonForgeGlobalSettings["UseCollectionsFavoriteMountButton"] and not IsAddOnLoaded("Blizzard_Collections")) then
|
|
LoadAddOn("Blizzard_Collections");
|
|
end
|
|
if (ButtonForgeGlobalSettings["UseCollectionsFavoriteMountButton"] and MountJournalSummonRandomFavoriteButton) then
|
|
self.Widget:SetAttribute("type", "click");
|
|
self.Widget:SetAttribute("clickbutton", MountJournalSummonRandomFavoriteButton);
|
|
else
|
|
-- this will cause a script warning when clicked if the player does not allow dangerous scripts but also chooses false for the global setting
|
|
self.Widget:SetAttribute("type", "macro");
|
|
self.Widget:SetAttribute("macrotext", "/run C_MountJournal.SummonByID("..self.MountID..")");
|
|
end
|
|
|
|
else
|
|
self.MountName = C_MountJournal.GetMountInfoByID(MountID);
|
|
self.MountSpellID = select(2, C_MountJournal.GetMountInfoByID(MountID));
|
|
self.MountSpellName = GetSpellInfo(self.MountSpellID);
|
|
self.Widget:SetAttribute("type", "macro");
|
|
self.Widget:SetAttribute("macrotext", "/cast "..self.MountSpellName);
|
|
end
|
|
|
|
|
|
self.Texture = GetSpellTexture(self.MountSpellID); --select(3, C_MountJournal.GetDisplayedMountInfo(Index));
|
|
|
|
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateCheckedCompanion;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.UpdateCooldownCompanion;
|
|
self.UpdateUsable = Button.UpdateUsableCompanion;
|
|
self.UpdateTextCount = Button.Empty;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipCompanion;
|
|
self.UpdateRangeTimer = Button.Empty;
|
|
self.CheckRangeTimer = Button.Empty;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorCompanion;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
--[[self.Mode = "companion";
|
|
self.CompanionId = Id;
|
|
self.CompanionType = Type;
|
|
self.CompanionIndex = Index;
|
|
self.CompanionName = Name;
|
|
self.CompanionSpellName = SpellName;
|
|
self.Texture = select(4, GetCompanionInfo(Type, Index)); --safe provided Type in ("MOUNT", "CRITTER") and Index is numeric
|
|
]]
|
|
self.Target = "target";
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
self:SaveCompanion(MountID, self.MountSpellID, self.MountName);
|
|
end
|
|
function Button:SetEnvEquipmentSet(Id, Name)
|
|
local Index = Util.LookupEquipmentSetIndex(Id);
|
|
|
|
if (Index == nil) then
|
|
-- This equip set is gone so clear it from the button
|
|
return self:ClearCommand();
|
|
end
|
|
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateChecked;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.Empty;
|
|
self.UpdateUsable = Button.Empty;
|
|
self.UpdateTextCount = Button.Empty;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipEquipmentSet;
|
|
self.UpdateRangeTimer = Button.Empty;
|
|
self.CheckRangeTimer = Button.Empty;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorEquipmentSet;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
self.Mode = "equipmentset";
|
|
self.EquipmentSetId = Id;
|
|
self.EquipmentSetName = Name;
|
|
self.Texture = select(2, C_EquipmentSet.GetEquipmentSetInfo(Index)) or ""; --"Interface/Icons/"..(GetEquipmentSetInfoByName(Name) or ""); --safe provided Name ~= nil
|
|
self.Target = "target";
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
self.WName:SetText(Name);
|
|
end
|
|
function Button:SetEnvBonusAction(Id)
|
|
self.UpdateTexture = Button.UpdateTextureBonusAction;
|
|
self.UpdateChecked = Button.UpdateCheckedBonusAction;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.UpdateCooldownBonusAction;
|
|
self.UpdateUsable = Button.UpdateUsableBonusAction;
|
|
self.UpdateTextCount = Button.UpdateTextCountBonusAction;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipBonusAction;
|
|
self.UpdateRangeTimer = Button.UpdateRangeTimerBonusAction;
|
|
self.CheckRangeTimer = Button.CheckRangeTimerBonusAction;
|
|
self.UpdateFlash = Button.UpdateFlashBonusAction;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorBonusAction;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
self.Mode = "bonusaction";
|
|
self.BonusActionId = Id;
|
|
self.BonusActionSlot = Id + 132;
|
|
self.Texture = GetActionTexture(self.BonusActionSlot);-- "Interface/Icons/"..(GetEquipmentSetInfoByName(Name) or ""); --safe provided Name ~= nil
|
|
self.Target = "target";
|
|
self.Tooltip = Util.GetLocaleString("BonusActionTooltip")..Id;
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
Util.AddBonusAction(self);
|
|
end
|
|
function Button:SetEnvFlyout(Id)
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateChecked;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.Empty;
|
|
self.UpdateUsable = Button.Empty;
|
|
self.UpdateTextCount = Button.Empty;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipFlyout;
|
|
self.UpdateRangeTimer = Button.Empty;
|
|
self.CheckRangeTimer = Button.Empty;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.UpdateFlyout;
|
|
|
|
self.GetCursor = Button.GetCursorFlyout;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
self.Mode = "flyout";
|
|
self.FlyoutId = Id;
|
|
local ind, booktype = Util.LookupSpellIndex("FLYOUT"..Id);
|
|
if (ind) then
|
|
self.Texture = GetSpellBookItemTexture(ind, booktype) or "Interface/Icons/INV_Misc_QuestionMark";
|
|
else
|
|
self.Texture = "Interface/Icons/INV_Misc_QuestionMark";
|
|
end
|
|
self.Target = "target";
|
|
self.Tooltip = "Placeholder";
|
|
self:ResetAppearance();
|
|
self:DisplayActive();
|
|
self:UpdateFlyout();
|
|
|
|
|
|
-- BFFlyoutWrapperFrame:WrapScript(SpellFlyout, "OnShow", [[return true, "true";]], [[owner:CallMethod("RefreshFlyouts");]]);
|
|
--BFFlyoutWrapperFrame:WrapScript(SpellFlyout, "OnHide", [[return true, "true";]], [[owner:CallMethod("RefreshFlyouts");]]);
|
|
end
|
|
function Button:SetEnvCustomAction(Name)
|
|
local TexCoords;
|
|
self.UpdateTexture = Button.UpdateTextureCustomAction;
|
|
self.UpdateChecked = Button.UpdateCheckedCustomAction;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.Empty;
|
|
self.UpdateUsable = Button.UpdateUsableCustomAction;
|
|
self.UpdateTextCount = Button.Empty;
|
|
self.UpdateTooltipFunc = Button.UpdateTooltipCustomAction;
|
|
self.UpdateRangeTimer = Button.Empty;
|
|
self.CheckRangeTimer = Button.Empty;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.GetCursorCustomAction;
|
|
|
|
self.FullRefresh = Button.FullRefresh;
|
|
|
|
self.Mode = "customaction";
|
|
self.CustomActionName = Name;
|
|
self.Texture, TexCoords = CustomAction.GetTexture(Name);
|
|
self.Target = "target";
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayActive(TexCoords);
|
|
Util.AddBonusAction(self);
|
|
end
|
|
function Button:SetEnvClear()
|
|
self.UpdateTexture = Button.Empty;
|
|
self.UpdateChecked = Button.UpdateChecked;
|
|
self.UpdateEquipped = Button.Empty;
|
|
self.UpdateCooldown = Button.Empty;
|
|
self.UpdateUsable = Button.Empty;
|
|
self.UpdateTextCount = Button.Empty;
|
|
self.UpdateTooltipFunc = Button.Empty;
|
|
self.UpdateRangeTimer = Button.Empty;
|
|
self.CheckRangeTimer = Button.Empty;
|
|
self.UpdateFlash = Button.Empty;
|
|
self.UpdateFlyout = Button.Empty;
|
|
|
|
self.GetCursor = Button.Empty;
|
|
|
|
self.FullRefresh = Button.Empty;
|
|
|
|
self.Mode = nil;
|
|
|
|
self:ResetAppearance();
|
|
self:DisplayEmpty();
|
|
end
|
|
|
|
--[[ These functions will update the save data for the button action --]]
|
|
function Button:SaveSpell(Id, NameRank, Name, Book)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "spell";
|
|
self.ButtonSave["SpellId"] = Id;
|
|
self.ButtonSave["SpellNameRank"] = NameRank;
|
|
self.ButtonSave["SpellName"] = Name;
|
|
self.ButtonSave["SpellBook"] = Book;
|
|
end
|
|
function Button:SaveItem(Id, Name, Link)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "item";
|
|
self.ButtonSave["ItemId"] = Id;
|
|
self.ButtonSave["ItemName"] = Name;
|
|
self.ButtonSave["ItemLink"] = Link;
|
|
end
|
|
function Button:SaveMacro(Index, Name, Body)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "macro";
|
|
self.ButtonSave["MacroIndex"] = Index;
|
|
self.ButtonSave["MacroName"] = Name;
|
|
self.ButtonSave["MacroBody"] = Body;
|
|
end
|
|
function Button:SaveCompanion(MountID, MountSpellID, MountName)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "mount";
|
|
self.ButtonSave["MountID"] = MountID;
|
|
self.ButtonSave["MountSpellID"] = MountSpellID;
|
|
self.ButtonSave["MountName"] = MountName;
|
|
end
|
|
function Button:SaveEquipmentSet(Id, Name)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "equipmentset";
|
|
self.ButtonSave["EquipmentSetId"] = Id;
|
|
self.ButtonSave["EquipmentSetName"] = Name;
|
|
end
|
|
function Button:SaveBonusAction(Id)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "bonusaction";
|
|
self.ButtonSave["BonusActionId"] = Id;
|
|
end
|
|
function Button:SaveFlyout(Id)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "flyout";
|
|
self.ButtonSave["FlyoutId"] = Id;
|
|
end
|
|
function Button:SaveCustomAction(Name)
|
|
self:SaveClear();
|
|
self.ButtonSave["Mode"] = "customaction";
|
|
self.ButtonSave["CustomActionName"] = Name;
|
|
end
|
|
function Button:SaveClear()
|
|
self.ButtonSave["SpellId"] = nil;
|
|
self.ButtonSave["SpellNameRank"] = nil;
|
|
self.ButtonSave["SpellName"] = nil;
|
|
self.ButtonSave["SpellBook"] = nil;
|
|
self.ButtonSave["ItemId"] = nil;
|
|
self.ButtonSave["ItemName"] = nil;
|
|
self.ButtonSave["ItemLink"] = nil;
|
|
self.ButtonSave["MacroIndex"] = nil;
|
|
self.ButtonSave["MacroName"] = nil;
|
|
self.ButtonSave["MacroBody"] = nil;
|
|
self.ButtonSave["CompanionId"] = nil;
|
|
self.ButtonSave["CompanionType"] = nil;
|
|
self.ButtonSave["CompanionIndex"] = nil;
|
|
self.ButtonSave["CompanionName"] = nil;
|
|
self.ButtonSave["MountIndex"] = nil;
|
|
self.ButtonSave["MountSpellID"] = nil;
|
|
self.ButtonSave["MountName"] = nil;
|
|
self.ButtonSave["MountID"] = nil;
|
|
self.ButtonSave["CompanionSpellName"] = nil;
|
|
self.ButtonSave["MountIndex"] = nil;
|
|
self.ButtonSave["MountSpellID"] = nil;
|
|
self.ButtonSave["MountName"] = nil;
|
|
self.ButtonSave["EquipmentSetId"] = nil;
|
|
self.ButtonSave["EquipmentSetName"] = nil;
|
|
self.ButtonSave["BonusActionId"] = nil;
|
|
self.ButtonSave["FlyoutId"] = nil;
|
|
self.ButtonSave["CustomActionName"] = nil;
|
|
self.ButtonSave["Mode"] = nil;
|
|
end
|
|
|
|
--[[ Set the buttons attributes (When I get some spare time this could be put in the secure env to allow changing the button during combat) --]]
|
|
function Button:SetAttributes(Type, Value)
|
|
--Firstly clear all relevant fields
|
|
self.Widget:SetAttribute("type", nil);
|
|
self.Widget:SetAttribute("spell", nil);
|
|
self.Widget:SetAttribute("item", nil);
|
|
self.Widget:SetAttribute("macro", nil);
|
|
self.Widget:SetAttribute("macrotext", nil);
|
|
self.Widget:SetAttribute("action", nil);
|
|
self.Widget:SetAttribute("clickbutton", nil);
|
|
self.Widget:SetAttribute("id", nil);
|
|
|
|
--Now if a valid type is passed in set it
|
|
if (Type == "spell") then
|
|
-- Patch to fix some spell that doesnt like to be cast with ID (Thrash, Stampeding Roar, ...)
|
|
local SpellName = GetSpellInfo(Value);
|
|
if ( SpellName ) then
|
|
self.Widget:SetAttribute("type", Type);
|
|
self.Widget:SetAttribute(Type, SpellName);
|
|
else
|
|
-- fallback to the old method if the name cannot be resolved
|
|
self.Widget:SetAttribute("type", Type);
|
|
self.Widget:SetAttribute(Type, Value);
|
|
end
|
|
|
|
elseif (Type == "item" or Type == "macro") then
|
|
self.Widget:SetAttribute("type", Type);
|
|
self.Widget:SetAttribute(Type, Value);
|
|
|
|
elseif (Type == "companion") then
|
|
self.Widget:SetAttribute("type", "spell");
|
|
self.Widget:SetAttribute("spell", Value);
|
|
|
|
elseif (Type == "equipmentset") then
|
|
self.Widget:SetAttribute("type", "macro");
|
|
self.Widget:SetAttribute("macrotext", "/equipset "..Value);
|
|
elseif (Type == "bonusaction") then
|
|
self.Widget:SetAttribute("type", "action");
|
|
self.Widget:SetAttribute("id", Value);
|
|
if (HasOverrideActionBar()) then
|
|
self.Widget:SetAttribute("action", Value + ((14 - 1) * 12));
|
|
else
|
|
self.Widget:SetAttribute("action", Value + ((12 - 1) * 12));
|
|
end
|
|
elseif (Type == "flyout") then
|
|
self.Widget:SetAttribute("type", "flyout");
|
|
self.Widget:SetAttribute("spell", Value);
|
|
elseif (Type == "customaction") then
|
|
CustomAction.SetAttributes(Value, self.Widget);
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------------------
|
|
Tidy up the display state for a button (does not include the icon itself)
|
|
----------------------------------------------------------------------------]]
|
|
function Button:ResetAppearance()
|
|
self.Widget:SetChecked(false);
|
|
|
|
self.WBorder:Hide();
|
|
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
|
|
self.WCooldown:Hide();
|
|
|
|
self.WIcon:SetAlpha(1);
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WIcon:SetTexCoord(0, 1, 0, 1);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
|
|
self.WCount:SetText("");
|
|
self.WName:SetText("");
|
|
Util.RemoveMacro(self);
|
|
Util.RemoveSpell(self);
|
|
Util.RemoveItem(self);
|
|
Util.RemoveBonusAction(self);
|
|
self:RemoveFromRangeTimer();
|
|
self:RemoveFromFlash();
|
|
Button.UpdateFlyout(self);
|
|
self:UpdateGlow();
|
|
if (self.TooltipEnabled and GetMouseFocus() == self.Widget) then
|
|
Button.OnEnterTooltip(self.Widget);
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------------------
|
|
Functions to do a full refresh of the display info for the Button
|
|
----------------------------------------------------------------------------]]
|
|
function Button:FullRefresh()
|
|
self:UpdateTexture();
|
|
self:UpdateChecked();
|
|
self:UpdateEquipped();
|
|
self:UpdateCooldown();
|
|
self:UpdateUsable();
|
|
self:UpdateTextCount();
|
|
self:UpdateRangeTimer();
|
|
self:UpdateFlash();
|
|
self:UpdateFlyout();
|
|
self:UpdateGlow();
|
|
|
|
self:UpdateTooltip();
|
|
|
|
end
|
|
|
|
function Button:FullRefreshMacro()
|
|
self:TranslateMacro();
|
|
Button.FullRefresh(self);
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[------------------------------------------------------------------------------
|
|
Since macros have to masquerade as potentially several different types this
|
|
function will cache what the macro currently is
|
|
--------------------------------------------------------------------------------]]
|
|
function Button:TranslateMacro()
|
|
local Texture = select(2, GetMacroInfo(self.MacroIndex));
|
|
--self.Texture = select(2, GetMacroInfo(self.MacroIndex));
|
|
local Action, Target = SecureCmdOptionParse(self.MacroBody or '');
|
|
self.Target = Target or "target"; --check into if this is the best thing to do or leaving it nil would be better?
|
|
local TargetName = UnitName(self.Target);
|
|
local TargetDead = UnitIsDead(self.Target);
|
|
if (self.Texture ~= Texture or self.MacroAction ~= Action or self.MacroTargetName ~= TargetName or self.MacroTargetDead ~= TargetDead) then
|
|
self.Texture = Texture;
|
|
self.MacroAction = Action;
|
|
self.MacroTargetName = TargetName;
|
|
self.MacroTargetDead = TargetDead;
|
|
local SpellName, SpellRank, SpellId = GetMacroSpell(self.MacroIndex);
|
|
if (SpellName) then
|
|
local CompanionType, CompanionID = Util.LookupCompanion(SpellName);
|
|
if (CompanionType) then
|
|
self.CompanionType = CompanionType;
|
|
self.CompanionIndex = CompanionID;
|
|
end
|
|
self.SpellName = SpellName;
|
|
self.SpellNameRank = GetSpellInfo(SpellName); --BFA fix: Cache is indexed by name and the old function returned the ID
|
|
self.SpellId = SpellId;
|
|
self.MacroMode = "spell";
|
|
else
|
|
local ItemName, ItemLink = GetMacroItem(self.MacroIndex);
|
|
if (ItemName) then
|
|
self.ItemId = Util.GetItemId(ItemName) or GetItemInfoInstant(ItemName) or 0; --basically we can't easily get the id, but for the item function calls below, itemid in the context of a macro should be fine
|
|
self.ItemName = ItemName;
|
|
self.ItemLink = ItemLink;
|
|
self.MacroMode = "item";
|
|
else
|
|
self.MacroMode = "";
|
|
end
|
|
end
|
|
Button.FullRefresh(self);
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[---------------------------------------------------------------------------------
|
|
Texture functions
|
|
-----------------------------------------------------------------------------------]]
|
|
function Button:UpdateTexture()
|
|
|
|
end
|
|
|
|
--BFA fix: BFA removed the use of UnitBuff with the spell name as a parameter.
|
|
--BFA fix: Added this function to compensate
|
|
function Button:UnitBuffBySpell(unit, spell)
|
|
for i=1,40 do
|
|
local name, icon, _, _, _, etime = UnitBuff(unit,i)
|
|
if name then
|
|
if name == spell then
|
|
return UnitBuff(unit,i);
|
|
end
|
|
else
|
|
break;
|
|
end;
|
|
end;
|
|
return nil;
|
|
end;
|
|
|
|
function Button:UpdateTextureWispSpell()
|
|
--BFA fix: UnitBuff can no longer be called with the spell name as a param
|
|
if (self.UnitBuffBySpell("player", self.SpellName)) then --NOTE: This en-US, hopefully it will be fine for other locales as well??
|
|
self.WIcon:SetTexture("Interface/Icons/Spell_Nature_WispSplode");
|
|
else
|
|
self.WIcon:SetTexture(self.Texture);
|
|
end
|
|
end
|
|
function Button:UpdateTextureMacro()
|
|
self.WIcon:SetTexture(self.Texture);
|
|
end
|
|
function Button:UpdateTextureBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if (HasOverrideActionBar() or HasVehicleActionBar()) then
|
|
local Texture = GetActionTexture(action);
|
|
if (not Texture) then
|
|
self.WIcon:SetTexture(Const.ImagesDir.."Bonus"..self.BonusActionId);
|
|
self.WIcon:SetAlpha(0.1);
|
|
else
|
|
self.WIcon:SetTexture(Texture);
|
|
self.WIcon:SetAlpha(1);
|
|
end
|
|
|
|
else
|
|
self.WIcon:SetTexture(Const.ImagesDir.."Bonus"..self.BonusActionId);
|
|
self.WIcon:SetAlpha(1);
|
|
end
|
|
end
|
|
function Button:UpdateTextureCustomAction()
|
|
self.WIcon:SetTexture(CustomAction.GetTexture(self.CustomActionName));
|
|
end
|
|
|
|
|
|
|
|
function Button:DisplayActive(TexCoords)
|
|
local Icon = self.WIcon;
|
|
|
|
Icon:SetTexture(self.Texture);
|
|
self.Widget:SetNormalTexture("Interface/Buttons/UI-Quickslot2");
|
|
if (TexCoords) then
|
|
Icon:SetTexCoord(unpack(TexCoords));
|
|
else
|
|
Icon:SetTexCoord(0, 1, 0, 1);
|
|
end
|
|
Icon:SetVertexColor(1.0, 1.0, 1.0, 1.0);
|
|
Icon:Show();
|
|
|
|
end
|
|
function Button:DisplayMissing()
|
|
local Icon = self.WIcon;
|
|
|
|
Icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark");
|
|
self.Widget:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
|
|
Icon:SetVertexColor(1.0, 1.0, 1.0, 0.5);
|
|
Icon:Show();
|
|
|
|
end
|
|
function Button:DisplayEmpty()
|
|
self.WIcon:Hide();
|
|
--self.Widget:SetNormalTexture("Interface/Buttons/UI-Quickslot");
|
|
self.WCooldown:Hide();
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------------------
|
|
Checked functions
|
|
----------------------------------------------------------------------------]]
|
|
function Button:UpdateChecked()
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
function Button:UpdateCheckedSpell()
|
|
if (IsCurrentSpell(self.SpellNameRank) or IsAutoRepeatSpell(self.SpellNameRank)) then
|
|
self.Widget:SetChecked(true);
|
|
else
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
end
|
|
function Button:UpdateCheckedItem()
|
|
if (IsCurrentItem(self.ItemId)) then
|
|
self.Widget:SetChecked(true);
|
|
else
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
end
|
|
function Button:UpdateCheckedMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateCheckedSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:UpdateCheckedItem();
|
|
elseif (self.MacroMode == "companion") then
|
|
self:UpdateCheckedCompanion();
|
|
else
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
end
|
|
function Button:UpdateCheckedCompanion()
|
|
--local Active = select(5, GetCompanionInfo(self.CompanionType, self.CompanionIndex));
|
|
--local SpellName = UnitCastingInfo("player");
|
|
if (select(4, C_MountJournal.GetMountInfoByID(self.MountID))
|
|
or (self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID and IsMounted())) then
|
|
self.Widget:SetChecked(true);
|
|
else
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
end
|
|
function Button:UpdateCheckedBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if ((HasOverrideActionBar() or HasVehicleActionBar()) and (IsCurrentAction(action) or IsAutoRepeatAction(action))) then
|
|
self.Widget:SetChecked(true);
|
|
else
|
|
self.Widget:SetChecked(false);
|
|
end
|
|
end
|
|
function Button:UpdateCheckedCustomAction()
|
|
self.Widget:SetChecked(CustomAction.GetChecked(self.CustomActionName));
|
|
end
|
|
|
|
|
|
--[[---------------------------------------------------------------------------------------
|
|
Equipped functions
|
|
-----------------------------------------------------------------------------------------]]
|
|
function Button:UpdateEquipped()
|
|
|
|
end
|
|
|
|
function Button:UpdateEquippedItem()
|
|
if (IsEquippedItem(self.ItemId)) then
|
|
self.WBorder:SetVertexColor(0, 1.0, 0, 0.35);
|
|
self.WBorder:Show();
|
|
else
|
|
self.WBorder:Hide();
|
|
end
|
|
end
|
|
function Button:UpdateEquippedMacro()
|
|
if (self.MacroMode == "item") then
|
|
self:UpdateEquippedItem();
|
|
else
|
|
self.WBorder:Hide();
|
|
end
|
|
end
|
|
-- In future it may be an idea to do an equip set check although I question the value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--[[-------------------------------------------------------------------------------------------
|
|
Cooldown functions (great care is needed with the cooldowns...)
|
|
---------------------------------------------------------------------------------------------]]
|
|
function Button:UpdateCooldown()
|
|
|
|
end
|
|
function Button:UpdateCooldownSpell()
|
|
local Start, Duration, Enable = GetSpellCooldown(self.SpellNameRank);
|
|
local Charges, MaxCharges, ChargeStart, ChargeDuration = GetSpellCharges(self.SpellNameRank);
|
|
|
|
if (Start ~= nil) then
|
|
--Charges = Charges or 0;
|
|
--MaxCharges = MaxCharges or 0;
|
|
if (Charges ~= MaxCharges) then
|
|
Start = ChargeStart;
|
|
Duration = ChargeDuration;
|
|
end
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, Start, Duration, Enable, Charges, MaxCharges);
|
|
else
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
|
|
self.WCooldown:Hide();
|
|
end
|
|
end
|
|
function Button:UpdateCooldownItem()
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, GetItemCooldown(self.ItemId));
|
|
end
|
|
function Button:UpdateCooldownMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateCooldownSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:UpdateCooldownItem();
|
|
elseif (self.MacroMode == "companion") then
|
|
self:UpdateCooldownCompanion();
|
|
else
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
|
|
self.WCooldown:Hide();
|
|
end
|
|
end
|
|
function Button:UpdateCooldownCompanion()
|
|
--CooldownFrame_SetTimer(self.WCooldown, GetCompanionCooldown(self.CompanionType, self.CompanionIndex));
|
|
--as of 5.0.4 doesn't appear to exist anymore?!
|
|
end
|
|
function Button:UpdateCooldownBonusAction()
|
|
if (HasOverrideActionBar() or HasVehicleActionBar()) then
|
|
local action = self.Widget:GetAttribute("action");
|
|
Util.CooldownFrame_SetTimer(self.WCooldown, GetActionCooldown(action));
|
|
else
|
|
self.WCooldown:Hide();
|
|
end
|
|
end
|
|
|
|
|
|
--[[-------------------------------------------------------------------------------------
|
|
Usable Functions
|
|
---------------------------------------------------------------------------------------]]
|
|
function Button:UpdateUsable()
|
|
|
|
end
|
|
function Button:UpdateUsableSpell()
|
|
local IsUsable, NotEnoughMana = IsUsableSpell(self.SpellNameRank);
|
|
if (IsUsable) then
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
elseif (NotEnoughMana) then
|
|
self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
|
|
self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
|
|
else
|
|
self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
function Button:UpdateUsableItem()
|
|
local IsUsable, NotEnoughMana = IsUsableItem(self.ItemId);
|
|
IsUsable = IsUsable or PlayerHasToy(self.ItemId);
|
|
if (IsUsable) then
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
elseif (NotEnoughMana) then
|
|
self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
|
|
self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
|
|
else
|
|
self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
function Button:UpdateUsableMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateUsableSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:UpdateUsableItem();
|
|
elseif (self.MacroMode == "companion") then
|
|
self:UpdateUsableCompanion();
|
|
else
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
function Button:UpdateUsableCompanion()
|
|
local IsUsable = IsUsableSpell(self.MountSpellID) and (select(5, C_MountJournal.GetMountInfoByID(self.MountID)) or self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID);
|
|
|
|
if (IsUsable) then
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
else
|
|
self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
function Button:UpdateUsableBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
local IsUsable, NotEnoughMana = IsUsableAction(action);
|
|
if (IsUsable or (HasOverrideActionBar() == nil and HasVehicleActionBar() == nil)) then
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
elseif (NotEnoughMana) then
|
|
self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
|
|
self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
|
|
else
|
|
self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
function Button:UpdateUsableCustomAction()
|
|
local IsUsable, NotEnoughMana = CustomAction.IsUsable(self.CustomActionName);
|
|
if (IsUsable) then
|
|
self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
elseif (NotEnoughMana) then
|
|
self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
|
|
self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
|
|
else
|
|
self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
|
|
self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
|
|
|
|
--[[----------------------------------------------------------------------------
|
|
Text functions
|
|
------------------------------------------------------------------------------]]
|
|
function Button:UpdateTextCount()
|
|
|
|
end
|
|
function Button:UpdateTextCountSpell()
|
|
local count = GetSpellCount(self.SpellNameRank);
|
|
if (count ~= 0 or IsConsumableSpell(self.SpellNameRank)) then
|
|
self.WCount:SetText(count);
|
|
return;
|
|
end
|
|
local charges = GetSpellCharges(self.SpellNameRank);
|
|
if (charges ~= nil) then
|
|
self.WCount:SetText(charges);
|
|
return;
|
|
end
|
|
self.WCount:SetText("");
|
|
end
|
|
function Button:UpdateTextCountItem()
|
|
local ItemCount = GetItemCount(self.ItemId, nil, true);
|
|
if (IsConsumableItem(self.ItemId) or ItemCount > 1) then
|
|
self.WCount:SetText(ItemCount);
|
|
else
|
|
self.WCount:SetText("");
|
|
end
|
|
end
|
|
function Button:UpdateTextCountMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateTextCountSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:UpdateTextCountItem();
|
|
else
|
|
self.WCount:SetText("");
|
|
end
|
|
|
|
if (self.WCount:GetText() == nil and self.MacroTextEnabled) then
|
|
self.WName:SetText(self.MacroName);
|
|
else
|
|
self.WName:SetText("");
|
|
end
|
|
end
|
|
function Button:UpdateTextCountBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if ((HasOverrideActionBar() or HasVehicleActionBar()) and (IsConsumableAction(action) or IsStackableAction(action))) then
|
|
self.WCount:SetText(GetActionCount(action));
|
|
else
|
|
self.WCount:SetText("");
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Button:UpdateTooltip()
|
|
|
|
end
|
|
|
|
function Button:UpdateTooltipFunc()
|
|
|
|
end
|
|
|
|
function Button:UpdateTooltipSpell()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
--local Index, BookType = Util.LookupSpellIndex(self.SpellNameRank);
|
|
GameTooltip:SetSpellByID(self.SpellId);
|
|
--if (Index) then
|
|
-- GameTooltip:SetSpellBookItem(Index, BookType);
|
|
--end
|
|
end
|
|
function Button:UpdateTooltipItem()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
local EquippedSlot = Util.LookupItemIdEquippedSlot(self.ItemId);
|
|
if (EquippedSlot ~= nil) then
|
|
GameTooltip:SetInventoryItem("player", EquippedSlot);
|
|
else
|
|
local Bag, BagSlot = Util.LookupItemIdBagSlot(self.ItemId);
|
|
if (Bag ~= nil) then
|
|
GameTooltip:SetBagItem(Bag, BagSlot);
|
|
else
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget); --It appears that the sethyperlink (specifically this one) requires that the anchor be constantly refreshed!?
|
|
GameTooltip:SetHyperlink(self.ItemLink);
|
|
end
|
|
end
|
|
end
|
|
function Button:UpdateTooltipMacro()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
|
|
if (not self.ShowTooltip) then
|
|
--we just show the name in this case
|
|
GameTooltip:SetText(self.MacroName, 1, 1, 1, 1);
|
|
|
|
elseif (self.MacroMode == "spell") then
|
|
local Index, BookType = Util.LookupSpellIndex(self.SpellNameRank);
|
|
if (Index) then
|
|
GameTooltip:SetSpellBookItem(Index, BookType);
|
|
elseif (self.CompanionType == "MOUNT") then
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget); --It appears that the sethyperlink (specifically this one) requires that the anchor be constantly refreshed!?
|
|
GameTooltip:SetHyperlink("spell:"..self.SpellName);
|
|
end
|
|
elseif (self.MacroMode == "item") then
|
|
local EquippedSlot = Util.LookupItemNameEquippedSlot(self.ItemId);
|
|
if (EquippedSlot ~= nil) then
|
|
GameTooltip:SetInventoryItem("player", EquippedSlot);
|
|
else
|
|
local Bag, BagSlot = Util.LookupItemNameBagSlot(self.ItemId);
|
|
if (Bag ~= nil) then
|
|
GameTooltip:SetBagItem(Bag, BagSlot);
|
|
else
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget); --It appears that the sethyperlink (specifically this one) requires that the anchor be constantly refreshed!?
|
|
GameTooltip:SetHyperlink(self.ItemLink);
|
|
end
|
|
end
|
|
elseif (self.MacroMode == "companion") then
|
|
local Id, Name, SpellId = GetCompanionInfo(self.CompanionType, self.CompanionIndex);
|
|
GameTooltip:SetHyperlink("spell:"..SpellId);
|
|
end
|
|
end
|
|
function Button:UpdateTooltipCompanion()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget);
|
|
GameTooltip:SetMountBySpellID(self.MountSpellID);
|
|
end
|
|
function Button:UpdateTooltipEquipmentSet()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
|
|
GameTooltip:SetEquipmentSet(self.EquipmentSetName);
|
|
end
|
|
function Button:UpdateTooltipBonusAction()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
local action = self.Widget:GetAttribute("action");
|
|
if (HasOverrideActionBar() or HasVehicleActionBar()) then
|
|
GameTooltip:SetAction(action);
|
|
else
|
|
GameTooltip:SetText(self.Tooltip, nil, nil, nil, nil, 1);
|
|
end
|
|
end
|
|
function Button:UpdateTooltipFlyout()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
local Index, BookType = Util.LookupSpellIndex("FLYOUT"..self.FlyoutId);
|
|
|
|
if (Index and not GameTooltip:IsShown()) then
|
|
GameTooltip:SetSpellBookItem(Index, BookType);
|
|
end
|
|
end
|
|
function Button:UpdateTooltipCustomAction()
|
|
self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
|
|
|
|
CustomAction.UpdateTooltip(self.CustomActionName);
|
|
end
|
|
|
|
|
|
--[[---------------------------------------------------------------------
|
|
Cursor functions
|
|
-----------------------------------------------------------------------]]
|
|
function Button:GetCursor()
|
|
|
|
end
|
|
function Button:GetCursorSpell()
|
|
return self.Mode, nil, nil, self.SpellId;
|
|
end
|
|
function Button:GetCursorItem()
|
|
return self.Mode, self.ItemId, nil;
|
|
end
|
|
function Button:GetCursorMacro()
|
|
return self.Mode, self.MacroIndex, nil;
|
|
end
|
|
function Button:GetCursorCompanion()
|
|
return self.Mode, self.MountID;
|
|
end
|
|
function Button:GetCursorEquipmentSet()
|
|
return self.Mode, self.EquipmentSetName, nil;
|
|
end
|
|
function Button:GetCursorBonusAction()
|
|
return self.Mode, self.BonusActionId, nil;
|
|
end
|
|
function Button:GetCursorFlyout()
|
|
return self.Mode, self.FlyoutId, nil;
|
|
end
|
|
function Button:GetCursorCustomAction()
|
|
return self.Mode, self.CustomActionName, nil;
|
|
end
|
|
|
|
|
|
--[[------------------------------------------------------------------------
|
|
Flash functions
|
|
--------------------------------------------------------------------------]]
|
|
function Button:UpdateFlash()
|
|
|
|
end
|
|
function Button:UpdateFlashSpell()
|
|
if ((IsAttackSpell(self.SpellNameRank) and IsCurrentSpell(self.SpellNameRank)) or IsAutoRepeatSpell(self.SpellNameRank)) then
|
|
if (not self.FlashOn) then
|
|
self:AddToFlash();
|
|
end
|
|
elseif (self.FlashOn) then
|
|
self:RemoveFromFlash();
|
|
end
|
|
end
|
|
function Button:UpdateFlashMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateFlashSpell();
|
|
elseif (self.FlashOn) then
|
|
self:RemoveFromFlash();
|
|
end
|
|
end
|
|
function Button:UpdateFlashBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if ((HasOverrideActionBar() or HasVehicleActionBar()) and ((IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action))) then
|
|
if (not self.FlashOn) then
|
|
self:AddToFlash();
|
|
end
|
|
elseif (self.FlashOn) then
|
|
self:RemoveFromFlash();
|
|
end
|
|
end
|
|
function Button:AddToFlash()
|
|
Util.AddToFlash(self);
|
|
self.FlashOn = true;
|
|
end
|
|
function Button:RemoveFromFlash()
|
|
Util.RemoveFromFlash(self);
|
|
self.FlashOn = false;
|
|
self.WFlashTexture:Hide();
|
|
end
|
|
|
|
function Button:FlashShow()
|
|
self.WFlashTexture:Show();
|
|
end
|
|
|
|
function Button:FlashHide()
|
|
self.WFlashTexture:Hide();
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--[[------------------------------------------------------------------------
|
|
Range Timer functions
|
|
--------------------------------------------------------------------------]]
|
|
function Button:UpdateRangeTimer()
|
|
|
|
end
|
|
function Button:UpdateRangeTimerSpell()
|
|
if (IsSpellInRange(self.SpellNameRank, self.Target)) then
|
|
if (not self.RangeTimerOn) then
|
|
self:AddToRangeTimer();
|
|
end
|
|
elseif (self.RangeTimerOn) then
|
|
self:RemoveFromRangeTimer();
|
|
end
|
|
end
|
|
function Button:UpdateRangeTimerItem()
|
|
if (IsItemInRange(self.ItemId, self.Target)) then
|
|
if (not self.RangeTimerOn) then
|
|
self:AddToRangeTimer();
|
|
end
|
|
elseif (self.RangeTimerOn) then
|
|
self:RemoveFromRangeTimer();
|
|
end
|
|
end
|
|
function Button:UpdateRangeTimerMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:UpdateRangeTimerSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:UpdateRangeTimerItem();
|
|
elseif (self.RangeTimerOn) then
|
|
self:RemoveFromRangeTimer();
|
|
end
|
|
end
|
|
function Button:UpdateRangeTimerBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if ((HasOverrideActionBar() or HasVehicleActionBar()) and IsActionInRange(action)) then
|
|
if (not self.RangeTimerOn) then
|
|
self:AddToRangeTimer();
|
|
end
|
|
elseif (self.RangeTimerOn) then
|
|
self:RemoveFromRangeTimer();
|
|
end
|
|
end
|
|
|
|
function Button:AddToRangeTimer()
|
|
Util.AddToRangeTimer(self);
|
|
self.RangeTimerOn = true;
|
|
if (self.WHotKey:GetText() == RANGE_INDICATOR) then
|
|
self.WHotKey:Show();
|
|
end
|
|
self:CheckRangeTimer();
|
|
end
|
|
function Button:RemoveFromRangeTimer()
|
|
Util.RemoveFromRangeTimer(self);
|
|
self.RangeTimerOn = false;
|
|
if (self.WHotKey:GetText() == RANGE_INDICATOR) then
|
|
self.WHotKey:Hide();
|
|
else
|
|
self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
|
|
end
|
|
end
|
|
|
|
function Button:CheckRangeTimerSpell()
|
|
if (IsSpellInRange(self.SpellNameRank, self.Target) == 1) then
|
|
self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
|
|
else
|
|
self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
|
|
end
|
|
end
|
|
function Button:CheckRangeTimerItem()
|
|
if (IsItemInRange(self.ItemId, self.Target) == 1) then
|
|
self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
|
|
else
|
|
self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
|
|
end
|
|
end
|
|
function Button:CheckRangeTimerMacro()
|
|
if (self.MacroMode == "spell") then
|
|
self:CheckRangeTimerSpell();
|
|
elseif (self.MacroMode == "item") then
|
|
self:CheckRangeTimerItem();
|
|
else
|
|
self:RemoveFromRangeTimer();
|
|
end
|
|
end
|
|
function Button:CheckRangeTimerBonusAction()
|
|
local action = self.Widget:GetAttribute("action");
|
|
if (IsActionInRange(action) == 1) then
|
|
self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
|
|
else
|
|
self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[--------------------------------------------------------------------------
|
|
|
|
----------------------------------------------------------------------------]]
|
|
|
|
--[[
|
|
Make sure the Macro is up to date
|
|
--]]
|
|
function Button:RefreshMacro()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
if (self.Mode == "macro") then
|
|
local TrimBody = strtrim(self.MacroBody or '');
|
|
local AccMacros, CharMacros = GetNumMacros();
|
|
local BodyIndex = 0;
|
|
|
|
--Shallow Checking - Full Affinity
|
|
local Name, Icon, Body = GetMacroInfo(self.MacroIndex);
|
|
if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
|
|
self:SetCommandMacro(self.MacroIndex);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
|
|
if (Util.IncBetween(self.MacroIndex - 1, 1, AccMacros) or Util.IncBetween(self.MacroIndex - 1, MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros)) then
|
|
Name, Icon, Body = GetMacroInfo(self.MacroIndex - 1);
|
|
if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
|
|
self:SetCommandMacro(self.MacroIndex - 1);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
end
|
|
|
|
if (Util.IncBetween(self.MacroIndex + 1, 1, AccMacros) or Util.IncBetween(self.MacroIndex + 1, MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros)) then
|
|
Name, Icon, Body = GetMacroInfo(self.MacroIndex + 1);
|
|
if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
|
|
self:SetCommandMacro(self.MacroIndex + 1);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
end
|
|
|
|
--Scan Checking - Full Affinity
|
|
for i = 1, AccMacros do
|
|
Name, Icon, Body = GetMacroInfo(i);
|
|
Body = strtrim(Body or '');
|
|
if (TrimBody == Body and self.MacroName == Name) then
|
|
self:SetCommandMacro(i);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
|
|
if (TrimBody == Body and Body ~= nil and Body ~= "") then
|
|
BodyIndex = i;
|
|
end
|
|
end
|
|
for i = MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros do
|
|
Name, Icon, Body = GetMacroInfo(i);
|
|
Body = strtrim(Body or '');
|
|
if (TrimBody == Body and self.MacroName == Name) then
|
|
self:SetCommandMacro(i);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
|
|
if (TrimBody == Body and Body ~= nil and Body ~= "") then
|
|
BodyIndex = i;
|
|
end
|
|
end
|
|
|
|
if (not Util.MacroDeleted) then
|
|
--Full Scan - Body Affinity
|
|
if (BodyIndex ~= 0) then
|
|
self:SetCommandMacro(BodyIndex);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
|
|
--Low Scan - Name Affinity (the macro should not have moved if the body changed)
|
|
Name = GetMacroInfo(self.MacroIndex);
|
|
if (self.MacroName == Name) then
|
|
self:SetCommandMacro(self.MacroIndex);
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
end
|
|
|
|
--Not Found - Clear Macro?
|
|
if (ButtonForgeGlobalSettings["RemoveMissingMacros"] and Util.MacroCheckDelayComplete) then
|
|
self:ClearCommand();
|
|
self:FullRefresh();
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--[[
|
|
|
|
--]]
|
|
function Button:PromoteSpell()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
--[[
|
|
if (self.Mode == "spell") then
|
|
local Name, Rank = GetSpellInfo(self.SpellName); --This will actually retrieve for the highest rank of the spell
|
|
if (Name) then
|
|
if (Util.LookupNewSpellIndex(Name.."("..Rank..")")) then
|
|
if (strfind(Rank, Util.GetLocaleString("SpellRank"), 1, true) and strfind(self.SpellNameRank, Util.GetLocaleString("SpellRank"), 1, true)) then
|
|
if (Name.."("..Rank..")" ~= self.SpellNameRank) then
|
|
self:SetCommandSpell(Util.LookupNewSpellIndex(Name.."("..Rank..")")); --It is important to note that to get here we have a valid spell
|
|
self:FullRefresh();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end]]
|
|
end
|
|
function Button:RefreshSpell()
|
|
--in the case of a spell refresh we just need to make sure the texture reflects its current status
|
|
if (self.Mode == "spell") then
|
|
self.Texture = GetSpellTexture(self.SpellId) or "Interface/Icons/INV_Misc_QuestionMark";
|
|
self:DisplayActive();
|
|
end
|
|
end
|
|
|
|
function Button:RefreshCompanion()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
if (self.Mode == "companion") then
|
|
local Type, Index = Util.LookupCompanion(self.CompanionName);
|
|
if (Type == nil) then
|
|
self:ClearCommand();
|
|
self:FullRefresh();
|
|
return;
|
|
end
|
|
if (Index ~= self.CompanionIndex) then
|
|
self:SetCommandCompanion(Index, Type);
|
|
self:FullRefresh();
|
|
end
|
|
end
|
|
end
|
|
|
|
function Button:RefreshEquipmentSet()
|
|
if (InCombatLockdown()) then
|
|
return;
|
|
end
|
|
if (self.Mode == "equipmentset") then
|
|
local Index = Util.LookupEquipmentSetIndex(self.EquipmentSetId);
|
|
|
|
if (Index == nil) then
|
|
-- This equip set is gone so clear it from the button
|
|
return self:ClearCommand();
|
|
end
|
|
local TextureName = select(2, C_EquipmentSet.GetEquipmentSetInfo(Index));
|
|
if (TextureName) then
|
|
self.Texture = TextureName;
|
|
self:DisplayActive();
|
|
else
|
|
self:ClearCommand();
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--Copied and adapted from Blizz's coding (too bad they Assume there is an action associated with the button!!!)
|
|
--This is currently coded to always be up... this will probably need to be adaptable down the track
|
|
function Button:UpdateFlyout()
|
|
local Widget = self.Widget;
|
|
if (self.Mode == "flyout") then
|
|
-- Update border and determine arrow position
|
|
local arrowDistance;
|
|
if (SpellFlyout:GetParent() == Widget) then
|
|
-- SpellFlyout.isActionBar = false;
|
|
end
|
|
if ((SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == Widget) or GetMouseFocus() == Widget) then
|
|
Widget.FlyoutBorder:Show();
|
|
Widget.FlyoutBorderShadow:Show();
|
|
arrowDistance = 5;
|
|
else
|
|
Widget.FlyoutBorder:Hide();
|
|
Widget.FlyoutBorderShadow:Hide();
|
|
arrowDistance = 2;
|
|
end
|
|
|
|
-- Update arrow
|
|
Widget.FlyoutArrow:Show();
|
|
Widget.FlyoutArrow:ClearAllPoints();
|
|
--if (self:GetParent() == MultiBarRight or self:GetParent() == MultiBarLeft) then
|
|
--self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0);
|
|
--SetClampedTextureRotation(self.FlyoutArrow, 270);
|
|
--else
|
|
Widget.FlyoutArrow:SetPoint("TOP", Widget, "TOP", 0, arrowDistance);
|
|
SetClampedTextureRotation(Widget.FlyoutArrow, 0);
|
|
--end
|
|
else
|
|
Widget.FlyoutBorder:Hide();
|
|
Widget.FlyoutBorderShadow:Hide();
|
|
Widget.FlyoutArrow:Hide();
|
|
end
|
|
end
|
|
|
|
|
|
function Button:UpdateGlow()
|
|
if ((self.Mode == "spell" or (self.MacroMode == "spell" and self.Mode == "macro")) and Util.GlowSpells[self.SpellName]) then
|
|
ActionButton_ShowOverlayGlow(self.Widget);
|
|
else
|
|
ActionButton_HideOverlayGlow(self.Widget);
|
|
end
|
|
end
|
|
|
|
--hooksecurefunc("IsSpellOverlayed", print);
|
|
--[[
|
|
-- Empty functions
|
|
-- ]]
|
|
function Button:Empty()
|
|
|
|
end
|