fix(tracker): make the objective marker button usable at larger sizes
The button shared the quest gutter with the collapse button, the quest item buttons and the zone header text, so anything past the default size was clipped by the tracker edge or drawn on top of its neighbours. Give it a gutter of its own instead. GetSuperTrackMarginReserve feeds questMarginLeft, which every layout and width calculation already builds on, and the quest item buttons and zone labels are shifted by the same amount. The button then anchors flush left of the line and the tracker widens to match, so nothing overlaps at any size. Raise the size cap to 70 now that it fits, and drop the hover tooltip. Also stop relying on the SetSuperTrackedQuestID hook as the only source of truth. It never fires while the player is a ghost -- the corpse arrow takes over the marker -- and it has not fired yet on a login or reload, which left the tracker with no idea what was tracked in both cases. The client is now asked directly: the watch frame POI buttons flag their own selection, the map pins say it through their art (the selected variant sits half a texture above the normal one), and the quest log selection answers for the login window when no pin is styled yet. Selection calls are hooked for the same reason, so clicks repaint while dead, and the requests are coalesced because callers select a quest log entry and restore the previous one a line later.
This commit is contained in:
@@ -116,10 +116,6 @@ local trackerOptionsLocales = {
|
|||||||
["enUS"] = true,
|
["enUS"] = true,
|
||||||
},
|
},
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
["Point the objective marker at this quest"] = {
|
|
||||||
["enUS"] = true,
|
|
||||||
},
|
|
||||||
---------------------------------------------------------
|
|
||||||
["Auto Minimize Completed Quests"] = {
|
["Auto Minimize Completed Quests"] = {
|
||||||
["ptBR"] = "Minimizar missões concluídas",
|
["ptBR"] = "Minimizar missões concluídas",
|
||||||
["ruRU"] = "Свернуть выполненные",
|
["ruRU"] = "Свернуть выполненные",
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ function QuestieOptions.tabs.tracker:Initialize()
|
|||||||
hidden = function() return not TrackerUtils:IsSuperTrackAvailable() end,
|
hidden = function() return not TrackerUtils:IsSuperTrackAvailable() end,
|
||||||
disabled = function() return (not Questie.db.profile.trackerEnabled) or (not Questie.db.profile.trackerShowSuperTrackButton) end,
|
disabled = function() return (not Questie.db.profile.trackerEnabled) or (not Questie.db.profile.trackerShowSuperTrackButton) end,
|
||||||
min = 8,
|
min = 8,
|
||||||
max = 32,
|
max = 70,
|
||||||
step = 1,
|
step = 1,
|
||||||
get = function() return Questie.db.profile.trackerSuperTrackButtonSize end,
|
get = function() return Questie.db.profile.trackerSuperTrackButtonSize end,
|
||||||
set = function(_, value)
|
set = function(_, value)
|
||||||
|
|||||||
@@ -845,7 +845,11 @@ function QuestieTracker:Update()
|
|||||||
-- Setup local QuestieTracker:Update vars
|
-- Setup local QuestieTracker:Update vars
|
||||||
local trackerFontSizeZone = Questie.db.profile.trackerFontSizeZone
|
local trackerFontSizeZone = Questie.db.profile.trackerFontSizeZone
|
||||||
local trackerFontSizeQuest = Questie.db.profile.trackerFontSizeQuest
|
local trackerFontSizeQuest = Questie.db.profile.trackerFontSizeQuest
|
||||||
local questMarginLeft = (trackerMarginLeft + trackerMarginRight) - (18 - trackerFontSizeQuest)
|
-- The supertrack button sits at the very left of a quest line, so the whole quest list is
|
||||||
|
-- indented past it: otherwise it is clipped by the tracker's left edge and collides with the
|
||||||
|
-- quest item buttons, which share that gutter.
|
||||||
|
local superTrackMarginLeft = TrackerLinePool.GetSuperTrackMarginReserve()
|
||||||
|
local questMarginLeft = (trackerMarginLeft + trackerMarginRight) - (18 - trackerFontSizeQuest) + superTrackMarginLeft
|
||||||
local objectiveMarginLeft = questMarginLeft + trackerFontSizeQuest
|
local objectiveMarginLeft = questMarginLeft + trackerFontSizeQuest
|
||||||
local questItemButtonSize = 12 + trackerFontSizeQuest
|
local questItemButtonSize = 12 + trackerFontSizeQuest
|
||||||
local objectiveColor = Questie.db.profile.trackerColorObjectives
|
local objectiveColor = Questie.db.profile.trackerColorObjectives
|
||||||
@@ -895,9 +899,11 @@ function QuestieTracker:Update()
|
|||||||
line.criteriaMark:Hide()
|
line.criteriaMark:Hide()
|
||||||
line.playButton:Hide()
|
line.playButton:Hide()
|
||||||
|
|
||||||
-- Setup Zone Label
|
-- Setup Zone Label. Indented like the quest lines below it: the supertrack
|
||||||
|
-- buttons overflow their own line at larger sizes, and the zone label is the
|
||||||
|
-- only text that would otherwise share that gutter with them.
|
||||||
line.label:ClearAllPoints()
|
line.label:ClearAllPoints()
|
||||||
line.label:SetPoint("TOPLEFT", line, "TOPLEFT", 0, 0)
|
line.label:SetPoint("TOPLEFT", line, "TOPLEFT", superTrackMarginLeft, 0)
|
||||||
|
|
||||||
-- Set Zone Title and default Min/Max states
|
-- Set Zone Title and default Min/Max states
|
||||||
if Questie.db.char.collapsedZones[zoneName] then
|
if Questie.db.char.collapsedZones[zoneName] then
|
||||||
@@ -924,19 +930,19 @@ function QuestieTracker:Update()
|
|||||||
|
|
||||||
-- Check and measure Zone Label text width and update tracker width
|
-- Check and measure Zone Label text width and update tracker width
|
||||||
QuestieTracker:UpdateWidth(line.label:GetStringWidth() + trackerMarginLeft +
|
QuestieTracker:UpdateWidth(line.label:GetStringWidth() + trackerMarginLeft +
|
||||||
trackerMarginRight)
|
superTrackMarginLeft + trackerMarginRight)
|
||||||
|
|
||||||
-- Set Zone Label and Line widths
|
-- Set Zone Label and Line widths
|
||||||
line.label:SetWidth(trackerBaseFrame:GetWidth() - trackerMarginLeft - trackerMarginRight)
|
line.label:SetWidth(trackerBaseFrame:GetWidth() - trackerMarginLeft - superTrackMarginLeft - trackerMarginRight)
|
||||||
line:SetWidth(line.label:GetWidth())
|
line:SetWidth(line.label:GetWidth() + superTrackMarginLeft)
|
||||||
|
|
||||||
-- Compare largest text Label in the tracker with current Label, then save widest width
|
-- Compare largest text Label in the tracker with current Label, then save widest width
|
||||||
trackerLineWidth = math.max(trackerLineWidth,
|
trackerLineWidth = math.max(trackerLineWidth,
|
||||||
line.label:GetStringWidth() + trackerMarginLeft)
|
line.label:GetStringWidth() + trackerMarginLeft + superTrackMarginLeft)
|
||||||
|
|
||||||
-- Setup Min/Max Button
|
-- Setup Min/Max Button
|
||||||
line.expandZone:ClearAllPoints()
|
line.expandZone:ClearAllPoints()
|
||||||
line.expandZone:SetPoint("TOPLEFT", line, "TOPLEFT", 0, 0)
|
line.expandZone:SetPoint("TOPLEFT", line, "TOPLEFT", superTrackMarginLeft, 0)
|
||||||
line.expandZone:SetWidth(line.label:GetWidth())
|
line.expandZone:SetWidth(line.label:GetWidth())
|
||||||
line.expandZone:SetHeight(line.label:GetHeight())
|
line.expandZone:SetHeight(line.label:GetHeight())
|
||||||
line.expandZone:Show()
|
line.expandZone:Show()
|
||||||
@@ -1175,7 +1181,7 @@ function QuestieTracker:Update()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Attach button to Quest Title linePool
|
-- Attach button to Quest Title linePool
|
||||||
button:SetPoint("TOPLEFT", button.line, "TOPLEFT", 0, 0)
|
button:SetPoint("TOPLEFT", button.line, "TOPLEFT", superTrackMarginLeft, 0)
|
||||||
button:SetParent(button.line)
|
button:SetParent(button.line)
|
||||||
button:Show()
|
button:Show()
|
||||||
|
|
||||||
@@ -1283,7 +1289,7 @@ function QuestieTracker:Update()
|
|||||||
|
|
||||||
-- Attach button to Quest Title linePool
|
-- Attach button to Quest Title linePool
|
||||||
altButton:SetPoint("TOPLEFT", altButton.line, "TOPLEFT",
|
altButton:SetPoint("TOPLEFT", altButton.line, "TOPLEFT",
|
||||||
2 + questItemButtonSize, 0)
|
superTrackMarginLeft + 2 + questItemButtonSize, 0)
|
||||||
altButton:SetParent(altButton.line)
|
altButton:SetParent(altButton.line)
|
||||||
altButton:Show()
|
altButton:Show()
|
||||||
|
|
||||||
@@ -1642,9 +1648,9 @@ function QuestieTracker:Update()
|
|||||||
line.criteriaMark:Hide()
|
line.criteriaMark:Hide()
|
||||||
line.playButton:Hide()
|
line.playButton:Hide()
|
||||||
|
|
||||||
-- Setup Zone Label
|
-- Setup Zone Label (indented past the supertrack button gutter, as above)
|
||||||
line.label:ClearAllPoints()
|
line.label:ClearAllPoints()
|
||||||
line.label:SetPoint("TOPLEFT", line, "TOPLEFT", 0, 0)
|
line.label:SetPoint("TOPLEFT", line, "TOPLEFT", superTrackMarginLeft, 0)
|
||||||
|
|
||||||
-- Set Zone Title and Min/Max states
|
-- Set Zone Title and Min/Max states
|
||||||
if Questie.db.char.collapsedZones[zoneName] then
|
if Questie.db.char.collapsedZones[zoneName] then
|
||||||
@@ -1673,15 +1679,15 @@ function QuestieTracker:Update()
|
|||||||
|
|
||||||
-- Check and measure Zone Label text width and update tracker width
|
-- Check and measure Zone Label text width and update tracker width
|
||||||
QuestieTracker:UpdateWidth(line.label:GetStringWidth() + trackerMarginLeft +
|
QuestieTracker:UpdateWidth(line.label:GetStringWidth() + trackerMarginLeft +
|
||||||
trackerMarginRight)
|
superTrackMarginLeft + trackerMarginRight)
|
||||||
|
|
||||||
-- Set Zone Label and Line widths
|
-- Set Zone Label and Line widths
|
||||||
line.label:SetWidth(trackerBaseFrame:GetWidth() - trackerMarginLeft - trackerMarginRight)
|
line.label:SetWidth(trackerBaseFrame:GetWidth() - trackerMarginLeft - superTrackMarginLeft - trackerMarginRight)
|
||||||
line:SetWidth(line.label:GetWidth())
|
line:SetWidth(line.label:GetWidth() + superTrackMarginLeft)
|
||||||
|
|
||||||
-- Compare largest text Label in the tracker with current Label, then save widest width
|
-- Compare largest text Label in the tracker with current Label, then save widest width
|
||||||
trackerLineWidth = math.max(trackerLineWidth,
|
trackerLineWidth = math.max(trackerLineWidth,
|
||||||
line.label:GetStringWidth() + trackerMarginLeft)
|
line.label:GetStringWidth() + trackerMarginLeft + superTrackMarginLeft)
|
||||||
|
|
||||||
-- Setup Min/Max Button
|
-- Setup Min/Max Button
|
||||||
line.expandZone:ClearAllPoints()
|
line.expandZone:ClearAllPoints()
|
||||||
|
|||||||
@@ -62,6 +62,29 @@ local function MirrorPinRegion(destination, source, size, pinSize)
|
|||||||
destination:Show()
|
destination:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- The pin atlases stack the selected (yellow circle, black digits) variant of every cell exactly
|
||||||
|
-- half a texture above the normal one. The client only restyles its pins during the world map's own
|
||||||
|
-- selection pass, which has not run yet right after a login or a reload, so the variant is forced
|
||||||
|
-- here rather than taken on trust from the pin.
|
||||||
|
local function ApplySelectedVariant(texture, selected)
|
||||||
|
local topLeftX, topLeftY, bottomLeftX, bottomLeftY, topRightX, topRightY, bottomRightX, bottomRightY = texture:GetTexCoord()
|
||||||
|
if (not topLeftY) or (not bottomLeftY) or (bottomLeftY - topLeftY) > 0.5 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local offset
|
||||||
|
if selected and topLeftY >= 0.5 then
|
||||||
|
offset = -0.5
|
||||||
|
elseif (not selected) and bottomLeftY <= 0.5 then
|
||||||
|
offset = 0.5
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
texture:SetTexCoord(topLeftX, topLeftY + offset, bottomLeftX, bottomLeftY + offset,
|
||||||
|
topRightX, topRightY + offset, bottomRightX, bottomRightY + offset)
|
||||||
|
end
|
||||||
|
|
||||||
local function GetNumLines(label)
|
local function GetNumLines(label)
|
||||||
if label.GetNumLines then
|
if label.GetNumLines then
|
||||||
return label:GetNumLines()
|
return label:GetNumLines()
|
||||||
@@ -81,6 +104,20 @@ local linePool = {}
|
|||||||
local buttonPool = {}
|
local buttonPool = {}
|
||||||
local lineMarginLeft = 10
|
local lineMarginLeft = 10
|
||||||
|
|
||||||
|
-- Gutter given to the supertrack button, which sits flush with the left edge of a quest line. The
|
||||||
|
-- collapse button, the quest item buttons and the labels are all shifted right by this much, so
|
||||||
|
-- nothing lands on top of it and nothing hangs over the tracker's left edge. Fed into
|
||||||
|
-- questMarginLeft, which every width calculation already builds on, so the tracker widens to match.
|
||||||
|
function TrackerLinePool.GetSuperTrackMarginReserve()
|
||||||
|
if (not Questie.db.profile.trackerShowSuperTrackButton) or (not TrackerUtils:IsSuperTrackAvailable()) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Reserved even for quests whose button is hidden, so the list does not shift around as quests
|
||||||
|
-- come in and out of the supertrackable set.
|
||||||
|
return (Questie.db.profile.trackerSuperTrackButtonSize or 25) + 4
|
||||||
|
end
|
||||||
|
|
||||||
---@param questFrame Frame
|
---@param questFrame Frame
|
||||||
function TrackerLinePool.Initialize(questFrame)
|
function TrackerLinePool.Initialize(questFrame)
|
||||||
local trackerQuestFrame = questFrame
|
local trackerQuestFrame = questFrame
|
||||||
@@ -489,31 +526,33 @@ function TrackerLinePool.Initialize(questFrame)
|
|||||||
-- texture file has to be copied along with the coordinates: completed quests swap in a
|
-- texture file has to be copied along with the coordinates: completed quests swap in a
|
||||||
-- different file for these slots, and coordinates from one file applied to another
|
-- different file for these slots, and coordinates from one file applied to another
|
||||||
-- sample nonsense.
|
-- sample nonsense.
|
||||||
|
local isSuperTracked = TrackerUtils:GetSuperTrackedQuestId() == self.questId
|
||||||
|
|
||||||
local pinTexture = pin.GetNormalTexture and pin:GetNormalTexture()
|
local pinTexture = pin.GetNormalTexture and pin:GetNormalTexture()
|
||||||
if pinTexture then
|
if pinTexture then
|
||||||
local ownTexture = self:GetNormalTexture()
|
local ownTexture = self:GetNormalTexture()
|
||||||
ownTexture:SetTexture(pinTexture:GetTexture())
|
ownTexture:SetTexture(pinTexture:GetTexture())
|
||||||
ownTexture:SetTexCoord(pinTexture:GetTexCoord())
|
ownTexture:SetTexCoord(pinTexture:GetTexCoord())
|
||||||
|
ApplySelectedVariant(ownTexture, isSuperTracked)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pinSize = pin:GetWidth()
|
local pinSize = pin:GetWidth()
|
||||||
MirrorPinRegion(self.number, pin.number, buttonSize, pinSize)
|
MirrorPinRegion(self.number, pin.number, buttonSize, pinSize)
|
||||||
MirrorPinRegion(self.turnin, pin.turnin, buttonSize, pinSize)
|
MirrorPinRegion(self.turnin, pin.turnin, buttonSize, pinSize)
|
||||||
|
if self.number:IsShown() then
|
||||||
-- Sit to the left of whatever already occupies the gutter: the AI_VoiceOver play button
|
ApplySelectedVariant(self.number, isSuperTracked)
|
||||||
-- when that addon is loaded, otherwise the quest collapse button.
|
|
||||||
self:ClearAllPoints()
|
|
||||||
if playButton:IsShown() then
|
|
||||||
self:SetPoint("RIGHT", playButton, "LEFT", -2, 0)
|
|
||||||
elseif line.expandQuest then
|
|
||||||
self:SetPoint("RIGHT", line.expandQuest, "LEFT", -2, 0)
|
|
||||||
else
|
|
||||||
self:SetPoint("RIGHT", line.label, "LEFT", -4, 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The icon itself already shows the selected variant, copied from the pin above; the
|
-- Flush with the left edge of the line, in the gutter GetSuperTrackMarginReserve keeps
|
||||||
-- glow is the one part the pin draws as a separate texture.
|
-- clear. Anchored to the top rather than centred on the line so the button stays level
|
||||||
if TrackerUtils:GetSuperTrackedQuestId() == self.questId then
|
-- with the first row of a quest title that wraps, matching the collapse button.
|
||||||
|
local fontSizeQuest = Questie.db.profile.trackerFontSizeQuest
|
||||||
|
self:ClearAllPoints()
|
||||||
|
self:SetPoint("TOPLEFT", line, "TOPLEFT", 0, (buttonSize - fontSizeQuest) / 2 + 1)
|
||||||
|
|
||||||
|
-- The icon carries the selected variant itself; the glow is the one part the pin draws
|
||||||
|
-- as a separate texture.
|
||||||
|
if isSuperTracked then
|
||||||
self.glow:Show()
|
self.glow:Show()
|
||||||
else
|
else
|
||||||
self.glow:Hide()
|
self.glow:Hide()
|
||||||
@@ -533,16 +572,6 @@ function TrackerLinePool.Initialize(questFrame)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
superTrackButton:SetScript("OnEnter", function(self)
|
|
||||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
|
||||||
GameTooltip:SetText(l10n("Point the objective marker at this quest"), 1, 1, 1)
|
|
||||||
GameTooltip:Show()
|
|
||||||
end)
|
|
||||||
|
|
||||||
superTrackButton:SetScript("OnLeave", function()
|
|
||||||
GameTooltip:Hide()
|
|
||||||
end)
|
|
||||||
|
|
||||||
superTrackButton:Hide()
|
superTrackButton:Hide()
|
||||||
|
|
||||||
line.superTrackButton = superTrackButton
|
line.superTrackButton = superTrackButton
|
||||||
|
|||||||
@@ -1272,16 +1272,40 @@ end
|
|||||||
-- stomps it, so we click the same POI frames the client itself clicks.
|
-- stomps it, so we click the same POI frames the client itself clicks.
|
||||||
local superTrackedQuestId
|
local superTrackedQuestId
|
||||||
local superTrackHooked
|
local superTrackHooked
|
||||||
|
local superTrackRefreshing
|
||||||
|
local superTrackRefreshPending
|
||||||
|
local superTrackEventFrame
|
||||||
|
|
||||||
|
-- Refreshing rebuilds the map's POI frames, which can land back in the very hooks that asked for the
|
||||||
|
-- refresh, so this is the only way the buttons are ever repainted. Requests are also coalesced:
|
||||||
|
-- callers like TrackerQuestTimers select a quest log entry and immediately restore the previous one,
|
||||||
|
-- so reading the selection on the first of those calls would catch a state the client is about to
|
||||||
|
-- undo. Waiting a tick means the burst has settled.
|
||||||
|
local function RefreshSuperTrackButtons()
|
||||||
|
if superTrackRefreshing or superTrackRefreshPending then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
superTrackRefreshPending = true
|
||||||
|
C_Timer.After(0.05, function()
|
||||||
|
superTrackRefreshPending = false
|
||||||
|
superTrackRefreshing = true
|
||||||
|
TrackerLinePool.UpdateSuperTrackButtons()
|
||||||
|
superTrackRefreshing = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
function TrackerUtils:IsSuperTrackAvailable()
|
function TrackerUtils:IsSuperTrackAvailable()
|
||||||
return (C_SuperTrack ~= nil) and ((WorldMapFrame_SelectQuestFrame ~= nil) or (WatchFrameQuestPOI_OnClick ~= nil))
|
return (C_SuperTrack ~= nil) and ((WorldMapFrame_SelectQuestFrame ~= nil) or (WatchFrameQuestPOI_OnClick ~= nil))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Every path that changes the supertracked quest ends up in SetSuperTrackedQuestID -- our own
|
-- Most paths that change the supertracked quest end up in SetSuperTrackedQuestID -- our own button,
|
||||||
-- button, world map pins, the map quest list, the Blizzard tracker, and the automatic re-pick that
|
-- world map pins, the map quest list, the Blizzard tracker, and the automatic re-pick that happens
|
||||||
-- happens when the map switches zone. Hooking it is the only way to know what is supertracked,
|
-- when the map switches zone -- so hooking it stands in for the GetSuperTrackedQuestID getter this
|
||||||
-- since this client dropped the GetSuperTrackedQuestID getter. Caching what we last set would go
|
-- client dropped. It goes quiet while the player is a ghost, though: the corpse arrow takes the
|
||||||
-- stale the moment the player changed it by any other means.
|
-- marker over, so no quest is ever handed to it even though the map keeps selecting one. The quest
|
||||||
|
-- selection itself is therefore hooked as well, and that is what keeps the buttons honest while
|
||||||
|
-- dead. Caching what we last set would go stale the moment the player changed it by other means.
|
||||||
function TrackerUtils:InitSuperTrackHook()
|
function TrackerUtils:InitSuperTrackHook()
|
||||||
if superTrackHooked or (not C_SuperTrack) then
|
if superTrackHooked or (not C_SuperTrack) then
|
||||||
return
|
return
|
||||||
@@ -1291,19 +1315,106 @@ function TrackerUtils:InitSuperTrackHook()
|
|||||||
|
|
||||||
hooksecurefunc(C_SuperTrack, "SetSuperTrackedQuestID", function(questId)
|
hooksecurefunc(C_SuperTrack, "SetSuperTrackedQuestID", function(questId)
|
||||||
superTrackedQuestId = questId
|
superTrackedQuestId = questId
|
||||||
TrackerLinePool.UpdateSuperTrackButtons()
|
RefreshSuperTrackButtons()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if C_SuperTrack.ClearSuperTracker then
|
if C_SuperTrack.ClearSuperTracker then
|
||||||
hooksecurefunc(C_SuperTrack, "ClearSuperTracker", function()
|
hooksecurefunc(C_SuperTrack, "ClearSuperTracker", function()
|
||||||
superTrackedQuestId = nil
|
superTrackedQuestId = nil
|
||||||
TrackerLinePool.UpdateSuperTrackButtons()
|
RefreshSuperTrackButtons()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if WorldMapFrame_SelectQuestFrame then
|
||||||
|
hooksecurefunc("WorldMapFrame_SelectQuestFrame", RefreshSuperTrackButtons)
|
||||||
|
end
|
||||||
|
|
||||||
|
if WatchFrameQuestPOI_OnClick then
|
||||||
|
hooksecurefunc("WatchFrameQuestPOI_OnClick", RefreshSuperTrackButtons)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Everything that supertracks a quest goes through the quest log selection, map or no map, alive
|
||||||
|
-- or dead -- including opening a quest in the quest log window, which no other hook here sees.
|
||||||
|
if SelectQuestLogEntry then
|
||||||
|
hooksecurefunc("SelectQuestLogEntry", RefreshSuperTrackButtons)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Nothing at all fires on a login or a reload: the map has not been touched, so the hooks above
|
||||||
|
-- stay silent and the tracker draws before the client has styled its pins. These events are the
|
||||||
|
-- only prompt to go back and look.
|
||||||
|
superTrackEventFrame = CreateFrame("Frame")
|
||||||
|
superTrackEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
|
superTrackEventFrame:RegisterEvent("PLAYER_UNGHOST")
|
||||||
|
superTrackEventFrame:RegisterEvent("PLAYER_ALIVE")
|
||||||
|
superTrackEventFrame:RegisterEvent("PLAYER_DEAD")
|
||||||
|
superTrackEventFrame:SetScript("OnEvent", function()
|
||||||
|
RefreshSuperTrackButtons()
|
||||||
|
-- The client fills in its POI frames a moment after entering the world, so the immediate
|
||||||
|
-- pass above can still come up empty.
|
||||||
|
C_Timer.After(2, RefreshSuperTrackButtons)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The hook only hears about the changes the client itself makes, and while the player is a ghost the
|
||||||
|
-- floating marker is disabled: selecting a quest then never reaches SetSuperTrackedQuestID, so the
|
||||||
|
-- hook reports nothing after a login or a reload in that state and goes stale after any click. The
|
||||||
|
-- client's own frames still know. Watch frame POI buttons say so outright, and the world map's quest
|
||||||
|
-- frames say it through their art: the atlases stack the selected (yellow) variant of a cell half a
|
||||||
|
-- texture above the normal one, so a pin drawn from the upper half is the supertracked one.
|
||||||
|
local function FindSelectedQuestId()
|
||||||
|
for i = 1, 30 do
|
||||||
|
local firstInRow = _G["poiWatchFrameLines" .. i .. "_1"]
|
||||||
|
if not firstInRow then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
for j = 1, 5 do
|
||||||
|
local poiButton = (j == 1) and firstInRow or _G["poiWatchFrameLines" .. i .. "_" .. j]
|
||||||
|
if not poiButton then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if poiButton.isSelected and poiButton.questId then
|
||||||
|
return poiButton.questId
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for i = 1, 25 do
|
||||||
|
local questFrame = _G["WorldMapQuestFrame" .. i]
|
||||||
|
if not questFrame then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
local pin = questFrame.ownPOI or questFrame.poiIcon
|
||||||
|
local pinTexture = pin and pin.GetNormalTexture and pin:GetNormalTexture()
|
||||||
|
if pinTexture and questFrame.questId then
|
||||||
|
local _, topY = pinTexture:GetTexCoord()
|
||||||
|
if topY and topY < 0.5 then
|
||||||
|
return questFrame.questId
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Right after a login or a reload no pin is styled at all: the client marks them the first time
|
||||||
|
-- the world map is opened. The quest log selection is what it reads when it gets there, so it
|
||||||
|
-- answers for the gap in between.
|
||||||
|
local selection = GetQuestLogSelection and GetQuestLogSelection()
|
||||||
|
if selection and selection > 0 then
|
||||||
|
-- GetQuestIDFromLogIndex, not the raw API: GetQuestLogTitle is the compat wrapper here,
|
||||||
|
-- which normalises the client's 9 return values down to 8.
|
||||||
|
local questId = QuestieCompat.GetQuestIDFromLogIndex(selection)
|
||||||
|
if questId and questId ~= 0 then
|
||||||
|
return questId
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The client is asked before the hook: the hook cannot see a ghost's selection changes at all, so
|
||||||
|
-- its value is the fallback for when no POI frame exists to read (another zone, or frames not built
|
||||||
|
-- yet), not the source of truth.
|
||||||
function TrackerUtils:GetSuperTrackedQuestId()
|
function TrackerUtils:GetSuperTrackedQuestId()
|
||||||
return superTrackedQuestId
|
return FindSelectedQuestId() or superTrackedQuestId
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The world map builds its quest POI frames lazily, so right after login -- or after a zone change
|
-- The world map builds its quest POI frames lazily, so right after login -- or after a zone change
|
||||||
@@ -1414,6 +1525,10 @@ function TrackerUtils:SetSuperTrackedQuest(questId)
|
|||||||
end
|
end
|
||||||
|
|
||||||
clickHandler(frame)
|
clickHandler(frame)
|
||||||
|
|
||||||
|
-- Refresh here rather than leaning on the SetSuperTrackedQuestID hook: it stays silent while the
|
||||||
|
-- player is a ghost, which would leave the button we just clicked looking untouched.
|
||||||
|
RefreshSuperTrackButtons()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user