· 8 years ago · Aug 28, 2018, 05:36 PM
1--[[
2 Author: Alternator (Massiner of Nathrezim)
3 Copyright 2010
4
5Notes:
6 - Texture retrieval on Spells will not return different state textures for a spell (e.g. Wisp, when a Hunter Aspect is selected)
7 - Texture retrieval on Macros will however return the different state textures - I do not believe this can be leveraged to fix the above
8 - Index refers to the players index to a macro, spell, Companion etc...
9 - Id refers to the universal Id where one exists
10 - 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
11 - Because Frames can be dynamically created, abandoned Frames need to be managed... This could lead to recycling them, but consider that later on
12 - OnClick of the SecureButtonTemplate has some subtle but important behaviour as follows
13 - Clears the Cursor
14 - 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)
15 - Querying Companion information is dicey when the player first enters the gameworld (during a new session, or perhaps empty cache??)
16 - 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
17 - A work around is to continually try to create the companion cache until it successfully runs to completetion
18 - Macros with Companions as the action, will return the action as though it were a spell :S
19 - 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
20 - This is done by creating a reverse cache of the companions for easy lookup
21 - MouseOver macro conditional changed has the following considerations
22 - 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)
23 - The Event UPDATE_MOUSEOVER_UNIT would have done the trick, except it does not fire when the player mouses off a target to nothing
24 - 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)
25
26 - Button is inherited for each Button created
27 - each created Button has a table entry called Widget, this is the actual button widget shown on screen
28 - 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
29 and the first parameter will be Widget)... This is due to the setting of some Button functions as Scripts for events on the Widget.
30]]
31
32--Create a mapping to the needed elements (allocate the item if necessary)
33
34local Util = BFUtil;
35local Const = BFConst;
36local Button = BFButton;
37local UILib = BFUILib;
38local CustomAction = BFCustomAction;
39local KeyBinder = BFKeyBinder;
40Button.__index = Button;
41
42local IsUsableSpell = IsUsableSpell;
43local SecureClickWrapperFrame = CreateFrame("FRAME", nil, nil, "SecureHandlerBaseTemplate");
44
45
46
47
48
49
50--[[--------------------------------------------------------------
51 Create a New Button
52----------------------------------------------------------------]]
53function Button.New(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText)
54 if (InCombatLockdown()) then
55 return;
56 end
57 local NewButton = {};
58 setmetatable(NewButton, Button);
59
60 NewButton.Widget = Button.CreateButtonWidget(Parent);
61 local Name = NewButton.Widget:GetName();
62 NewButton.WIcon = _G[Name.."Icon"];
63 NewButton.WNormalTexture = _G[Name.."NormalTexture"];
64 NewButton.WCooldown = _G[Name.."Cooldown"];
65 NewButton.WCount = _G[Name.."Count"];
66 NewButton.WBorder = _G[Name.."Border"];
67 NewButton.WFlashTexture = _G[Name.."Flash"];
68 NewButton.WHotKey = _G[Name.."HotKey"];
69 NewButton.WName = _G[Name.."Name"];
70 NewButton.Widget.ParentButton = NewButton;
71
72 NewButton.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0, 0.5);
73 NewButton.WCooldown:SetEdgeTexture("Interface\\Cooldown\\edge");
74 NewButton.WCooldown:SetSwipeColor(0, 0, 0);
75 NewButton.WCooldown:SetHideCountdownNumbers(false);
76 NewButton.WCooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL;
77
78 NewButton.UpdateTooltip = Button.Empty;
79 NewButton:Configure(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText);
80 NewButton:SetupActionButtonClick();
81
82 return NewButton;
83end
84
85function Button.CreateButtonWidget(Parent)
86 local Name = Const.ButtonNaming..Const.ButtonSeq;
87 local Widget = CreateFrame("CheckButton", Name, Parent, "SecureActionButtonTemplate, ActionButtonTemplate");
88 Const.ButtonSeq = Const.ButtonSeq + 1;
89 Widget:SetAttribute("checkselfcast", true);
90 Widget:SetAttribute("checkfocuscast", true);
91 Widget:RegisterForDrag("LeftButton", "RightButton");
92 --Widget:RegisterForClicks("AnyUp");
93 Widget:SetScript("OnReceiveDrag", Button.OnReceiveDrag);
94 Widget:SetScript("OnDragStart", Button.OnDragStart);
95
96 if (Util.ForceOffCastOnKeyDown) then
97 Widget:SetScript("PostClick", Button.PostClickBasic);
98 Widget:SetScript("PreClick", Button.PreClickBasic);
99 else
100 Widget:SetScript("PostClick", Button.PostClick);
101 Widget:SetScript("PreClick", Button.PreClick);
102 end
103
104 --The ActionButtonTemplate does not include the following (which will be created here)
105 --FloatingBG (e.g. MultiBarButtonTemplate)
106 local FloatingBG = Widget:CreateTexture(Name.."FloatingBG", "BACKGROUND", nil, -1);
107 FloatingBG:SetTexture("Interface\\Buttons\\UI-Quickslot");
108 FloatingBG:SetAlpha(0.4);
109 FloatingBG:SetPoint("TOPLEFT", -15, 15);
110 FloatingBG:SetPoint("BOTTOMRIGHT", 15, -15);
111
112 --AutoCastable (e.g. PetActionButtonTemplate)
113 local AutoCastable = Widget:CreateTexture(Name.."AutoCastable", "OVERLAY");
114 AutoCastable:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay");
115 AutoCastable:SetSize(70, 70);
116 AutoCastable:SetPoint("CENTER", 0, 0);
117 AutoCastable:Hide();
118
119 --AutoCast
120 local Shine = CreateFrame("FRAME", Name.."Shine", Widget, "AutoCastShineTemplate");
121 Shine:SetSize(34, 34);
122 Shine:SetPoint("CENTER", 0, 0);
123
124 --_G[Widget:GetName().."HotKey"]:ClearAllPoints();
125 --_G[Widget:GetName().."HotKey"]:SetPoint("TOPLEFT", Widget, "TOPLEFT", 1, -2);
126 Widget.action = 10000;
127 if (Util.LBFMasterGroup) then
128 Util.LBFMasterGroup:AddButton(Widget);
129 end
130 return Widget;
131end
132
133function Button:SetupActionButtonClick()
134 local Widget = self.Widget;
135
136 -- This particular setting will only gets set at login (if the player changes it they must log out and back in)
137 if (Util.ForceOffCastOnKeyDown) then
138 Widget:RegisterForClicks("AnyUp");
139 return;
140 end
141
142 SecureClickWrapperFrame:UnwrapScript(Widget, "OnClick");
143
144 if (GetCVarBool("ActionButtonUseKeyDown")) then
145 Widget:RegisterForClicks("AnyUp", "AnyDown");
146 local SecurePreClickSnippet =
147 [[if (down and button == "KeyBind") then
148 return "LeftButton";
149 end
150 if ((not down) and button ~= "KeyBind") then
151 return;
152 end
153 return false;]];
154 SecureClickWrapperFrame:WrapScript(Widget, "OnClick", SecurePreClickSnippet);
155
156 else
157 Widget:RegisterForClicks("AnyUp");
158 local SecurePreClickSnippet =
159 [[if (button == "KeyBind") then
160 return "LeftButton";
161 end]];
162 SecureClickWrapperFrame:WrapScript(Widget, "OnClick", SecurePreClickSnippet);
163 end
164
165end
166
167--[[ Configure the button for use --]]
168function Button:Configure(Parent, ButtonSave, ButtonLocked, TooltipEnabled, MacroText, KeyBindText)
169 self.Widget:SetParent(Parent);
170 self.ButtonSave = ButtonSave;
171
172 local Mode = ButtonSave["Mode"];
173 if (Mode == "spell") then
174 self:SetCommandExplicitSpell(ButtonSave["SpellId"], ButtonSave["SpellNameRank"], ButtonSave["SpellName"], ButtonSave["SpellBook"]); --the util functions will get both the index and the book
175
176 elseif (Mode == "item") then
177 self:SetCommandExplicitItem(ButtonSave["ItemId"], ButtonSave["ItemName"], ButtonSave["ItemLink"]);
178
179 elseif (Mode == "macro") then
180 self:SetCommandExplicitMacro(ButtonSave["MacroIndex"], ButtonSave["MacroName"], ButtonSave["MacroBody"]);
181
182 --elseif (Mode == "companion") then
183 -- self:SetCommandExplicitCompanion(ButtonSave["CompanionId"], ButtonSave["CompanionType"], ButtonSave["CompanionIndex"], ButtonSave["CompanionName"], ButtonSave["CompanionSpellName"]);
184 elseif (Mode == "mount") then
185 self:SetCommandExplicitCompanion(ButtonSave["MountID"]);
186
187 elseif (Mode == "equipmentset") then
188 self:SetCommandExplicitEquipmentSet(ButtonSave["EquipmentSetId"], ButtonSave["EquipmentSetName"]);
189
190 elseif (Mode == "bonusaction") then
191 self:SetCommandExplicitBonusAction(ButtonSave["BonusActionId"]);
192
193 elseif (Mode == "flyout") then
194 self:SetCommandExplicitFlyout(ButtonSave["FlyoutId"]);
195
196 elseif (Mode == "customaction") then
197 self:SetCommandExplicitCustomAction(ButtonSave["CustomActionName"]);
198
199 elseif (Mode == "battlepet") then
200 self:SetCommandExplicitBattlePet(ButtonSave["BattlePetId"]);
201
202 else
203 self:ClearCommand();
204 end
205
206 if (ButtonForgeSave["RightClickSelfCast"]) then
207 self.Widget:SetAttribute("unit2", "player");
208 else
209 self.Widget:SetAttribute("unit2", nil);
210 end
211 self:SetButtonLock(ButtonLocked);
212 self:SetTooltipEnabled(TooltipEnabled);
213 self:SetMacroText(MacroText);
214 self:SetKeyBindText(KeyBindText);
215 self:SetKeyBind(ButtonSave["KeyBinding"]);
216 self:Show();
217 self:FullRefresh();
218end
219
220
221
222
223
224--[[--------------------------------------------------------------
225 Deallocate the Button
226----------------------------------------------------------------]]
227function Button:Deallocate()
228 self:ClearCommand();
229 self:SetKeyBind(nil);
230 self:SetOnEnter();
231 self:Hide();
232end
233
234
235
236
237--[[--------------------------------------------------------------
238 Detach the Button
239----------------------------------------------------------------]]
240function Button:Detach()
241 -- Same as Deallocate except this will first detach from its save store to leave that intact
242 self.ButtonSave = {};
243 self:Deallocate();
244end
245
246
247
248
249
250--[[--------------------------------------------------------------
251 Set functions
252----------------------------------------------------------------]]
253function Button:SetButtonLock(Value)
254 self.Locked = Value;
255end
256
257function Button:SetTooltipEnabled(Value)
258 self.TooltipEnabled = Value;
259 self:SetOnEnter();
260end
261
262function Button:SetMacroText(Value)
263 self.MacroTextEnabled = Value;
264 if (self.Mode == "macro") then
265 if (Value) then
266 self.WName:SetText(self.MacroName);
267 else
268 self.WName:SetText("");
269 end
270 end
271end
272
273function Button:SetKeyBindText(Value)
274 self.KeyBindTextEnabled = Value;
275 self:RefreshKeyBindDisplay();
276end
277
278function Button:SetKeyBind(Key)
279 if (InCombatLockdown()) then
280 return false;
281 end
282
283 --Each key owns it's own key binding
284 ClearOverrideBindings(self.Widget);
285 if (Key ~= "" and Key ~= nil) then
286 self.ButtonSave["KeyBinding"] = Key;
287 if (Util.ForceOffCastOnKeyDown) then
288 SetOverrideBindingClick(self.Widget, false, Key, self.Widget:GetName());
289 else
290 SetOverrideBindingClick(self.Widget, false, Key, self.Widget:GetName(), "KeyBind");
291 end
292 self.Widget:SetAttribute("KeyBindValue", Key);
293 else
294 --clear the binding
295 self.ButtonSave["KeyBinding"] = nil;
296 self.Widget:SetAttribute("KeyBindValue", nil);
297 end
298
299 self:RefreshKeyBindDisplay();
300
301 return true;
302end
303
304function Button:RefreshKeyBindDisplay()
305 local Key = self.ButtonSave["KeyBinding"];
306 if (Key ~= nil and self.KeyBindTextEnabled) then
307 self.WHotKey:SetText(GetBindingText(Key, "KEY_", 1));
308 --if not self.WHotKey.__LBF_SetPoint then
309 --self.WHotKey:ClearAllPoints();
310 --self.WHotKey:SetPoint("TOPLEFT", self.Widget, "TOPLEFT", -2, -2);
311 --end
312 self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
313 self.WHotKey:Show();
314
315 else
316 self.WHotKey:SetText(RANGE_INDICATOR);
317 --if not self.WHotKey.__LBF_SetPoint then
318 --self.WHotKey:ClearAllPoints();
319 --self.WHotKey:SetPoint("TOPLEFT", self.Widget, "TOPLEFT", 1, -2);
320 --end
321 self.WHotKey:Hide();
322
323 end
324end
325
326function Button:SetOnEnter(Value)
327 if (Value == "KeyBind") then
328 self.Widget:SetScript("OnEnter", Button.OnEnterKeyBind);
329 self.Widget:SetScript("OnLeave", Button.OnLeaveFlyout);
330 elseif (self.TooltipEnabled) then
331 self.Widget:SetScript("OnEnter", Button.OnEnterTooltip);
332 self.Widget:SetScript("OnLeave", Button.OnLeaveTooltip);
333 else
334 self.Widget:SetScript("OnEnter", Button.OnEnterFlyout);
335 self.Widget:SetScript("OnLeave", Button.OnLeaveFlyout);
336 end
337end
338
339
340
341
342
343--[[-------------------------------------------------------------------------
344 OnEnter / OnLeave handlers
345---------------------------------------------------------------------------]]
346function Button.OnLeaveTooltip(Widget) --Includes flyout
347 GameTooltip:Hide();
348 Widget.ParentButton.UpdateTooltip = Button.Empty;
349 Widget.ParentButton:UpdateFlyout();
350end
351
352function Button.OnEnterTooltip(Widget) --Includes flyout!
353 local self = Widget.ParentButton;
354 GameTooltip_SetDefaultAnchor(GameTooltip, Widget);
355 self.UpdateTooltip = self.UpdateTooltipFunc;
356 self.Widget.UpdateTooltip = self.UpdateTooltip;
357 self:UpdateTooltip();
358 self:UpdateFlyout();
359end
360
361function Button.OnEnterKeyBind(Widget)
362 UILib.SetMask(Widget.ParentButton, KeyBinder.ShowBindingDialog, KeyBinder.CancelButtonSelectorMode, Widget, "CAST_CURSOR","Interface/TARGETINGFRAME/UI-RaidTargetingIcon_1", {0, 1, 0, 1});
363 GameTooltip_SetDefaultAnchor(GameTooltip, Widget);
364end
365
366--Noting these are the same function...
367function Button.OnEnterFlyout(Widget)
368 local self = Widget.ParentButton;
369 self:UpdateFlyout();
370end
371
372function Button.OnLeaveFlyout(Widget)
373 local self = Widget.ParentButton;
374 self:UpdateFlyout();
375end
376
377
378
379--[[----------------------------------------------------------------------------------
380 Button Display altering functions (used when reducing cols/rows or hiding
381 such as when the grid is not always on, or the button is deallocated
382------------------------------------------------------------------------------------]]
383function Button:Fade(Value)
384 if (Value) then
385 self.Widget:SetAlpha(0.5);
386 else
387 self.Widget:SetAlpha(1);
388 end
389end
390
391function Button:Hide()
392 if (InCombatLockdown()) then
393 return;
394 end
395 self.Widget:Hide();
396end
397
398function Button:Show()
399 if (InCombatLockdown()) then
400 return;
401 end
402 self.Widget:Show();
403end
404
405
406
407
408
409--[[------------------------------------------------------------------------------------------
410 Functions that manage setting the action for the button, including the script handlers
411 for the player drag/dropping actions
412--------------------------------------------------------------------------------------------]]
413
414--[[ Script Handlers --]]
415function Button.PreClickBasic(Widget, Button, Down)
416 if (InCombatLockdown()) then
417 return;
418 end
419
420 local Command, Data, Subvalue, Subsubvalue = GetCursorInfo();
421 if (not Command) then
422 Command, Data, Subvalue, Subsubvalue = UILib.GetDragInfo();
423 end
424 Util.StoreCursor(Command, Data, Subvalue, Subsubvalue); --Always store this, so that if it is nil PostClick wont try to use it
425 if (Command) then
426 Widget.BackupType = Widget:GetAttribute("type");
427 Widget:SetAttribute("type", ""); --Temp unset the type to prevent any action happening
428 end
429end
430function Button.PreClick(Widget, Button, Down)
431 if (InCombatLockdown() or Button == "KeyBind" or Down) then
432 return;
433 end
434
435 local Command, Data, Subvalue, Subsubvalue = GetCursorInfo();
436 if (not Command) then
437 Command, Data, Subvalue, Subsubvalue = UILib.GetDragInfo();
438 end
439 Util.StoreCursor(Command, Data, Subvalue, Subsubvalue); --Always store this, so that if it is nil PostClick wont try to use it
440 if (Command) then
441 Widget.BackupType = Widget:GetAttribute("type");
442 Widget:SetAttribute("type", ""); --Temp unset the type to prevent any action happening
443 end
444end
445
446function Button.PostClickBasic(Widget, Button, Down)
447 local self = Widget.ParentButton;
448 self:UpdateChecked();
449 if (InCombatLockdown()) then
450 return;
451 end
452
453 if (self.Mode == "flyout") then
454 BFEventFrames["Full"].RefreshButtons = true;
455 BFEventFrames["Full"].RefFlyouts = true;
456 end
457 if (not InCombatLockdown()) then
458 local Command, Data, Subvalue, Subsubvalue = Util.GetStoredCursor();
459 if (Command) then
460 Util.StoreCursor(self:GetCursor()); --Store the info from the button for later setting the cursor
461 if (self:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)) then --Set the button to the cursor
462 Util.SetCursor(Util.GetStoredCursor()); --On success set the cursor to the stored button info
463 else
464 Util.SetCursor(Command, Data, Subvalue, Subsubvalue); --On fail set the cursor to what ever it was
465 self.Widget:SetAttribute("type", Widget.BackupType); --and restore the button mode
466 end
467 end
468 end
469 --self:UpdateChecked();
470end
471function Button.PostClick(Widget, Button, Down)
472 local self = Widget.ParentButton;
473 self:UpdateChecked();
474 if (InCombatLockdown() or Button == "KeyBind" or Down) then
475 return;
476 end
477
478 if (self.Mode == "flyout") then
479 BFEventFrames["Full"].RefreshButtons = true;
480 BFEventFrames["Full"].RefFlyouts = true;
481 end
482 if (not InCombatLockdown()) then
483 local Command, Data, Subvalue, Subsubvalue = Util.GetStoredCursor();
484 if (Command) then
485 Util.StoreCursor(self:GetCursor()); --Store the info from the button for later setting the cursor
486 if (self:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)) then --Set the button to the cursor
487 Util.SetCursor(Util.GetStoredCursor()); --On success set the cursor to the stored button info
488 else
489 Util.SetCursor(Command, Data, Subvalue, Subsubvalue); --On fail set the cursor to what ever it was
490 self.Widget:SetAttribute("type", Widget.BackupType); --and restore the button mode
491 end
492 end
493 end
494 --self:UpdateChecked();
495end
496
497function Button.OnReceiveDrag(Widget)
498 local self = Widget.ParentButton;
499 if (not InCombatLockdown()) then
500 if (GetCursorInfo()) then
501 Util.StoreCursor(self:GetCursor());
502 if (self:SetCommandFromTriplet(GetCursorInfo())) then
503 Util.SetCursor(Util.GetStoredCursor());
504 end
505 elseif (UILib.GetDragInfo()) then
506 Util.StoreCursor(self:GetCursor());
507 if (self:SetCommandFromTriplet(UILib.GetDragInfo())) then
508 Util.SetCursor(Util.GetStoredCursor());
509 end
510 end
511 end
512end
513
514function Button.OnDragStart(Widget)
515 local self = Widget.ParentButton;
516 if (not (InCombatLockdown() or (self.Locked and not IsShiftKeyDown()))) then
517 Util.StoreCursor(self:GetCursor());
518 if (GetCursorInfo()) then
519 if (self:SetCommandFromTriplet(GetCursorInfo())) then
520 Util.SetCursor(Util.GetStoredCursor());
521 end
522 elseif (self:SetCommandFromTriplet(UILib.GetDragInfo())) then
523 Util.SetCursor(Util.GetStoredCursor());
524 end
525 end
526end
527
528--[[ Set up the buttons action based on the triplet of data provided from the cursor --]]
529function Button:SetCommandFromTriplet(Command, Data, Subvalue, Subsubvalue)
530 if (InCombatLockdown()) then
531 return false;
532 end
533
534 local OldMode = self.Mode;
535
536 if (Command == "spell") then
537 self:SetCommandSpell(Subsubvalue); --Data = Index, Subvalue = Book (spell/pet)
538 elseif (Command == "item") then
539 self:SetCommandItem(Data, Subvalue); --Data = Id, Subvalue = Link
540 elseif (Command == "macro") then
541 self:SetCommandMacro(Data); --Data = Index
542 elseif (Command == "mount") then
543 self:SetCommandCompanion(Data); -- Data = MountID, Subvalue = ???
544 elseif (Command == "equipmentset") then
545 self:SetCommandEquipmentSet(Data); --Data = Name
546 elseif (Command == "bonusaction") then
547 self:SetCommandBonusAction(Data); --Data = Id (1 to 12)
548 elseif (Command == "flyout") then
549 self:SetCommandFlyout(Data); --Data = Id
550 elseif (Command == "customaction") then
551 self:SetCommandCustomAction(Data); --Data = Action
552 elseif (Command == "battlepet") then
553 self:SetCommandBattlePet(Data);
554 elseif (Command == nil or Command == "") then
555 self:ClearCommand();
556 else
557 return false;
558 end
559
560 self:FullRefresh();
561 return true;
562end
563
564--[[ Function to clear the command on the button --]]
565function Button:ClearCommand()
566 self:SetEnvClear();
567 self:SetAttributes(nil, nil);
568 self:SaveClear();
569 self:ResetAppearance();
570end
571
572--[[ Set the individual types of actions including obtained any extra data they may need --]]
573function Button:SetCommandSpell(Id)
574 local Name, Rank = GetSpellInfo(Id);
575 local NameRank = Util.GetFullSpellName(Name, Rank);
576 self:SetCommandExplicitSpell(Id, NameRank, Name, Book);
577end
578function Button:SetCommandItem(Id, Link)
579 local Name;
580 Name, Link = GetItemInfo(Id); --Note this will get a clean link, as the one passed in may have enchants etc encoded in it
581 self:SetCommandExplicitItem(Id, Name, Link);
582end
583function Button:SetCommandMacro(Index)
584 local Name, Texture, Body = GetMacroInfo(Index);
585 self:SetCommandExplicitMacro(Index, Name, Body or '');
586end
587function Button:SetCommandCompanion(MountID)
588 --local SpellName = GetSpellInfo(SpellId);
589 self:SetCommandExplicitCompanion(MountID);
590end
591function Button:SetCommandEquipmentSet(SetName)
592 local SetCount = C_EquipmentSet.GetNumEquipmentSets();
593 for i=0,SetCount-1 do
594 name, texture, setIndex, isEquipped, totalItems, equippedItems, inventoryItems, missingItems, ignoredSlots = C_EquipmentSet.GetEquipmentSetInfo(i);
595 if (name == SetName ) then
596 self:SetCommandExplicitEquipmentSet(setIndex, name);
597 break;
598 end
599 end;
600end
601function Button:SetCommandBonusAction(Id)
602 self:SetCommandExplicitBonusAction(Id);
603end
604function Button:SetCommandFlyout(Id)
605 self:SetCommandExplicitFlyout(Id);
606end
607function Button:SetCommandCustomAction(Name)
608 self:SetCommandExplicitCustomAction(Name);
609end
610function Button:SetCommandBattlePet(Id)
611 self:SetCommandExplicitBattlePet(Id);
612end
613
614--[[ Set the individual types of actions (all data needed is supplied to the functions as args) --]]
615function Button:SetCommandExplicitSpell(Id, NameRank, Name, Book)
616 local IsTalent = Util.IsSpellIdTalent(Id);
617 self:SetEnvSpell(Id, NameRank, Name, Book, IsTalent);
618 if (IsTalent) then
619 -- Talents only can be triggered off the name, The API is really random as to when it works better with the name vs ID
620 self:SetAttributes("spell", NameRank);
621 else
622 -- 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
623 -- And yes, as it stands if Blizz do same name variant Talents, then well bugger...
624 self:SetAttributes("spell", Id);
625 end
626 self:SaveSpell(Id, NameRank, Name, Book);
627end
628function Button:SetCommandExplicitItem(Id, Name, Link)
629 self:SetEnvItem(Id, Name, Link);
630 self:SetAttributes("item", Name);
631 self:SaveItem(Id, Name, Link);
632end
633function Button:SetCommandExplicitMacro(Index, Name, Body)
634 self:SetEnvMacro(Index, Name, Body);
635 self:SetAttributes("macro", Index);
636 self:SaveMacro(Index, Name, Body);
637end
638function Button:SetCommandExplicitCompanion(MountID)
639 self:SetEnvCompanion(MountID);
640 --self:SetAttributes("companion", SpellName); mopved to set env
641 --self:SaveCompanion(Index, SpellID); moved to end of set env
642end
643function Button:SetCommandExplicitEquipmentSet(Id, Name)
644 self:SetEnvEquipmentSet(Id, Name);
645 self:SetAttributes("equipmentset", Name);
646 self:SaveEquipmentSet(Id, Name);
647end
648function Button:SetCommandExplicitBonusAction(Id)
649 self:SetAttributes("bonusaction", Id);
650 self:SetEnvBonusAction(Id);
651
652 self:SaveBonusAction(Id);
653end
654function Button:SetCommandExplicitFlyout(Id)
655 self:SetEnvFlyout(Id);
656 self:SetAttributes("flyout", Id);
657 self:SaveFlyout(Id);
658end
659function Button:SetCommandExplicitCustomAction(Name)
660 self:SetEnvCustomAction(Name);
661 self:SetAttributes("customaction", Name);
662 self:SaveCustomAction(Name);
663end
664function Button:SetCommandExplicitBattlePet(Id)
665 self:SetEnvBattlePet(Id);
666 self:SetAttributes("battlepet", Id);
667 self:SaveBattlePet(Id);
668end
669
670--[[ 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) --]]
671function Button:SetEnvSpell(Id, NameRank, Name, Book, IsTalent)
672 self.UpdateTexture = Button.Empty;
673 self.UpdateChecked = Button.UpdateCheckedSpell;
674 self.UpdateEquipped = Button.Empty;
675 self.UpdateCooldown = Button.UpdateCooldownSpell;
676 self.UpdateUsable = Button.UpdateUsableSpell;
677 self.UpdateTextCount = Button.UpdateTextCountSpell;
678 self.UpdateTooltipFunc = Button.UpdateTooltipSpell;
679 self.UpdateRangeTimer = Button.UpdateRangeTimerSpell;
680 self.CheckRangeTimer = Button.CheckRangeTimerSpell;
681 self.UpdateFlash = Button.UpdateFlashSpell;
682 self.UpdateFlyout = Button.Empty;
683
684 self.GetCursor = Button.GetCursorSpell;
685
686 self.FullRefresh = Button.FullRefresh;
687
688 local Matched = false;
689 if (Const.WispSpellIds[Id]) then
690 -- This spell may update its icon to the wisp state...
691 self.UpdateTexture = Button.UpdateTextureWispSpell;
692 end
693
694 self.Mode = "spell";
695 self.SpellId = Id;
696 self.SpellNameRank = NameRank;
697 self.SpellName = Name;
698 self.SpellBook = Book;
699 self.SpellIsTalent = IsTalent;
700 self.Texture = GetSpellTexture(Id) or "Interface/Icons/INV_Misc_QuestionMark";
701 self.Target = "target";
702
703 self:ResetAppearance();
704 self:DisplayActive();
705 Util.AddSpell(self);
706end
707function Button:SetEnvItem(Id, Name, Link)
708 self.UpdateTexture = Button.Empty;
709 self.UpdateChecked = Button.UpdateCheckedItem;
710 self.UpdateEquipped = Button.UpdateEquippedItem;
711 self.UpdateCooldown = Button.UpdateCooldownItem;
712 self.UpdateUsable = Button.UpdateUsableItem;
713 self.UpdateTextCount = Button.UpdateTextCountItem;
714 self.UpdateTooltipFunc = Button.UpdateTooltipItem;
715 self.UpdateRangeTimer = Button.UpdateRangeTimerItem;
716 self.CheckRangeTimer = Button.CheckRangeTimerItem;
717 self.UpdateFlash = Button.Empty;
718 self.UpdateFlyout = Button.Empty;
719
720 self.GetCursor = Button.GetCursorItem;
721
722
723 self.FullRefresh = Button.FullRefresh;
724
725 self.Mode = "item";
726 self.ItemId = Id;
727 self.ItemName = Name;
728 self.ItemLink = Link;
729 self.Texture = GetItemIcon(Id) or "Interface/Icons/INV_Misc_QuestionMark"; --safe no matter what
730 self.Target = "target";
731
732 self:ResetAppearance();
733 self:DisplayActive();
734 Util.AddItem(self);
735end
736function Button:SetEnvMacro(Index, Name, Body)
737 self.UpdateTexture = Button.UpdateTextureMacro;
738 self.UpdateChecked = Button.UpdateCheckedMacro;
739 self.UpdateEquipped = Button.UpdateEquippedMacro;
740 self.UpdateCooldown = Button.UpdateCooldownMacro;
741 self.UpdateUsable = Button.UpdateUsableMacro;
742 self.UpdateTextCount = Button.UpdateTextCountMacro;
743 self.UpdateTooltipFunc = Button.UpdateTooltipMacro;
744 self.UpdateRangeTimer = Button.UpdateRangeTimerMacro;
745 self.CheckRangeTimer = Button.CheckRangeTimerMacro;
746 self.UpdateFlash = Button.UpdateFlashMacro;
747 self.TranslateMacro = Button.TranslateMacro;
748 self.GetCursor = Button.GetCursorMacro;
749 self.UpdateFlyout = Button.Empty;
750
751 self.FullRefresh = Button.FullRefreshMacro;
752
753 self.Mode = "macro";
754 self.MacroIndex = Index;
755 self.MacroName = Name;
756 self.MacroBody = Body;
757 self.Texture = nil; --set in translate macro
758 self.Target = "target";
759 self.ShowTooltip = string.find(Body, "#showtooltip") ~= nil;
760
761 self:ResetAppearance();
762 self:DisplayActive();
763
764 Util.AddMacro(self);
765end
766function Button:SetEnvCompanion(MountID)
767 if (not MountID) then
768 return self:ClearCommand();
769 end
770 -- now only handles mounts
771 -- This code path ultimately works - but it is a bit wonky when the Summon Random Favorite comes through
772 --[[if (SpellID == nil) then
773 -- We got the useless Index, try and map it
774 Index = Util.GetMountIndexFromUselessIndex(Index);
775 SpellID = select(2, C_MountJournal.GetDisplayedMountInfo(Index));
776 else
777 -- We got a good Index, but we should check that
778 -- the Mapping is still valid
779 if (SpellID ~= select(2, C_MountJournal.GetDisplayedMountInfo(Index))) then
780 -- The mapping isn't right, so update the Index
781 Index = Util.GetMountIndexFromSpellID(SpellID);
782 end
783 end--]]
784
785 --[[if (Index == nil) then
786 -- So no mount was found
787 self:ClearCommand();
788 return;]]
789 --local SpellID = select(2, C_MountJournal.GetDisplayedMountInfo(Index));
790 --if (Index == 0) then
791 -- It's the random favorite button
792 --SpellID = Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL;
793
794 --self:SetMountFavorite(BFButton);
795 --return;
796 --end
797 self.Widget:SetAttribute("type", nil);
798 self.Widget:SetAttribute("spell", nil);
799 self.Widget:SetAttribute("item", nil);
800 self.Widget:SetAttribute("macro", nil);
801 self.Widget:SetAttribute("macrotext", nil);
802 self.Widget:SetAttribute("action", nil);
803 self.Widget:SetAttribute("id", nil);
804 self.Mode = "mount";
805 self.MountID = MountID;
806
807 if (self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID) then
808 self.MountName = GetSpellInfo(Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL);
809 self.MountSpellID = Const.SUMMON_RANDOM_FAVORITE_MOUNT_SPELL;
810 self.MountSpellName = self.MountName;
811
812
813
814 if (ButtonForgeGlobalSettings["UseCollectionsFavoriteMountButton"] and not IsAddOnLoaded("Blizzard_Collections")) then
815 LoadAddOn("Blizzard_Collections");
816 end
817 if (ButtonForgeGlobalSettings["UseCollectionsFavoriteMountButton"] and MountJournalSummonRandomFavoriteButton) then
818 self.Widget:SetAttribute("type", "click");
819 self.Widget:SetAttribute("clickbutton", MountJournalSummonRandomFavoriteButton);
820 else
821 -- this will cause a script warning when clicked if the player does not allow dangerous scripts but also chooses false for the global setting
822 self.Widget:SetAttribute("type", "macro");
823 self.Widget:SetAttribute("macrotext", "/run C_MountJournal.SummonByID("..self.MountID..")");
824 end
825
826 else
827 self.MountName = C_MountJournal.GetMountInfoByID(MountID);
828 self.MountSpellID = select(2, C_MountJournal.GetMountInfoByID(MountID));
829 self.MountSpellName = GetSpellInfo(self.MountSpellID);
830 self.Widget:SetAttribute("type", "macro");
831 self.Widget:SetAttribute("macrotext", "/cast "..self.MountSpellName);
832 end
833
834
835 self.Texture = GetSpellTexture(self.MountSpellID); --select(3, C_MountJournal.GetDisplayedMountInfo(Index));
836
837
838 self.UpdateTexture = Button.Empty;
839 self.UpdateChecked = Button.UpdateCheckedCompanion;
840 self.UpdateEquipped = Button.Empty;
841 self.UpdateCooldown = Button.UpdateCooldownCompanion;
842 self.UpdateUsable = Button.UpdateUsableCompanion;
843 self.UpdateTextCount = Button.Empty;
844 self.UpdateTooltipFunc = Button.UpdateTooltipCompanion;
845 self.UpdateRangeTimer = Button.Empty;
846 self.CheckRangeTimer = Button.Empty;
847 self.UpdateFlash = Button.Empty;
848 self.UpdateFlyout = Button.Empty;
849
850 self.GetCursor = Button.GetCursorCompanion;
851
852 self.FullRefresh = Button.FullRefresh;
853
854 --[[self.Mode = "companion";
855 self.CompanionId = Id;
856 self.CompanionType = Type;
857 self.CompanionIndex = Index;
858 self.CompanionName = Name;
859 self.CompanionSpellName = SpellName;
860 self.Texture = select(4, GetCompanionInfo(Type, Index)); --safe provided Type in ("MOUNT", "CRITTER") and Index is numeric
861 ]]
862 self.Target = "target";
863
864 self:ResetAppearance();
865 self:DisplayActive();
866 self:SaveCompanion(MountID, self.MountSpellID, self.MountName);
867end
868function Button:SetEnvEquipmentSet(Id, Name)
869 local Index = Util.LookupEquipmentSetIndex(Id);
870
871 if (Index == nil) then
872 -- This equip set is gone so clear it from the button
873 return self:ClearCommand();
874 end
875
876 self.UpdateTexture = Button.Empty;
877 self.UpdateChecked = Button.UpdateChecked;
878 self.UpdateEquipped = Button.Empty;
879 self.UpdateCooldown = Button.Empty;
880 self.UpdateUsable = Button.Empty;
881 self.UpdateTextCount = Button.Empty;
882 self.UpdateTooltipFunc = Button.UpdateTooltipEquipmentSet;
883 self.UpdateRangeTimer = Button.Empty;
884 self.CheckRangeTimer = Button.Empty;
885 self.UpdateFlash = Button.Empty;
886 self.UpdateFlyout = Button.Empty;
887
888 self.GetCursor = Button.GetCursorEquipmentSet;
889
890 self.FullRefresh = Button.FullRefresh;
891
892 self.Mode = "equipmentset";
893 self.EquipmentSetId = Id;
894 self.EquipmentSetName = Name;
895 self.Texture = select(2, C_EquipmentSet.GetEquipmentSetInfo(Index)) or ""; --"Interface/Icons/"..(GetEquipmentSetInfoByName(Name) or ""); --safe provided Name ~= nil
896 self.Target = "target";
897
898 self:ResetAppearance();
899 self:DisplayActive();
900 self.WName:SetText(Name);
901end
902function Button:SetEnvBonusAction(Id)
903 self.UpdateTexture = Button.UpdateTextureBonusAction;
904 self.UpdateChecked = Button.UpdateCheckedBonusAction;
905 self.UpdateEquipped = Button.Empty;
906 self.UpdateCooldown = Button.UpdateCooldownBonusAction;
907 self.UpdateUsable = Button.UpdateUsableBonusAction;
908 self.UpdateTextCount = Button.UpdateTextCountBonusAction;
909 self.UpdateTooltipFunc = Button.UpdateTooltipBonusAction;
910 self.UpdateRangeTimer = Button.UpdateRangeTimerBonusAction;
911 self.CheckRangeTimer = Button.CheckRangeTimerBonusAction;
912 self.UpdateFlash = Button.UpdateFlashBonusAction;
913 self.UpdateFlyout = Button.Empty;
914
915 self.GetCursor = Button.GetCursorBonusAction;
916
917 self.FullRefresh = Button.FullRefresh;
918
919 self.Mode = "bonusaction";
920 self.BonusActionId = Id;
921 self.BonusActionSlot = Id + 132;
922 self.Texture = GetActionTexture(self.BonusActionSlot);-- "Interface/Icons/"..(GetEquipmentSetInfoByName(Name) or ""); --safe provided Name ~= nil
923 self.Target = "target";
924 self.Tooltip = Util.GetLocaleString("BonusActionTooltip")..Id;
925 self:ResetAppearance();
926 self:DisplayActive();
927 Util.AddBonusAction(self);
928end
929function Button:SetEnvFlyout(Id)
930 self.UpdateTexture = Button.Empty;
931 self.UpdateChecked = Button.UpdateChecked;
932 self.UpdateEquipped = Button.Empty;
933 self.UpdateCooldown = Button.Empty;
934 self.UpdateUsable = Button.Empty;
935 self.UpdateTextCount = Button.Empty;
936 self.UpdateTooltipFunc = Button.UpdateTooltipFlyout;
937 self.UpdateRangeTimer = Button.Empty;
938 self.CheckRangeTimer = Button.Empty;
939 self.UpdateFlash = Button.Empty;
940 self.UpdateFlyout = Button.UpdateFlyout;
941
942 self.GetCursor = Button.GetCursorFlyout;
943
944 self.FullRefresh = Button.FullRefresh;
945
946 self.Mode = "flyout";
947 self.FlyoutId = Id;
948 local ind, booktype = Util.LookupSpellIndex("FLYOUT"..Id);
949 if (ind) then
950 self.Texture = GetSpellBookItemTexture(ind, booktype) or "Interface/Icons/INV_Misc_QuestionMark";
951 else
952 self.Texture = "Interface/Icons/INV_Misc_QuestionMark";
953 end
954 self.Target = "target";
955 self.Tooltip = "Placeholder";
956 self:ResetAppearance();
957 self:DisplayActive();
958 self:UpdateFlyout();
959
960
961-- BFFlyoutWrapperFrame:WrapScript(SpellFlyout, "OnShow", [[return true, "true";]], [[owner:CallMethod("RefreshFlyouts");]]);
962 --BFFlyoutWrapperFrame:WrapScript(SpellFlyout, "OnHide", [[return true, "true";]], [[owner:CallMethod("RefreshFlyouts");]]);
963end
964function Button:SetEnvCustomAction(Name)
965 local TexCoords;
966 self.UpdateTexture = Button.UpdateTextureCustomAction;
967 self.UpdateChecked = Button.UpdateCheckedCustomAction;
968 self.UpdateEquipped = Button.Empty;
969 self.UpdateCooldown = Button.Empty;
970 self.UpdateUsable = Button.UpdateUsableCustomAction;
971 self.UpdateTextCount = Button.Empty;
972 self.UpdateTooltipFunc = Button.UpdateTooltipCustomAction;
973 self.UpdateRangeTimer = Button.Empty;
974 self.CheckRangeTimer = Button.Empty;
975 self.UpdateFlash = Button.Empty;
976 self.UpdateFlyout = Button.Empty;
977
978 self.GetCursor = Button.GetCursorCustomAction;
979
980 self.FullRefresh = Button.FullRefresh;
981
982 self.Mode = "customaction";
983 self.CustomActionName = Name;
984 self.Texture, TexCoords = CustomAction.GetTexture(Name);
985 self.Target = "target";
986
987 self:ResetAppearance();
988 self:DisplayActive(TexCoords);
989 Util.AddBonusAction(self);
990end
991function Button:SetEnvBattlePet(Id)
992 self.UpdateTexture = Button.Empty;
993 self.UpdateChecked = Button.UpdateCheckedBattlePet;
994 self.UpdateEquipped = Button.Empty;
995 self.UpdateCooldown = Button.UpdateCooldownBattlePet;
996 self.UpdateUsable = Button.UpdateUsableBattlePet;
997 self.UpdateTextCount = Button.Empty;
998 self.UpdateTooltipFunc = Button.UpdateTooltipBattlePet;
999 self.UpdateRangeTimer = Button.Empty;
1000 self.CheckRangeTimer = Button.Empty;
1001 self.UpdateFlash = Button.Empty;
1002 self.UpdateFlyout = Button.Empty;
1003
1004 self.GetCursor = Button.GetCursorBattlePet;
1005
1006 self.FullRefresh = Button.FullRefresh;
1007
1008 self.Mode = "battlepet";
1009 self.BattlePetId = Id;
1010 if (Id == Const.SUMMON_RANDOM_FAVORITE_BATTLE_PET_ID) then
1011 self.Texture = Const.SUMMON_RANDOM_FAVORITE_BATTLE_PET_TEXTURE;
1012 else
1013 self.Texture = select(9, C_PetJournal.GetPetInfoByPetID(Id));
1014 end
1015 self.Target = "target";
1016
1017 self:ResetAppearance();
1018 self:DisplayActive();
1019end
1020function Button:SetEnvClear()
1021 self.UpdateTexture = Button.Empty;
1022 self.UpdateChecked = Button.UpdateChecked;
1023 self.UpdateEquipped = Button.Empty;
1024 self.UpdateCooldown = Button.Empty;
1025 self.UpdateUsable = Button.Empty;
1026 self.UpdateTextCount = Button.Empty;
1027 self.UpdateTooltipFunc = Button.Empty;
1028 self.UpdateRangeTimer = Button.Empty;
1029 self.CheckRangeTimer = Button.Empty;
1030 self.UpdateFlash = Button.Empty;
1031 self.UpdateFlyout = Button.Empty;
1032
1033 self.GetCursor = Button.Empty;
1034
1035 self.FullRefresh = Button.Empty;
1036
1037 self.Mode = nil;
1038
1039 self:ResetAppearance();
1040 self:DisplayEmpty();
1041end
1042
1043--[[ These functions will update the save data for the button action --]]
1044function Button:SaveSpell(Id, NameRank, Name, Book)
1045 self:SaveClear();
1046 self.ButtonSave["Mode"] = "spell";
1047 self.ButtonSave["SpellId"] = Id;
1048 self.ButtonSave["SpellNameRank"] = NameRank;
1049 self.ButtonSave["SpellName"] = Name;
1050 self.ButtonSave["SpellBook"] = Book;
1051end
1052function Button:SaveItem(Id, Name, Link)
1053 self:SaveClear();
1054 self.ButtonSave["Mode"] = "item";
1055 self.ButtonSave["ItemId"] = Id;
1056 self.ButtonSave["ItemName"] = Name;
1057 self.ButtonSave["ItemLink"] = Link;
1058end
1059function Button:SaveMacro(Index, Name, Body)
1060 self:SaveClear();
1061 self.ButtonSave["Mode"] = "macro";
1062 self.ButtonSave["MacroIndex"] = Index;
1063 self.ButtonSave["MacroName"] = Name;
1064 self.ButtonSave["MacroBody"] = Body;
1065end
1066function Button:SaveCompanion(MountID, MountSpellID, MountName)
1067 self:SaveClear();
1068 self.ButtonSave["Mode"] = "mount";
1069 self.ButtonSave["MountID"] = MountID;
1070 self.ButtonSave["MountSpellID"] = MountSpellID;
1071 self.ButtonSave["MountName"] = MountName;
1072end
1073function Button:SaveEquipmentSet(Id, Name)
1074 self:SaveClear();
1075 self.ButtonSave["Mode"] = "equipmentset";
1076 self.ButtonSave["EquipmentSetId"] = Id;
1077 self.ButtonSave["EquipmentSetName"] = Name;
1078end
1079function Button:SaveBonusAction(Id)
1080 self:SaveClear();
1081 self.ButtonSave["Mode"] = "bonusaction";
1082 self.ButtonSave["BonusActionId"] = Id;
1083end
1084function Button:SaveFlyout(Id)
1085 self:SaveClear();
1086 self.ButtonSave["Mode"] = "flyout";
1087 self.ButtonSave["FlyoutId"] = Id;
1088end
1089function Button:SaveCustomAction(Name)
1090 self:SaveClear();
1091 self.ButtonSave["Mode"] = "customaction";
1092 self.ButtonSave["CustomActionName"] = Name;
1093end
1094function Button:SaveBattlePet(Id)
1095 self:SaveClear();
1096 self.ButtonSave["Mode"] = "battlepet";
1097 self.ButtonSave["BattlePetId"] = Id;
1098end
1099function Button:SaveClear()
1100 self.ButtonSave["SpellId"] = nil;
1101 self.ButtonSave["SpellNameRank"] = nil;
1102 self.ButtonSave["SpellName"] = nil;
1103 self.ButtonSave["SpellBook"] = nil;
1104 self.ButtonSave["ItemId"] = nil;
1105 self.ButtonSave["ItemName"] = nil;
1106 self.ButtonSave["ItemLink"] = nil;
1107 self.ButtonSave["MacroIndex"] = nil;
1108 self.ButtonSave["MacroName"] = nil;
1109 self.ButtonSave["MacroBody"] = nil;
1110 self.ButtonSave["CompanionId"] = nil;
1111 self.ButtonSave["CompanionType"] = nil;
1112 self.ButtonSave["CompanionIndex"] = nil;
1113 self.ButtonSave["CompanionName"] = nil;
1114 self.ButtonSave["MountIndex"] = nil;
1115 self.ButtonSave["MountSpellID"] = nil;
1116 self.ButtonSave["MountName"] = nil;
1117 self.ButtonSave["MountID"] = nil;
1118 self.ButtonSave["CompanionSpellName"] = nil;
1119 self.ButtonSave["MountIndex"] = nil;
1120 self.ButtonSave["MountSpellID"] = nil;
1121 self.ButtonSave["MountName"] = nil;
1122 self.ButtonSave["EquipmentSetId"] = nil;
1123 self.ButtonSave["EquipmentSetName"] = nil;
1124 self.ButtonSave["BonusActionId"] = nil;
1125 self.ButtonSave["FlyoutId"] = nil;
1126 self.ButtonSave["CustomActionName"] = nil;
1127 self.ButtonSave["BattlePetId"] = nil;
1128 self.ButtonSave["Mode"] = nil;
1129end
1130
1131--[[ 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) --]]
1132function Button:SetAttributes(Type, Value)
1133 --Firstly clear all relevant fields
1134 self.Widget:SetAttribute("type", nil);
1135 self.Widget:SetAttribute("spell", nil);
1136 self.Widget:SetAttribute("item", nil);
1137 self.Widget:SetAttribute("macro", nil);
1138 self.Widget:SetAttribute("macrotext", nil);
1139 self.Widget:SetAttribute("action", nil);
1140 self.Widget:SetAttribute("clickbutton", nil);
1141 self.Widget:SetAttribute("id", nil);
1142
1143 --Now if a valid type is passed in set it
1144 if (Type == "spell" or Type == "item" or Type == "macro") then
1145 self.Widget:SetAttribute("type", Type);
1146 self.Widget:SetAttribute(Type, Value);
1147
1148 elseif (Type == "companion") then
1149 self.Widget:SetAttribute("type", "spell");
1150 self.Widget:SetAttribute("spell", Value);
1151
1152 elseif (Type == "equipmentset") then
1153 self.Widget:SetAttribute("type", "macro");
1154 self.Widget:SetAttribute("macrotext", "/equipset "..Value);
1155 elseif (Type == "bonusaction") then
1156 self.Widget:SetAttribute("type", "action");
1157 self.Widget:SetAttribute("id", Value);
1158 if (HasOverrideActionBar()) then
1159 self.Widget:SetAttribute("action", Value + ((14 - 1) * 12));
1160 else
1161 self.Widget:SetAttribute("action", Value + ((12 - 1) * 12));
1162 end
1163 elseif (Type == "flyout") then
1164 self.Widget:SetAttribute("type", "flyout");
1165 self.Widget:SetAttribute("spell", Value);
1166 elseif (Type == "customaction") then
1167 CustomAction.SetAttributes(Value, self.Widget);
1168 elseif (Type == "battlepet") then
1169 self.Widget:SetAttribute("type", "macro");
1170 self.Widget:SetAttribute("macrotext", "/summonpet "..Value);
1171 end
1172end
1173
1174
1175
1176
1177
1178--[[--------------------------------------------------------------------------
1179 Tidy up the display state for a button (does not include the icon itself)
1180----------------------------------------------------------------------------]]
1181function Button:ResetAppearance()
1182 self.Widget:SetChecked(false);
1183
1184 self.WBorder:Hide();
1185
1186 Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
1187 self.WCooldown:Hide();
1188
1189 self.WIcon:SetAlpha(1);
1190 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1191 self.WIcon:SetTexCoord(0, 1, 0, 1);
1192 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1193
1194 self.WCount:SetText("");
1195 self.WName:SetText("");
1196 Util.RemoveMacro(self);
1197 Util.RemoveSpell(self);
1198 Util.RemoveItem(self);
1199 Util.RemoveBonusAction(self);
1200 self:RemoveFromRangeTimer();
1201 self:RemoveFromFlash();
1202 Button.UpdateFlyout(self);
1203 self:UpdateGlow();
1204 if (self.TooltipEnabled and GetMouseFocus() == self.Widget) then
1205 Button.OnEnterTooltip(self.Widget);
1206 end
1207end
1208
1209
1210
1211
1212
1213--[[--------------------------------------------------------------------------
1214 Functions to do a full refresh of the display info for the Button
1215----------------------------------------------------------------------------]]
1216function Button:FullRefresh()
1217 self:UpdateTexture();
1218 self:UpdateChecked();
1219 self:UpdateEquipped();
1220 self:UpdateCooldown();
1221 self:UpdateUsable();
1222 self:UpdateTextCount();
1223 self:UpdateRangeTimer();
1224 self:UpdateFlash();
1225 self:UpdateFlyout();
1226 self:UpdateGlow();
1227
1228 self:UpdateTooltip();
1229
1230end
1231
1232function Button:FullRefreshMacro()
1233 self:TranslateMacro();
1234 Button.FullRefresh(self);
1235end
1236
1237
1238
1239
1240
1241--[[------------------------------------------------------------------------------
1242 Since macros have to masquerade as potentially several different types this
1243 function will cache what the macro currently is
1244--------------------------------------------------------------------------------]]
1245function Button:TranslateMacro()
1246 local Texture = select(2, GetMacroInfo(self.MacroIndex));
1247 --self.Texture = select(2, GetMacroInfo(self.MacroIndex));
1248 local Action, Target = SecureCmdOptionParse(self.MacroBody or '');
1249 self.Target = Target or "target"; --check into if this is the best thing to do or leaving it nil would be better?
1250 local TargetName = UnitName(self.Target);
1251 local TargetDead = UnitIsDead(self.Target);
1252 if (self.Texture ~= Texture or self.MacroAction ~= Action or self.MacroTargetName ~= TargetName or self.MacroTargetDead ~= TargetDead) then
1253 self.Texture = Texture;
1254 self.MacroAction = Action;
1255 self.MacroTargetName = TargetName;
1256 self.MacroTargetDead = TargetDead;
1257 local SpellName, SpellRank, SpellId = GetMacroSpell(self.MacroIndex);
1258 if (SpellName) then
1259 --[[local CompanionType, CompanionIndex = Util.LookupCompanion(SpellName);
1260 if (CompanionType) then
1261 self.CompanionType = CompanionType;
1262 self.CompanionIndex = CompanionIndex;
1263 local SpellId = select(3, GetCompanionInfo(CompanionType, CompanionIndex));
1264 self.CompanionSpellName = GetSpellInfo(SpellId);
1265 self.MacroMode = "companion";
1266 else]]
1267 self.SpellName = SpellName;
1268 self.SpellNameRank = Util.GetFullSpellName(SpellName, SpellRank);
1269 self.SpellId = SpellId;
1270 self.MacroMode = "spell";
1271 --end
1272 else
1273 local ItemName, ItemLink = GetMacroItem(self.MacroIndex);
1274 if (ItemName) then
1275 self.ItemId = Util.GetItemId(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
1276 self.ItemName = ItemName;
1277 self.ItemLink = ItemLink;
1278 self.MacroMode = "item";
1279 else
1280 self.MacroMode = "";
1281 end
1282 end
1283 Button.FullRefresh(self);
1284 end
1285end
1286
1287
1288
1289
1290
1291--[[---------------------------------------------------------------------------------
1292 Texture functions
1293-----------------------------------------------------------------------------------]]
1294function Button:UpdateTexture()
1295
1296end
1297
1298--BFA fix: BFA removed the use of UnitBuff with the spell name as a parameter.
1299--BFA fix: Added this function to compensate
1300function Button:UnitBuffBySpell(unit, spell)
1301 for i=1,40 do
1302 local name, icon, _, _, _, etime = UnitBuff(unit,i)
1303 if name then
1304 if name == spell then
1305 return UnitBuff(unit,i);
1306 end
1307 else
1308 break;
1309 end;
1310 end;
1311 return nil;
1312end;
1313
1314function Button:UpdateTextureWispSpell()
1315--BFA fix: UnitBuff can no longer be called with the spell name as a param
1316 if (self.UnitBuffBySpell("player", self.SpellName)) then --NOTE: This en-US, hopefully it will be fine for other locales as well??
1317 self.WIcon:SetTexture("Interface/Icons/Spell_Nature_WispSplode");
1318 else
1319 self.WIcon:SetTexture(self.Texture);
1320 end
1321end
1322function Button:UpdateTextureMacro()
1323 self.WIcon:SetTexture(self.Texture);
1324end
1325function Button:UpdateTextureBonusAction()
1326 local action = self.Widget:GetAttribute("action");
1327 if (HasOverrideActionBar() or HasVehicleActionBar()) then
1328 local Texture = GetActionTexture(action);
1329 if (not Texture) then
1330 self.WIcon:SetTexture(Const.ImagesDir.."Bonus"..self.BonusActionId);
1331 self.WIcon:SetAlpha(0.1);
1332 else
1333 self.WIcon:SetTexture(Texture);
1334 self.WIcon:SetAlpha(1);
1335 end
1336
1337 else
1338 self.WIcon:SetTexture(Const.ImagesDir.."Bonus"..self.BonusActionId);
1339 self.WIcon:SetAlpha(1);
1340 end
1341end
1342function Button:UpdateTextureCustomAction()
1343 self.WIcon:SetTexture(CustomAction.GetTexture(self.CustomActionName));
1344end
1345
1346
1347
1348function Button:DisplayActive(TexCoords)
1349 local Icon = self.WIcon;
1350
1351 Icon:SetTexture(self.Texture);
1352 self.Widget:SetNormalTexture("Interface/Buttons/UI-Quickslot2");
1353 if (TexCoords) then
1354 Icon:SetTexCoord(unpack(TexCoords));
1355 else
1356 Icon:SetTexCoord(0, 1, 0, 1);
1357 end
1358 Icon:SetVertexColor(1.0, 1.0, 1.0, 1.0);
1359 Icon:Show();
1360
1361end
1362function Button:DisplayMissing()
1363 local Icon = self.WIcon;
1364
1365 Icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark");
1366 self.Widget:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
1367 Icon:SetVertexColor(1.0, 1.0, 1.0, 0.5);
1368 Icon:Show();
1369
1370end
1371function Button:DisplayEmpty()
1372 self.WIcon:Hide();
1373 --self.Widget:SetNormalTexture("Interface/Buttons/UI-Quickslot");
1374 self.WCooldown:Hide();
1375end
1376
1377
1378
1379
1380
1381
1382--[[--------------------------------------------------------------------------
1383 Checked functions
1384----------------------------------------------------------------------------]]
1385function Button:UpdateChecked()
1386 self.Widget:SetChecked(false);
1387end
1388function Button:UpdateCheckedSpell()
1389 if (IsCurrentSpell(self.SpellNameRank) or IsAutoRepeatSpell(self.SpellNameRank)) then
1390 self.Widget:SetChecked(true);
1391 else
1392 self.Widget:SetChecked(false);
1393 end
1394end
1395function Button:UpdateCheckedItem()
1396 if (IsCurrentItem(self.ItemId)) then
1397 self.Widget:SetChecked(true);
1398 else
1399 self.Widget:SetChecked(false);
1400 end
1401end
1402function Button:UpdateCheckedMacro()
1403 if (self.MacroMode == "spell") then
1404 self:UpdateCheckedSpell();
1405 elseif (self.MacroMode == "item") then
1406 self:UpdateCheckedItem();
1407 elseif (self.MacroMode == "companion") then
1408 self:UpdateCheckedCompanion();
1409 else
1410 self.Widget:SetChecked(false);
1411 end
1412end
1413function Button:UpdateCheckedCompanion()
1414 --local Active = select(5, GetCompanionInfo(self.CompanionType, self.CompanionIndex));
1415 --local SpellName = UnitCastingInfo("player");
1416 if (select(4, C_MountJournal.GetMountInfoByID(self.MountID))
1417 or (self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID and IsMounted())) then
1418 self.Widget:SetChecked(true);
1419 else
1420 self.Widget:SetChecked(false);
1421 end
1422end
1423function Button:UpdateCheckedBonusAction()
1424 local action = self.Widget:GetAttribute("action");
1425 if ((HasOverrideActionBar() or HasVehicleActionBar()) and (IsCurrentAction(action) or IsAutoRepeatAction(action))) then
1426 self.Widget:SetChecked(true);
1427 else
1428 self.Widget:SetChecked(false);
1429 end
1430end
1431function Button:UpdateCheckedCustomAction()
1432 self.Widget:SetChecked(CustomAction.GetChecked(self.CustomActionName));
1433end
1434function Button:UpdateCheckedBattlePet()
1435 local Active = self.BattlePetId == C_PetJournal.GetSummonedPetGUID();
1436 self.Widget:SetChecked(Active);
1437end
1438
1439
1440
1441
1442--[[---------------------------------------------------------------------------------------
1443 Equipped functions
1444-----------------------------------------------------------------------------------------]]
1445function Button:UpdateEquipped()
1446
1447end
1448
1449function Button:UpdateEquippedItem()
1450 if (IsEquippedItem(self.ItemId)) then
1451 self.WBorder:SetVertexColor(0, 1.0, 0, 0.35);
1452 self.WBorder:Show();
1453 else
1454 self.WBorder:Hide();
1455 end
1456end
1457function Button:UpdateEquippedMacro()
1458 if (self.MacroMode == "item") then
1459 self:UpdateEquippedItem();
1460 else
1461 self.WBorder:Hide();
1462 end
1463end
1464-- In future it may be an idea to do an equip set check although I question the value
1465
1466
1467
1468
1469
1470
1471--[[-------------------------------------------------------------------------------------------
1472 Cooldown functions (great care is needed with the cooldowns...)
1473---------------------------------------------------------------------------------------------]]
1474function Button:UpdateCooldown()
1475
1476end
1477function Button:UpdateCooldownSpell()
1478 local Start, Duration, Enable = GetSpellCooldown(self.SpellNameRank);
1479 local Charges, MaxCharges, ChargeStart, ChargeDuration = GetSpellCharges(self.SpellNameRank);
1480
1481 if (Start ~= nil) then
1482 --Charges = Charges or 0;
1483 --MaxCharges = MaxCharges or 0;
1484 if (Charges ~= MaxCharges) then
1485 Start = ChargeStart;
1486 Duration = ChargeDuration;
1487 end
1488 Util.CooldownFrame_SetTimer(self.WCooldown, Start, Duration, Enable, Charges, MaxCharges);
1489 else
1490 Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
1491 self.WCooldown:Hide();
1492 end
1493end
1494function Button:UpdateCooldownItem()
1495 Util.CooldownFrame_SetTimer(self.WCooldown, GetItemCooldown(self.ItemId));
1496end
1497function Button:UpdateCooldownMacro()
1498 if (self.MacroMode == "spell") then
1499 self:UpdateCooldownSpell();
1500 elseif (self.MacroMode == "item") then
1501 self:UpdateCooldownItem();
1502 elseif (self.MacroMode == "companion") then
1503 self:UpdateCooldownCompanion();
1504 else
1505 Util.CooldownFrame_SetTimer(self.WCooldown, 0, 0, 0);
1506 self.WCooldown:Hide();
1507 end
1508end
1509function Button:UpdateCooldownCompanion()
1510 --CooldownFrame_SetTimer(self.WCooldown, GetCompanionCooldown(self.CompanionType, self.CompanionIndex));
1511 --as of 5.0.4 doesn't appear to exist anymore?!
1512end
1513function Button:UpdateCooldownBonusAction()
1514 if (HasOverrideActionBar() or HasVehicleActionBar()) then
1515 local action = self.Widget:GetAttribute("action");
1516 Util.CooldownFrame_SetTimer(self.WCooldown, GetActionCooldown(action));
1517 else
1518 self.WCooldown:Hide();
1519 end
1520end
1521function Button:UpdateCooldownBattlePet()
1522 --CooldownFrame_SetTimer(self.WCooldown, GetCompanionCooldown(self.CompanionType, self.CompanionIndex));
1523 --as of 5.0.4 doesn't appear to exist anymore?!
1524end
1525
1526
1527
1528--[[-------------------------------------------------------------------------------------
1529 Usable Functions
1530---------------------------------------------------------------------------------------]]
1531function Button:UpdateUsable()
1532
1533end
1534function Button:UpdateUsableSpell()
1535 local IsUsable, NotEnoughMana = IsUsableSpell(self.SpellNameRank);
1536 if (IsUsable) then
1537 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1538 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1539 elseif (NotEnoughMana) then
1540 self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
1541 self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
1542 else
1543 self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1544 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1545 end
1546end
1547function Button:UpdateUsableItem()
1548 local IsUsable, NotEnoughMana = IsUsableItem(self.ItemId);
1549 IsUsable = IsUsable or PlayerHasToy(self.ItemId);
1550 if (IsUsable) then
1551 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1552 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1553 elseif (NotEnoughMana) then
1554 self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
1555 self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
1556 else
1557 self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1558 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1559 end
1560end
1561function Button:UpdateUsableMacro()
1562 if (self.MacroMode == "spell") then
1563 self:UpdateUsableSpell();
1564 elseif (self.MacroMode == "item") then
1565 self:UpdateUsableItem();
1566 elseif (self.MacroMode == "companion") then
1567 self:UpdateUsableCompanion();
1568 else
1569 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1570 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1571 end
1572end
1573function Button:UpdateUsableCompanion()
1574 local IsUsable = IsUsableSpell(self.MountSpellID) and (select(5, C_MountJournal.GetMountInfoByID(self.MountID)) or self.MountID == Const.SUMMON_RANDOM_FAVORITE_MOUNT_ID);
1575
1576 if (IsUsable) then
1577 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1578 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1579 else
1580 self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1581 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1582 end
1583end
1584function Button:UpdateUsableBonusAction()
1585 local action = self.Widget:GetAttribute("action");
1586 local IsUsable, NotEnoughMana = IsUsableAction(action);
1587 if (IsUsable or (HasOverrideActionBar() == nil and HasVehicleActionBar() == nil)) then
1588 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1589 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1590 elseif (NotEnoughMana) then
1591 self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
1592 self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
1593 else
1594 self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1595 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1596 end
1597end
1598function Button:UpdateUsableCustomAction()
1599 local IsUsable, NotEnoughMana = CustomAction.IsUsable(self.CustomActionName);
1600 if (IsUsable) then
1601 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1602 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1603 elseif (NotEnoughMana) then
1604 self.WIcon:SetVertexColor(0.5, 0.5, 1.0);
1605 self.WNormalTexture:SetVertexColor(0.5, 0.5, 1.0);
1606 else
1607 self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1608 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1609 end
1610end
1611function Button:UpdateUsableBattlePet()
1612 --local IsUsable, NotEnoughMana = IsUsableItem(self.ItemName);
1613 --if (self.CompanionType == "MOUNT" and IsIndoors()) then
1614 -- self.WIcon:SetVertexColor(0.4, 0.4, 0.4);
1615 -- self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1616 --else
1617 self.WIcon:SetVertexColor(1.0, 1.0, 1.0);
1618 self.WNormalTexture:SetVertexColor(1.0, 1.0, 1.0);
1619 --end
1620end
1621
1622
1623--[[----------------------------------------------------------------------------
1624 Text functions
1625------------------------------------------------------------------------------]]
1626function Button:UpdateTextCount()
1627
1628end
1629function Button:UpdateTextCountSpell()
1630 local count = GetSpellCount(self.SpellNameRank);
1631 if (count ~= 0 or IsConsumableSpell(self.SpellNameRank)) then
1632 self.WCount:SetText(count);
1633 return;
1634 end
1635 local charges = GetSpellCharges(self.SpellNameRank);
1636 if (charges ~= nil) then
1637 self.WCount:SetText(charges);
1638 return;
1639 end
1640 self.WCount:SetText("");
1641end
1642function Button:UpdateTextCountItem()
1643 local ItemCount = GetItemCount(self.ItemId, nil, true);
1644 if (IsConsumableItem(self.ItemId) or ItemCount > 1) then
1645 self.WCount:SetText(ItemCount);
1646 else
1647 self.WCount:SetText("");
1648 end
1649end
1650function Button:UpdateTextCountMacro()
1651 if (self.MacroMode == "spell") then
1652 self:UpdateTextCountSpell();
1653 elseif (self.MacroMode == "item") then
1654 self:UpdateTextCountItem();
1655 else
1656 self.WCount:SetText("");
1657 end
1658
1659 if (self.WCount:GetText() == nil and self.MacroTextEnabled) then
1660 self.WName:SetText(self.MacroName);
1661 else
1662 self.WName:SetText("");
1663 end
1664end
1665function Button:UpdateTextCountBonusAction()
1666 local action = self.Widget:GetAttribute("action");
1667 if ((HasOverrideActionBar() or HasVehicleActionBar()) and (IsConsumableAction(action) or IsStackableAction(action))) then
1668 self.WCount:SetText(GetActionCount(action));
1669 else
1670 self.WCount:SetText("");
1671 end
1672end
1673
1674
1675
1676
1677
1678
1679function Button:UpdateTooltip()
1680
1681end
1682
1683function Button:UpdateTooltipFunc()
1684
1685end
1686
1687function Button:UpdateTooltipSpell()
1688 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1689 --local Index, BookType = Util.LookupSpellIndex(self.SpellNameRank);
1690 GameTooltip:SetSpellByID(self.SpellId);
1691 --if (Index) then
1692 -- GameTooltip:SetSpellBookItem(Index, BookType);
1693 --end
1694end
1695function Button:UpdateTooltipItem()
1696 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1697 local EquippedSlot = Util.LookupItemIdEquippedSlot(self.ItemId);
1698 if (EquippedSlot ~= nil) then
1699 GameTooltip:SetInventoryItem("player", EquippedSlot);
1700 else
1701 local Bag, BagSlot = Util.LookupItemIdBagSlot(self.ItemId);
1702 if (Bag ~= nil) then
1703 GameTooltip:SetBagItem(Bag, BagSlot);
1704 else
1705 GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget); --It appears that the sethyperlink (specifically this one) requires that the anchor be constantly refreshed!?
1706 GameTooltip:SetHyperlink(self.ItemLink);
1707 end
1708 end
1709end
1710function Button:UpdateTooltipMacro()
1711 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1712
1713 if (not self.ShowTooltip) then
1714 --we just show the name in this case
1715 GameTooltip:SetText(self.MacroName, 1, 1, 1, 1);
1716
1717 elseif (self.MacroMode == "spell") then
1718 local Index, BookType = Util.LookupSpellIndex(self.SpellNameRank);
1719 if (Index) then
1720 GameTooltip:SetSpellBookItem(Index, BookType);
1721 end
1722 elseif (self.MacroMode == "item") then
1723 local EquippedSlot = Util.LookupItemNameEquippedSlot(self.ItemId);
1724 if (EquippedSlot ~= nil) then
1725 GameTooltip:SetInventoryItem("player", EquippedSlot);
1726 else
1727 local Bag, BagSlot = Util.LookupItemNameBagSlot(self.ItemId);
1728 if (Bag ~= nil) then
1729 GameTooltip:SetBagItem(Bag, BagSlot);
1730 else
1731 GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget); --It appears that the sethyperlink (specifically this one) requires that the anchor be constantly refreshed!?
1732 GameTooltip:SetHyperlink(self.ItemLink);
1733 end
1734 end
1735 elseif (self.MacroMode == "companion") then
1736 local Id, Name, SpellId = GetCompanionInfo(self.CompanionType, self.CompanionIndex);
1737 GameTooltip:SetHyperlink("spell:"..SpellId);
1738 end
1739end
1740function Button:UpdateTooltipCompanion()
1741 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1742
1743 GameTooltip_SetDefaultAnchor(GameTooltip, self.Widget);
1744 GameTooltip:SetMountBySpellID(self.MountSpellID);
1745end
1746function Button:UpdateTooltipEquipmentSet()
1747 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1748
1749 GameTooltip:SetEquipmentSet(self.EquipmentSetName);
1750end
1751function Button:UpdateTooltipBonusAction()
1752 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1753 local action = self.Widget:GetAttribute("action");
1754 if (HasOverrideActionBar() or HasVehicleActionBar()) then
1755 GameTooltip:SetAction(action);
1756 else
1757 GameTooltip:SetText(self.Tooltip, nil, nil, nil, nil, 1);
1758 end
1759end
1760function Button:UpdateTooltipFlyout()
1761 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1762 local Index, BookType = Util.LookupSpellIndex("FLYOUT"..self.FlyoutId);
1763
1764 if (Index and not GameTooltip:IsShown()) then
1765 GameTooltip:SetSpellBookItem(Index, BookType);
1766 end
1767end
1768function Button:UpdateTooltipCustomAction()
1769 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1770
1771 CustomAction.UpdateTooltip(self.CustomActionName);
1772end
1773function Button:UpdateTooltipBattlePet()
1774 self = self.ParentButton or self; --This is a sneaky cheat incase the widget was used to get here...
1775 local speciesID, customName, level, xp, maxXp, displayID, isFavorite
1776 , name = C_PetJournal.GetPetInfoByPetID(self.BattlePetId);
1777
1778 if ( customName or name ) then
1779 GameTooltip:SetText(customName or name, 1, 1, 1);
1780 GameTooltip:AddLine(SPELL_CAST_TIME_INSTANT, 1, 1, 1, true);
1781 GameTooltip:AddLine(string.format(BATTLE_PET_TOOLTIP_SUMMON, name), nil, nil, nil, true);
1782 GameTooltip:Show();
1783 elseif (self.BattlePetId == Const.SUMMON_RANDOM_FAVORITE_BATTLE_PET_ID) then
1784 GameTooltip:SetText(PET_JOURNAL_SUMMON_RANDOM_FAVORITE_PET, 1, 1, 1);
1785 GameTooltip:AddLine(SPELL_CAST_TIME_INSTANT, 1, 1, 1, true);
1786 GameTooltip:Show();
1787 end
1788end
1789
1790
1791
1792--[[---------------------------------------------------------------------
1793 Cursor functions
1794-----------------------------------------------------------------------]]
1795function Button:GetCursor()
1796
1797end
1798function Button:GetCursorSpell()
1799 return self.Mode, nil, nil, self.SpellId;
1800end
1801function Button:GetCursorItem()
1802 return self.Mode, self.ItemId, nil;
1803end
1804function Button:GetCursorMacro()
1805 return self.Mode, self.MacroIndex, nil;
1806end
1807function Button:GetCursorCompanion()
1808 return self.Mode, self.MountID;
1809end
1810function Button:GetCursorEquipmentSet()
1811 return self.Mode, self.EquipmentSetName, nil;
1812end
1813function Button:GetCursorBonusAction()
1814 return self.Mode, self.BonusActionId, nil;
1815end
1816function Button:GetCursorFlyout()
1817 return self.Mode, self.FlyoutId, nil;
1818end
1819function Button:GetCursorCustomAction()
1820 return self.Mode, self.CustomActionName, nil;
1821end
1822function Button:GetCursorBattlePet()
1823 return self.Mode, self.BattlePetId, nil;
1824end
1825
1826
1827
1828
1829--[[------------------------------------------------------------------------
1830 Flash functions
1831--------------------------------------------------------------------------]]
1832function Button:UpdateFlash()
1833
1834end
1835function Button:UpdateFlashSpell()
1836 if ((IsAttackSpell(self.SpellNameRank) and IsCurrentSpell(self.SpellNameRank)) or IsAutoRepeatSpell(self.SpellNameRank)) then
1837 if (not self.FlashOn) then
1838 self:AddToFlash();
1839 end
1840 elseif (self.FlashOn) then
1841 self:RemoveFromFlash();
1842 end
1843end
1844function Button:UpdateFlashMacro()
1845 if (self.MacroMode == "spell") then
1846 self:UpdateFlashSpell();
1847 elseif (self.FlashOn) then
1848 self:RemoveFromFlash();
1849 end
1850end
1851function Button:UpdateFlashBonusAction()
1852 local action = self.Widget:GetAttribute("action");
1853 if ((HasOverrideActionBar() or HasVehicleActionBar()) and ((IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action))) then
1854 if (not self.FlashOn) then
1855 self:AddToFlash();
1856 end
1857 elseif (self.FlashOn) then
1858 self:RemoveFromFlash();
1859 end
1860end
1861function Button:AddToFlash()
1862 Util.AddToFlash(self);
1863 self.FlashOn = true;
1864end
1865function Button:RemoveFromFlash()
1866 Util.RemoveFromFlash(self);
1867 self.FlashOn = false;
1868 self.WFlashTexture:Hide();
1869end
1870
1871function Button:FlashShow()
1872 self.WFlashTexture:Show();
1873end
1874
1875function Button:FlashHide()
1876 self.WFlashTexture:Hide();
1877end
1878
1879
1880
1881
1882
1883--[[------------------------------------------------------------------------
1884 Range Timer functions
1885--------------------------------------------------------------------------]]
1886function Button:UpdateRangeTimer()
1887
1888end
1889function Button:UpdateRangeTimerSpell()
1890 if (IsSpellInRange(self.SpellNameRank, self.Target)) then
1891 if (not self.RangeTimerOn) then
1892 self:AddToRangeTimer();
1893 end
1894 elseif (self.RangeTimerOn) then
1895 self:RemoveFromRangeTimer();
1896 end
1897end
1898function Button:UpdateRangeTimerItem()
1899 if (IsItemInRange(self.ItemId, self.Target)) then
1900 if (not self.RangeTimerOn) then
1901 self:AddToRangeTimer();
1902 end
1903 elseif (self.RangeTimerOn) then
1904 self:RemoveFromRangeTimer();
1905 end
1906end
1907function Button:UpdateRangeTimerMacro()
1908 if (self.MacroMode == "spell") then
1909 self:UpdateRangeTimerSpell();
1910 elseif (self.MacroMode == "item") then
1911 self:UpdateRangeTimerItem();
1912 elseif (self.RangeTimerOn) then
1913 self:RemoveFromRangeTimer();
1914 end
1915end
1916function Button:UpdateRangeTimerBonusAction()
1917 local action = self.Widget:GetAttribute("action");
1918 if ((HasOverrideActionBar() or HasVehicleActionBar()) and IsActionInRange(action)) then
1919 if (not self.RangeTimerOn) then
1920 self:AddToRangeTimer();
1921 end
1922 elseif (self.RangeTimerOn) then
1923 self:RemoveFromRangeTimer();
1924 end
1925end
1926
1927function Button:AddToRangeTimer()
1928 Util.AddToRangeTimer(self);
1929 self.RangeTimerOn = true;
1930 if (self.WHotKey:GetText() == RANGE_INDICATOR) then
1931 self.WHotKey:Show();
1932 end
1933 self:CheckRangeTimer();
1934end
1935function Button:RemoveFromRangeTimer()
1936 Util.RemoveFromRangeTimer(self);
1937 self.RangeTimerOn = false;
1938 if (self.WHotKey:GetText() == RANGE_INDICATOR) then
1939 self.WHotKey:Hide();
1940 else
1941 self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
1942 end
1943end
1944
1945function Button:CheckRangeTimerSpell()
1946 if (IsSpellInRange(self.SpellNameRank, self.Target) == 1) then
1947 self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
1948 else
1949 self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
1950 end
1951end
1952function Button:CheckRangeTimerItem()
1953 if (IsItemInRange(self.ItemId, self.Target) == 1) then
1954 self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
1955 else
1956 self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
1957 end
1958end
1959function Button:CheckRangeTimerMacro()
1960 if (self.MacroMode == "spell") then
1961 self:CheckRangeTimerSpell();
1962 elseif (self.MacroMode == "item") then
1963 self:CheckRangeTimerItem();
1964 else
1965 self:RemoveFromRangeTimer();
1966 end
1967end
1968function Button:CheckRangeTimerBonusAction()
1969 local action = self.Widget:GetAttribute("action");
1970 if (IsActionInRange(action) == 1) then
1971 self.WHotKey:SetVertexColor(0.6, 0.6, 0.6);
1972 else
1973 self.WHotKey:SetVertexColor(1.0, 0.1, 0.1);
1974 end
1975end
1976
1977
1978
1979
1980--[[--------------------------------------------------------------------------
1981
1982----------------------------------------------------------------------------]]
1983
1984--[[
1985 Make sure the Macro is up to date
1986--]]
1987function Button:RefreshMacro()
1988 if (InCombatLockdown()) then
1989 return;
1990 end
1991 if (self.Mode == "macro") then
1992 local TrimBody = strtrim(self.MacroBody or '');
1993 local AccMacros, CharMacros = GetNumMacros();
1994 local BodyIndex = 0;
1995
1996 --Shallow Checking - Full Affinity
1997 local Name, Icon, Body = GetMacroInfo(self.MacroIndex);
1998 if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
1999 self:SetCommandMacro(self.MacroIndex);
2000 self:FullRefresh();
2001 return;
2002 end
2003
2004 if (Util.IncBetween(self.MacroIndex - 1, 1, AccMacros) or Util.IncBetween(self.MacroIndex - 1, MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros)) then
2005 Name, Icon, Body = GetMacroInfo(self.MacroIndex - 1);
2006 if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
2007 self:SetCommandMacro(self.MacroIndex - 1);
2008 self:FullRefresh();
2009 return;
2010 end
2011 end
2012
2013 if (Util.IncBetween(self.MacroIndex + 1, 1, AccMacros) or Util.IncBetween(self.MacroIndex + 1, MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros)) then
2014 Name, Icon, Body = GetMacroInfo(self.MacroIndex + 1);
2015 if (TrimBody == strtrim(Body or '') and self.MacroName == Name) then
2016 self:SetCommandMacro(self.MacroIndex + 1);
2017 self:FullRefresh();
2018 return;
2019 end
2020 end
2021
2022 --Scan Checking - Full Affinity
2023 for i = 1, AccMacros do
2024 Name, Icon, Body = GetMacroInfo(i);
2025 Body = strtrim(Body or '');
2026 if (TrimBody == Body and self.MacroName == Name) then
2027 self:SetCommandMacro(i);
2028 self:FullRefresh();
2029 return;
2030 end
2031
2032 if (TrimBody == Body and Body ~= nil and Body ~= "") then
2033 BodyIndex = i;
2034 end
2035 end
2036 for i = MAX_ACCOUNT_MACROS + 1, MAX_ACCOUNT_MACROS + CharMacros do
2037 Name, Icon, Body = GetMacroInfo(i);
2038 Body = strtrim(Body or '');
2039 if (TrimBody == Body and self.MacroName == Name) then
2040 self:SetCommandMacro(i);
2041 self:FullRefresh();
2042 return;
2043 end
2044
2045 if (TrimBody == Body and Body ~= nil and Body ~= "") then
2046 BodyIndex = i;
2047 end
2048 end
2049
2050 if (not Util.MacroDeleted) then
2051 --Full Scan - Body Affinity
2052 if (BodyIndex ~= 0) then
2053 self:SetCommandMacro(BodyIndex);
2054 self:FullRefresh();
2055 return;
2056 end
2057
2058 --Low Scan - Name Affinity (the macro should not have moved if the body changed)
2059 Name = GetMacroInfo(self.MacroIndex);
2060 if (self.MacroName == Name) then
2061 self:SetCommandMacro(self.MacroIndex);
2062 self:FullRefresh();
2063 return;
2064 end
2065 end
2066
2067 --Not Found - Clear Macro?
2068 if (ButtonForgeGlobalSettings["RemoveMissingMacros"] and Util.MacroCheckDelayComplete) then
2069 self:ClearCommand();
2070 self:FullRefresh();
2071 end
2072 end
2073end
2074
2075
2076--[[
2077
2078--]]
2079function Button:PromoteSpell()
2080 if (InCombatLockdown()) then
2081 return;
2082 end
2083 --[[
2084 if (self.Mode == "spell") then
2085 local Name, Rank = GetSpellInfo(self.SpellName); --This will actually retrieve for the highest rank of the spell
2086 if (Name) then
2087 if (Util.LookupNewSpellIndex(Name.."("..Rank..")")) then
2088 if (strfind(Rank, Util.GetLocaleString("SpellRank"), 1, true) and strfind(self.SpellNameRank, Util.GetLocaleString("SpellRank"), 1, true)) then
2089 if (Name.."("..Rank..")" ~= self.SpellNameRank) then
2090 self:SetCommandSpell(Util.LookupNewSpellIndex(Name.."("..Rank..")")); --It is important to note that to get here we have a valid spell
2091 self:FullRefresh();
2092 end
2093 end
2094 end
2095 end
2096 end]]
2097end
2098function Button:RefreshSpell()
2099 --in the case of a spell refresh we just need to make sure the texture reflects its current status
2100 if (self.Mode == "spell") then
2101 self.Texture = GetSpellTexture(self.SpellId) or "Interface/Icons/INV_Misc_QuestionMark";
2102 self:DisplayActive();
2103 end
2104end
2105
2106function Button:RefreshBattlePet()
2107 if (self.Mode == "battlepet") then
2108 if (self.BattlePetId == Const.SUMMON_RANDOM_FAVORITE_BATTLE_PET_ID) then
2109 self.Texture = Const.SUMMON_RANDOM_FAVORITE_BATTLE_PET_TEXTURE;
2110 else
2111 self.Texture = select(9, C_PetJournal.GetPetInfoByPetID(self.BattlePetId));
2112 end
2113 self.Texture = self.Texture or "Interface/Icons/INV_Misc_QuestionMark";
2114 self:DisplayActive();
2115 end
2116end
2117
2118function Button:RefreshCompanion()
2119 if (InCombatLockdown()) then
2120 return;
2121 end
2122 if (self.Mode == "companion") then
2123 local Type, Index = Util.LookupCompanion(self.CompanionName);
2124 if (Type == nil) then
2125 self:ClearCommand();
2126 self:FullRefresh();
2127 return;
2128 end
2129 if (Index ~= self.CompanionIndex) then
2130 self:SetCommandCompanion(Index, Type);
2131 self:FullRefresh();
2132 end
2133 end
2134end
2135
2136function Button:RefreshEquipmentSet()
2137 if (InCombatLockdown()) then
2138 return;
2139 end
2140 if (self.Mode == "equipmentset") then
2141 local Index = Util.LookupEquipmentSetIndex(self.EquipmentSetId);
2142
2143 if (Index == nil) then
2144 -- This equip set is gone so clear it from the button
2145 return self:ClearCommand();
2146 end
2147 local TextureName = select(2, C_EquipmentSet.GetEquipmentSetInfo(Index));
2148 if (TextureName) then
2149 self.Texture = TextureName;
2150 self:DisplayActive();
2151 else
2152 self:ClearCommand();
2153 end
2154 end
2155end
2156
2157
2158--Copied and adapted from Blizz's coding (too bad they Assume there is an action associated with the button!!!)
2159--This is currently coded to always be up... this will probably need to be adaptable down the track
2160function Button:UpdateFlyout()
2161 local Widget = self.Widget;
2162 if (self.Mode == "flyout") then
2163 -- Update border and determine arrow position
2164 local arrowDistance;
2165 if (SpellFlyout:GetParent() == Widget) then
2166 -- SpellFlyout.isActionBar = false;
2167 end
2168 if ((SpellFlyout and SpellFlyout:IsShown() and SpellFlyout:GetParent() == Widget) or GetMouseFocus() == Widget) then
2169 Widget.FlyoutBorder:Show();
2170 Widget.FlyoutBorderShadow:Show();
2171 arrowDistance = 5;
2172 else
2173 Widget.FlyoutBorder:Hide();
2174 Widget.FlyoutBorderShadow:Hide();
2175 arrowDistance = 2;
2176 end
2177
2178 -- Update arrow
2179 Widget.FlyoutArrow:Show();
2180 Widget.FlyoutArrow:ClearAllPoints();
2181 --if (self:GetParent() == MultiBarRight or self:GetParent() == MultiBarLeft) then
2182 --self.FlyoutArrow:SetPoint("LEFT", self, "LEFT", -arrowDistance, 0);
2183 --SetClampedTextureRotation(self.FlyoutArrow, 270);
2184 --else
2185 Widget.FlyoutArrow:SetPoint("TOP", Widget, "TOP", 0, arrowDistance);
2186 SetClampedTextureRotation(Widget.FlyoutArrow, 0);
2187 --end
2188 else
2189 Widget.FlyoutBorder:Hide();
2190 Widget.FlyoutBorderShadow:Hide();
2191 Widget.FlyoutArrow:Hide();
2192 end
2193end
2194
2195
2196function Button:UpdateGlow()
2197 if ((self.Mode == "spell" or (self.MacroMode == "spell" and self.Mode == "macro")) and Util.GlowSpells[self.SpellName]) then
2198 ActionButton_ShowOverlayGlow(self.Widget);
2199 else
2200 ActionButton_HideOverlayGlow(self.Widget);
2201 end
2202end
2203
2204--hooksecurefunc("IsSpellOverlayed", print);
2205--[[
2206-- Empty functions
2207-- ]]
2208function Button:Empty()
2209
2210end