WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   (Classic) Modifying the Quest Watch Frame (https://www.wowinterface.com/forums/showthread.php?t=58184)

Tair 08-31-20 08:09 PM

(Classic) Modifying the Quest Watch Frame
 
Hi everyone!

I've recently begun exploring writing my own simple addons. I have a decent beginner's understanding of how to create new functions with an addon, but I'm having a difficult time understanding how to best modify/override existing Blizzard frames.

As an example, I'd like to make some minor changes the Quest Watch frame in Classic. Simple cosmetic modifications like adjusting the fonts, text alignment, etc.

I've found the Blizzard function that I believe controls the things I want to modify, which is QuestWatch_Update(). Here's a segment of code from that function:

Code:

for j=1, numObjectives do
        text, type, finished = GetQuestLogLeaderBoard(j, questIndex);
        watchText = _G["QuestWatchLine"..watchTextIndex];
        -- Set Objective text
        watchText:SetText(" - "..text);
        -- Color the objectives
        if ( finished ) then
                watchText:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
                objectivesCompleted = objectivesCompleted + 1;
        else
                watchText:SetTextColor(0.8, 0.8, 0.8);
        end
        tempWidth = watchText:GetWidth();
        if ( tempWidth > questWatchMaxWidth ) then
                questWatchMaxWidth = tempWidth;
        end
        watchText:SetPoint("TOPLEFT", "QuestWatchLine"..(watchTextIndex - 1), "BOTTOMLEFT", 0, 0);
        watchText:Show();
        watchTextIndex = watchTextIndex + 1;
end


I'm looking for some help with understanding the correct way to reference/alias/override this code to, for example, get rid of the hyphen in front of a tracked objective:

Code:

-- original
watchText:SetText(" - "..text);
-- override
watchText:SetText(text);

I'd be grateful if anyone could point me in the right direction.

Thanks!

SDPhantom 08-31-20 08:52 PM

I would innately follow what the original function did, cutting out everything else that's irrelevant to what you want to change.

In response to your example, this would hook the original function to run afterward and change the text of the objectives to remove the prepended dash.
Lua Code:
  1. hooksecurefunc("QuestWatch_Update",function()
  2.     local questidx;
  3.     local lineidx=1;
  4.     local numobjectives;
  5.  
  6.     for i=1,GetNumQuestWatches() do
  7.         questidx=GetQuestIndexForWatch(i);
  8.         if questidx then
  9.             numobjectives=GetNumQuestLeaderBoards(questidx);
  10.             if numobjectives>0 then
  11.                 lineidx=lineidx+1;--    Iterate past title header
  12.                 for j=1,numobjectives do
  13.                     local textobj=_G["QuestWatchLine"..lineidx];
  14.                     if not textobj then return; end--   This check isn't in the original function and it will throw an error if it runs out of these text objects
  15.  
  16.                     local objective=GetQuestLogLeaderBoard(j,questidx);
  17.                     textobj:SetText(objective);
  18.  
  19.                     lineidx=lineidx+1;--    Iterate to next line
  20.                 end
  21.             end
  22.         end
  23.     end
  24. end);

Tair 08-31-20 09:33 PM

Thank you for this! I'm going to work on this the next time I have the chance, but I didn't want to delay in thanking you. I appreciate it.

Tair 09-01-20 10:20 AM

Okay, thanks again for that head start, SDPhantom. I used your demo as a guide and put together a hook that covers just about everything I wanted to do:

lua Code:
  1. hooksecurefunc("QuestWatch_Update",function()
  2.     local questIndex;
  3.     local watchTextIndex = 1;
  4.     local numObjectives;
  5.     local watchText;
  6.  
  7.     for i=1, GetNumQuestWatches() do
  8.         local questIndex = GetQuestIndexForWatch(i);
  9.         if (questIndex) then
  10.             numObjectives = GetNumQuestLeaderBoards(questIndex);
  11.             -- Quest title
  12.             if ( numObjectives > 0 ) then
  13.                 watchText = _G["QuestWatchLine"..watchTextIndex];
  14.                 -- Font
  15.                 watchText:SetFont("Fonts\\FRIZQT__.TTF", 15, "OUTLINE");
  16.                 watchText:SetShadowColor(0,0,0,0);
  17.                 watchText:SetAlpha(0.85);
  18.                 -- Adjust padding between quests
  19.                 if ( watchTextIndex > 1 ) then
  20.                     watchText:SetPoint("TOPLEFT", "QuestWatchLine"..(watchTextIndex - 1), "BOTTOMLEFT", 0, -12);
  21.                 end
  22.                 watchTextIndex = watchTextIndex + 1;
  23.             end
  24.             -- Quest objectives
  25.             for j=1, numObjectives do
  26.                 text = GetQuestLogLeaderBoard(j, questIndex);
  27.                 watchText = _G["QuestWatchLine"..watchTextIndex];
  28.                 watchText:SetText(text);
  29.                 -- Font
  30.                 watchText:SetFont("Fonts\\FRIZQT__.TTF", 13, "OUTLINE");
  31.                 watchText:SetShadowColor(0,0,0,0);
  32.                 watchText:SetAlpha(0.85);
  33.                 -- Adjust padding between objectives
  34.                 watchText:SetPoint("TOPLEFT", "QuestWatchLine"..(watchTextIndex - 1), "BOTTOMLEFT", 0, -4);
  35.                 watchTextIndex = watchTextIndex + 1;
  36.             end
  37.         end
  38.     end

And the result:



One question—the :SetJustifyH("RIGHT") parameter (not included in the above code) doesn't affect the quest titles or objectives. I'm thinking this could be due to the existing :SetPoint parameters that are used to position the text.

Is it possible to use :SetJustifyH or another method to right-align the titles and objectives without breaking the layout?

Thanks!

Edit: I had some success with getting right-aligned titles and objectives by adjusting the SetPoint parameters:

Lua Code:
  1. hooksecurefunc("QuestWatch_Update",function()
  2.     local questIndex;
  3.     local watchTextIndex = 1;
  4.     local numObjectives;
  5.     local watchText;
  6.  
  7.     for i=1, GetNumQuestWatches() do
  8.         local questIndex = GetQuestIndexForWatch(i);
  9.         if (questIndex) then
  10.             numObjectives = GetNumQuestLeaderBoards(questIndex);
  11.             -- Quest title
  12.             if ( numObjectives > 0 ) then
  13.                 watchText = _G["QuestWatchLine"..watchTextIndex];
  14.                 -- Font
  15.                 watchText:SetFont("Fonts\\FRIZQT__.TTF", 15, "OUTLINE");
  16.                 watchText:SetShadowColor(0,0,0,0);
  17.                 watchText:SetAlpha(0.85);
  18.                 -- Positioning
  19.                 watchText:ClearAllPoints();
  20.                 watchText:SetPoint("TOPRIGHT", QuestWatchFrame, "TOPRIGHT", -15, 0)
  21.                 -- Adjust padding between quests
  22.                 if ( watchTextIndex > 1 ) then
  23.                     watchText:ClearAllPoints();
  24.                     watchText:SetPoint("TOPRIGHT", "QuestWatchLine"..(watchTextIndex - 1), "TOPRIGHT", 0, -30)
  25.                 end
  26.                 watchTextIndex = watchTextIndex + 1;
  27.             end
  28.             -- Quest objectives
  29.             for j=1, numObjectives do
  30.                 text = GetQuestLogLeaderBoard(j, questIndex);
  31.                 watchText = _G["QuestWatchLine"..watchTextIndex];
  32.                 watchText:SetText(text);
  33.                 -- Font
  34.                 watchText:SetFont("Fonts\\FRIZQT__.TTF", 13, "OUTLINE");
  35.                 watchText:SetShadowColor(0,0,0,0);
  36.                 watchText:SetAlpha(0.85);
  37.                 -- Adjust padding between objectives
  38.                 watchText:ClearAllPoints();
  39.                 watchText:SetPoint("TOPRIGHT", "QuestWatchLine"..(watchTextIndex - 1), "TOPRIGHT", 0, -18);
  40.                 watchTextIndex = watchTextIndex + 1;
  41.             end
  42.         end
  43.     end
  44. end);

Thanks again for setting me on the right path.

SDPhantom 09-01-20 08:46 PM

:SetJustifyH() aligns text within the object's boundaries. Since no width or opposing points (left and right) are defined, it's automatically cropped to the size of the text contained. One issue I see is the width of the entire frame derives off calculations that depend on this behavior. The original function also calls UIParent's frame position manager, which means it may be susceptible to taint.

This series of setbacks may be why many UI addons opt to disable Blizzard's built-in tracker and build their own from scratch.

Tair 09-01-20 08:54 PM

Thanks for the additional info. I was able to knock out everything I wanted to accomplish thanks to your guidance. I appreciate the pointers!


All times are GMT -6. The time now is 10:16 PM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI