WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   AddOn Help/Support (https://www.wowinterface.com/forums/forumdisplay.php?f=3)
-   -   First Button Hook Attempt (https://www.wowinterface.com/forums/showthread.php?t=59843)

Codger 04-02-24 03:51 PM

First Button Hook Attempt
 
This adds a button next to the quest "Accept" button labeled "Accept Track". When pressed the quest is accepted and quest tracking is turned on. It seems to be working ok, but thought I would put it here for review and see if there was something different I should have done.

AcceptAndTrack.toc
Lua Code:
  1. ## Interface: 100206
  2. ## Title: Accept And Track
  3. ## Notes: Adds an 'Accept and Track' button to quest frames.
  4. ## Author: Codger
  5. ## Version: 10.2.6
  6. AcceptAndTrack.lua

AcceptAndTrack.lua
Lua Code:
  1. local function AcceptAndTrackQuest()
  2.     AcceptQuest();
  3.  
  4.     C_Timer.After(1, function() -- Delay to ensure the quest log is updated
  5.         local questID = GetQuestID();
  6.         if questID and not C_QuestLog.GetQuestWatchType(questID) then
  7.             C_QuestLog.AddQuestWatch(questID, Enum.QuestWatchType.Automatic);
  8.             -- No need to manually update the objective tracker anymore,
  9.             -- as the quest watch system handles it.
  10.         end
  11.     end)
  12. end
  13.  
  14. local function CreateButton()
  15.     if not QuestFrameAcceptButton then return end -- Ensures the Accept button is loaded
  16.  
  17.     local trackButton = CreateFrame("Button", "AcceptAndTrackButton", QuestFrame, "UIPanelButtonTemplate")
  18.     trackButton:SetSize(120, 22) -- Button size
  19.     trackButton:SetText("Accept And Track")
  20.     trackButton:SetPoint("TOPRIGHT", QuestFrameAcceptButton, "TOPRIGHT", 150, 0) -- Adjusted positioning
  21.     trackButton:SetScript("OnClick", AcceptAndTrackQuest)
  22.     trackButton:SetShown(QuestFrame:IsShown())
  23.  
  24.     -- Debug print to chat to confirm the button was created
  25.     print("AcceptAndTrack button created.")
  26. end
  27.  
  28. -- Delay button creation to ensure the QuestFrame is fully loaded
  29. C_Timer.After(2, CreateButton)
  30.  
  31. QuestFrame:HookScript("OnShow", function() if AcceptAndTrackButton then AcceptAndTrackButton:SetShown(true) end end)
  32. QuestFrame:HookScript("OnHide", function() if AcceptAndTrackButton then AcceptAndTrackButton:SetShown(false) end end)

SDPhantom 04-02-24 06:34 PM

  • Unless you're hooking into a Blizzard LoD "addon", the UI code is already loaded before yours. There's no need to delay creating your button.
  • Unless the inherited template requires it, frame names are optional. This ends up creating a global with the name of your frame. This can introduce name collisions when you have a generic name like "AcceptAndTrackButton".
  • Manually calling show/hide depending on parent visibility is redundant as children will never show when the parent is hidden.
  • Calling GetQuestID() after AcceptQuest() can have unpredictable results as it's only supposed to be valid while the quest detail is shown.
  • Using a time delay to set your tracking creates a race condition for the server to respond that you have successfully accepted a quest. It's better to respond to the event signifying this instead.

With these in mind, here's with the changes I've made.
Lua Code:
  1. local TrackButton = CreateFrame("Button", nil, QuestFrameDetailPanel, "UIPanelButtonTemplate");
  2. TrackButton:SetSize(120, 22);
  3. TrackButton:SetText("Accept And Track");
  4. TrackButton:SetPoint("BOTTOMLEFT", 113, 4);
  5. TrackButton:SetScript("OnClick", function(self)
  6.     self.QuestID = GetQuestID();
  7.     AcceptQuest();
  8. end);
  9.  
  10. TrackButton:RegisterEvent("QUEST_ACCEPTED");
  11. TrackButton:SetScript("OnEvent", function(self, event, questid)
  12.     if questid == self.QuestID then
  13.         if not C_QuestLog.GetQuestWatchType(questid) then
  14.             C_QuestLog.AddQuestWatch(questid, Enum.QuestWatchType.Automatic);
  15.         end
  16.         self.QuestID = nil;
  17.     end
  18. end);

Codger 04-02-24 06:49 PM

Thank you
 
I really appreciate the help!!

Codger 04-03-24 11:16 PM

Persistence problem with the button
 
I noticed that the button is showing up on the frame when the quest is being turned in.
i've tried a couple ways of hiding the button with no luck.
I tried setting IsShown to the same state as the accept button but the accept button is always reporting that shown is true. Then I tried to add another event QUEST_COMPLETE but that doesn't seem to help either. Although it seems obvious, I'm a bit confused as to how the show/hide button code works.
I've looked at events with /etrace to see if there was another event I could use but no luck.
I used /framestack to examine the buttons but so far I haven't found anything.

SDPhantom 04-04-24 02:28 AM

I swapped the button's parent to QuestFrameDetailPanel. That should do the trick.

Codger 04-04-24 01:10 PM

Works great
 
That works.
I opened up /framestack to understand the difference.
Thanks for the help.


All times are GMT -6. The time now is 07:49 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI