Thread Tools Display Modes
08-31-20, 08:09 PM   #1
Tair
A Deviate Faerie Dragon
Join Date: Aug 2020
Posts: 10
(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!
  Reply With Quote
08-31-20, 08:52 PM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
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);
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 08-31-20 at 09:00 PM.
  Reply With Quote
08-31-20, 09:33 PM   #3
Tair
A Deviate Faerie Dragon
Join Date: Aug 2020
Posts: 10
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.
  Reply With Quote
09-01-20, 10:20 AM   #4
Tair
A Deviate Faerie Dragon
Join Date: Aug 2020
Posts: 10
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.

Last edited by Tair : 09-01-20 at 08:34 PM.
  Reply With Quote
09-01-20, 08:46 PM   #5
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
: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.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
09-01-20, 08:54 PM   #6
Tair
A Deviate Faerie Dragon
Join Date: Aug 2020
Posts: 10
Thanks for the additional info. I was able to knock out everything I wanted to accomplish thanks to your guidance. I appreciate the pointers!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » (Classic) Modifying the Quest Watch Frame

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off