Files
Questie-X/Modules/Tracker/TrackerLinePool.lua
T
Narcasung 7ecc9016dd feat(tracker): match the client's pin interactions on the marker button
Hover used a Blizzard minimize-button highlight, which read as a red
tint over the pin art and looked nothing like the map. The pins draw
their hover and pressed states from the same UI-QuestPoi-NumberIcons
atlas they draw everything else from, additively blended, so mirror
those cells alongside the ones already being copied.

Add the pressed offset the pins have, nudging the digit or the "?" a
pixel down and right while held, reset on redraw since the pool recycles
buttons and a line can be rebuilt with the mouse still down. Play the
sound the pins play as well: we call WorldMapFrame_SelectQuestFrame
directly, and the sound lives a level above it in WorldMapQuestPOI_OnClick.
2026-07-25 16:31:20 +02:00

1361 lines
54 KiB
Lua

---@class TrackerLinePool
local TrackerLinePool = QuestieLoader:CreateModule("TrackerLinePool")
-------------------------
--Import QuestieTracker modules.
-------------------------
---@type QuestieTracker
local QuestieTracker = QuestieLoader:ImportModule("QuestieTracker")
---@type TrackerBaseFrame
local TrackerBaseFrame = QuestieLoader:ImportModule("TrackerBaseFrame")
---@type TrackerUtils
local TrackerUtils = QuestieLoader:ImportModule("TrackerUtils")
---@type TrackerQuestTimers
local TrackerQuestTimers = QuestieLoader:ImportModule("TrackerQuestTimers")
---@type TrackerMenu
local TrackerMenu = QuestieLoader:ImportModule("TrackerMenu")
---@type TrackerFadeTicker
local TrackerFadeTicker = QuestieLoader:ImportModule("TrackerFadeTicker")
-------------------------
--Import Questie modules.
-------------------------
---@type QuestieLink
local QuestieLink = QuestieLoader:ImportModule("QuestieLink")
---@type QuestieMap
local QuestieMap = QuestieLoader:ImportModule("QuestieMap")
---@type QuestieCombatQueue
local QuestieCombatQueue = QuestieLoader:ImportModule("QuestieCombatQueue")
---@type QuestieDB
local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
---@type QuestieLib
local QuestieLib = QuestieLoader:ImportModule("QuestieLib");
---@type l10n
local l10n = QuestieLoader:ImportModule("l10n")
--- COMPATIBILITY ---
local C_Timer = QuestieCompat.C_Timer
local C_QuestLog = QuestieCompat.C_QuestLog
local GetQuestLogIndexByID = QuestieCompat.GetQuestLogIndexByID
-- Copies one texture region of a quest pin onto our button. The texture file travels with the
-- coordinates because the client swaps files between states, and the region is only shown when the
-- pin itself shows it -- the pin uses "number" for in-progress quests and "turnin" for completed
-- ones, never both.
local function MirrorPinRegion(destination, source, size, pinSize)
if (not source) or (not source:IsShown()) or (not source:GetTexture()) then
destination:Hide()
return
end
-- Regions are not all the size of the pin -- the "?" is drawn larger than a digit -- so scale
-- them by how the pin itself was scaled instead of stretching each one to the button.
local scale = (pinSize and pinSize > 0) and (size / pinSize) or 1
local width = (source:GetWidth() or 0) * scale
local height = (source:GetHeight() or 0) * scale
if width <= 0 or height <= 0 then
width = size
height = size
end
destination:SetWidth(width)
destination:SetHeight(height)
destination:SetTexture(source:GetTexture())
destination:SetTexCoord(source:GetTexCoord())
destination:Show()
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
-- Whole-button states (hover, pressed) rather than the regions drawn inside them, so these fill the
-- button on their own and only need the atlas cell copied across.
local function MirrorPinButtonTexture(destination, source)
if (not destination) or (not source) or (not source.GetTexture) or (not source:GetTexture()) then
return
end
destination:SetTexture(source:GetTexture())
destination:SetTexCoord(source:GetTexCoord())
end
local function GetNumLines(label)
if label.GetNumLines then
return label:GetNumLines()
end
return QuestieCompat.GetNumLines(label)
end
local LibDropDown = QuestieCompat.LibUIDropDownMenu or LibStub:GetLibrary("LibUIDropDownMenuQuestie-4.0")
local LSM30 = LibStub and LibStub("LibSharedMedia-3.0", true)
local linePoolSize = 250
local lineIndex = 0
local buttonPoolSize = 25
local buttonIndex = 0
local linePool = {}
local buttonPool = {}
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
function TrackerLinePool.Initialize(questFrame)
local trackerQuestFrame = questFrame
local trackerFontSizeQuest = Questie.db.profile.trackerFontSizeQuest
-- create linePool for quests/achievements
local nextFrame
for i = 1, linePoolSize do
local timeElapsed = 0
local line = CreateFrame("Button", "linePool" .. i, trackerQuestFrame.ScrollChildFrame)
line:SetWidth(1)
line:SetHeight(1)
line.label = line:CreateFontString(nil, "ARTWORK", "GameFontNormal")
line.label:SetJustifyH("LEFT")
line.label:SetJustifyV("TOP")
line.label:SetPoint("TOPLEFT", line)
line.label:Hide()
-- autoadjust parent size for clicks
line.label._SetText = line.label.SetText
line.label.frame = line
line.label.SetText = function(self, text)
self:_SetText(text)
self.frame:SetWidth(self:GetWidth())
self.frame:SetHeight(self:GetHeight())
end
if nextFrame then
-- Second lineIndex hearafter
line:SetPoint("TOPLEFT", nextFrame, "BOTTOMLEFT", 0, 0)
else
-- First lineIndex
line:SetPoint("TOPLEFT", trackerQuestFrame.ScrollChildFrame, "TOPLEFT", lineMarginLeft, 0)
end
line.SetMode = TrackerLinePool.SetMode
function line:SetZone(ZoneId)
if type(ZoneId) == "string" then
self.expandZone.zoneId = ZoneId
elseif type(ZoneId) == "number" then
self.ZoneId = TrackerUtils:GetZoneNameByID(ZoneId)
self.expandZone.zoneId = ZoneId
end
end
function line:SetQuest(Quest)
if type(Quest) == "number" then
Quest = {
Id = Quest
}
self.Quest = Quest
self.expandQuest.questId = Quest.Id
else
self.Quest = Quest
self.expandQuest.questId = Quest.Id
end
-- Set Timed Quest Flag
if Quest.trackTimedQuest then
self.trackTimedQuest = Quest.trackTimedQuest
end
end
function line:SetObjective(Objective)
self.Objective = Objective
end
line.OnUpdate = function(self, elapsed)
if Questie.IsWotlk or QuestieCompat.Is335 then
timeElapsed = timeElapsed + elapsed
if timeElapsed > 1 and self.trackTimedQuest and self.label.activeTimer then
local _, timeRemaining = TrackerQuestTimers:GetRemainingTimeByQuestId(self.Quest.Id)
if timeRemaining ~= nil then
if timeRemaining > 1 then
TrackerQuestTimers:UpdateTimerFrame()
end
if timeRemaining == 1 then
TrackerQuestTimers:UpdateTimerFrame()
end
timeElapsed = 0
else
timeElapsed = 0
return
end
end
else
return
end
end
function line:SetVerticalPadding(amount)
if self.mode == "zone" then
self:SetHeight(Questie.db.profile.trackerFontSizeZone + amount)
elseif self.mode == "quest" or "achieve" then
self:SetHeight(Questie.db.profile.trackerFontSizeQuest + amount)
else
self:SetHeight(Questie.db.profile.trackerFontSizeObjective + amount)
end
end
line:EnableMouse(true)
line:RegisterForDrag("LeftButton")
line:RegisterForClicks("RightButtonUp", "LeftButtonUp")
function line:SetOnClick(onClickmode)
if onClickmode == "quest" then
self:SetScript("OnClick", TrackerLinePool.OnClickQuest)
elseif onClickmode == "achieve" then
self:SetScript("OnClick", TrackerLinePool.OnClickAchieve)
end
end
line:SetScript("OnDragStart", TrackerBaseFrame.OnDragStart)
line:SetScript("OnDragStop", TrackerBaseFrame.OnDragStop)
line:SetScript("OnEnter", function(self)
TrackerLinePool.OnHighlightEnter(self)
TrackerFadeTicker.Unfade()
end)
line:SetScript("OnLeave", function(self)
TrackerLinePool.OnHighlightLeave(self)
TrackerFadeTicker.Fade()
end)
-- create objective complete criteria marks
local criteriaMark = CreateFrame("Button", "linePool.criteriaMark" .. i, line)
criteriaMark.texture = criteriaMark:CreateTexture(nil, "OVERLAY", nil, 0)
criteriaMark.texture:SetWidth(Questie.db.profile.trackerFontSizeObjective)
criteriaMark.texture:SetHeight(Questie.db.profile.trackerFontSizeObjective)
criteriaMark.texture:SetAllPoints(criteriaMark)
criteriaMark:SetWidth(1)
criteriaMark:SetHeight(1)
criteriaMark:SetPoint("RIGHT", line.label, "LEFT", -4, 0)
criteriaMark:SetFrameLevel(100)
criteriaMark.SetCriteria = function(self, criteria)
if criteria ~= self.mode then
self.mode = criteria
if criteria == true then
self.texture:SetTexture(QuestieLib.AddonPath.."Icons\\Checkmark")
---------------------------------------------------------------------
-- Just in case we decide to show the minus sign for incompletes
---------------------------------------------------------------------
--self.texture:SetAlpha(1)
--else
--self.texture:SetTexture("Interface\\Addons\\Questie\\Icons\\Minus")
--self.texture:SetAlpha(0.5)
---------------------------------------------------------------------
end
self:SetWidth(Questie.db.profile.trackerFontSizeObjective)
self:SetHeight(Questie.db.profile.trackerFontSizeObjective)
end
end
criteriaMark:SetCriteria(false)
criteriaMark:Hide()
line.criteriaMark = criteriaMark
-- create expanding zone headers for quests sorted by zones
local expandZone = CreateFrame("Button", "linePool.expandZone" .. i, line)
expandZone:SetWidth(1)
expandZone:SetHeight(1)
expandZone:SetPoint("TOPLEFT", line, "TOPLEFT", 0, 0)
expandZone.SetMode = function(self, mode)
if mode ~= self.mode then
self.mode = mode
end
end
expandZone:SetMode(1) -- maximized
expandZone:EnableMouse(true)
expandZone:RegisterForDrag("LeftButton")
expandZone:RegisterForClicks("LeftButtonUp", "LeftButtonDown", "RightButtonUp", "RightButtonDown")
expandZone:SetScript("OnMouseDown", function(self, button)
if button == "LeftButton" then
if IsShiftKeyDown() then
-- This sets up the minAllQuestsInZone table upon first click
if not Questie.db.char.collapsedZones[self.zoneId] then
if not Questie.db.char.minAllQuestsInZone[self.zoneId] then
Questie.db.char.minAllQuestsInZone[self.zoneId] = {}
-- This flag prevents repopulating QuestID's where we don't want them.
Questie.db.char.minAllQuestsInZone[self.zoneId].isTrue = true
QuestieCombatQueue:Queue(function()
QuestieTracker:Update()
end)
end
end
end
end
end)
expandZone:SetScript("OnMouseUp", function(self, button)
if button == "LeftButton" then
if IsShiftKeyDown() then
if not Questie.db.char.collapsedZones[self.zoneId] then
C_Timer.After(0.1, function()
if Questie.db.char.minAllQuestsInZone[self.zoneId].isTrue then
-- Places all QuestID's into the collapsedQuests table and keeps the Min/Max buttons in sync.
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:minAllQuestsInZone] - Minimize")
for questId, _ in pairs(Questie.db.char.minAllQuestsInZone[self.zoneId]) do
if type(questId) == "number" then
Questie.db.char.collapsedQuests[questId] = true
end
end
Questie.db.char.minAllQuestsInZone[self.zoneId].isTrue = nil
else
-- Removes all QuestID's from the collapsedQuests table.
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:minAllQuestsInZone] - Maximize")
for questId, _ in pairs(Questie.db.char.minAllQuestsInZone[self.zoneId]) do
if type(questId) == "number" then
Questie.db.char.collapsedQuests[questId] = nil
end
end
Questie.db.char.minAllQuestsInZone[self.zoneId] = nil
end
QuestieCombatQueue:Queue(function()
QuestieTracker:Update()
end)
end)
end
else
if self.mode == 1 then
self:SetMode(0)
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:expandZone] - Minimize")
else
self:SetMode(1)
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:expandZone] - Maximize")
end
if Questie.db.char.collapsedZones[self.zoneId] == true then
Questie.db.char.collapsedZones[self.zoneId] = nil
else
Questie.db.char.collapsedZones[self.zoneId] = true
end
QuestieCombatQueue:Queue(function()
QuestieTracker:Update()
end)
end
end
end)
expandZone:SetScript("OnEnter", function(self)
TrackerLinePool.OnHighlightEnter(self)
TrackerFadeTicker.Unfade()
end)
expandZone:SetScript("OnLeave", function(self)
TrackerLinePool.OnHighlightLeave(self)
TrackerFadeTicker.Fade()
end)
expandZone:Hide()
line.expandZone = expandZone
-- create play buttons for AI_VoiceOver
local playButton = CreateFrame("Button", "linePool.playButton" .. i, line)
playButton:SetWidth(20)
playButton:SetHeight(20)
playButton:SetHitRectInsets(2, 2, 2, 2)
playButton:SetPoint("RIGHT", line.label, "LEFT", -4, 0)
playButton:SetFrameLevel(0)
playButton:SetNormalTexture(QuestieLib.AddonPath.."Icons\\QuestLogPlayButton")
playButton:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight")
playButton.SetPlayButton = function(self, questId)
if questId ~= self.mode then
self.mode = questId
if questId and TrackerUtils:IsVoiceOverLoaded() then
self:Show()
else
self.mode = nil
self:SetAlpha(0)
self:Hide()
end
end
end
playButton:EnableMouse(true)
playButton:RegisterForClicks("LeftButtonUp")
playButton:SetScript("OnClick", function(self)
if self.mode ~= nil then
if TrackerUtils:IsVoiceOverLoaded() then
local button = VoiceOver.QuestOverlayUI.questPlayButtons[self.mode]
if button then
if not VoiceOver.QuestOverlayUI.questPlayButtons[self.mode].soundData then
local type, id = VoiceOver.DataModules:GetQuestLogQuestGiverTypeAndID(self.mode)
local qli = GetQuestLogIndexByID(self.mode)
local title = (qli and GetQuestLogTitle(qli)) or ""
VoiceOver.QuestOverlayUI.questPlayButtons[self.mode].soundData = {
event = VoiceOver.Enums.SoundEvent.QuestAccept,
questID = self.mode,
name = id and VoiceOver.DataModules:GetObjectName(type, id) or "Unknown Name",
title = title,
unitGUID = id and VoiceOver.Enums.GUID:CanHaveID(type) and VoiceOver.Utils:MakeGUID(type, id) or nil
}
end
local soundData = VoiceOver.QuestOverlayUI.questPlayButtons[self.mode].soundData
local isPlaying = VoiceOver.SoundQueue:Contains(soundData)
if not isPlaying then
VoiceOver.SoundQueue:AddSoundToQueue(soundData)
VoiceOver.QuestOverlayUI:UpdatePlayButtonTexture(self.mode)
soundData.stopCallback = function()
VoiceOver.QuestOverlayUI:UpdatePlayButtonTexture(self.mode)
VoiceOver.QuestOverlayUI.questPlayButtons[self.mode].soundData = nil
end
else
VoiceOver.SoundQueue:RemoveSoundFromQueue(soundData)
end
isPlaying = button.soundData and VoiceOver.SoundQueue:Contains(button.soundData)
local texturePath = isPlaying and QuestieLib.AddonPath.."Icons\\QuestLogStopButton" or QuestieLib.AddonPath.."Icons\\QuestLogPlayButton"
self:SetNormalTexture(texturePath)
-- Move the VoiceOverFrame below the DurabilityFrame if it's present and not already moved
if (Questie.db.profile.stickyDurabilityFrame and DurabilityFrame:IsVisible()) and select(5, VoiceOverFrame:GetPoint()) < -125 then
QuestieTracker:UpdateVoiceOverFrame()
end
end
end
end
end)
playButton:SetAlpha(0)
playButton:Hide()
line.playButton = playButton
-- create supertrack buttons for the Ascension floating objective marker
local superTrackButton = CreateFrame("Button", "linePool.superTrackButton" .. i, line)
superTrackButton:SetWidth(25)
superTrackButton:SetHeight(25)
superTrackButton:SetHitRectInsets(1, 1, 1, 1)
-- Hover and pressed states come from the pin atlas too, additively blended, exactly as the
-- client's own pins do it. RefreshSuperTrackButton mirrors the pin's cells over these.
superTrackButton:SetHighlightTexture("Interface\\WorldMap\\UI-QuestPoi-NumberIcons", "ADD")
superTrackButton:GetHighlightTexture():SetTexCoord(0.625, 0.75, 0.375, 0.5)
superTrackButton:SetPushedTexture("Interface\\WorldMap\\UI-QuestPoi-NumberIcons")
-- Same texture and atlas sub-rect the client's own quest POI pins use, so the tracker button
-- reads as native rather than as an addon icon.
superTrackButton:SetNormalTexture("Interface\\WorldMap\\UI-QuestPoi-NumberIcons")
superTrackButton:GetNormalTexture():SetTexCoord(0.5, 0.625, 0.875, 1)
-- The client marks the selected pin with this glow rather than by swapping the icon, so the
-- tracker button highlights the same way the map pin does.
superTrackButton.glow = superTrackButton:CreateTexture(nil, "BACKGROUND")
superTrackButton.glow:SetTexture("Interface\\WorldMap\\UI-QuestPoi-IconGlow")
superTrackButton.glow:SetBlendMode("ADD")
superTrackButton.glow:SetPoint("CENTER", superTrackButton, "CENTER", 0, 0)
superTrackButton.glow:Hide()
-- The digit printed inside the pin is another cell of the same atlas, drawn over the icon.
superTrackButton.number = superTrackButton:CreateTexture(nil, "OVERLAY")
superTrackButton.number:SetPoint("CENTER", superTrackButton, "CENTER", 0, 0)
superTrackButton.number:Hide()
-- Completed quests draw a "?" from this separate region instead of a digit.
superTrackButton.turnin = superTrackButton:CreateTexture(nil, "OVERLAY")
superTrackButton.turnin:SetPoint("CENTER", superTrackButton, "CENTER", 0, 0)
superTrackButton.turnin:Hide()
-- The quest id is remembered even while the button is hidden. POI frames only exist once the
-- world map has built them, so a quest that looks unreachable while the tracker is drawing
-- can become reachable later -- without the id we would have nothing left to re-check.
-- The pin's pressed state nudges what is drawn inside it down and to the right; the pushed
-- texture covers the circle, this covers the digit and the "?".
superTrackButton.SetPressedOffset = function(self, pressed)
local offset = pressed and 1 or 0
self.number:ClearAllPoints()
self.number:SetPoint("CENTER", self, "CENTER", offset, -offset)
self.turnin:ClearAllPoints()
self.turnin:SetPoint("CENTER", self, "CENTER", offset, -offset)
end
superTrackButton.SetSuperTrackButton = function(self, questId)
self.questId = questId
self:RefreshSuperTrackButton()
end
superTrackButton.RefreshSuperTrackButton = function(self)
-- No map pin means the client has nothing to point the marker at (quest in another zone,
-- or a quest without map coordinates), so there is nothing to offer.
local pin = self.questId and TrackerUtils:GetSuperTrackPin(self.questId)
if (not pin) or (not Questie.db.profile.trackerShowSuperTrackButton) then
self:Hide()
return
end
local buttonSize = Questie.db.profile.trackerSuperTrackButtonSize or 25
self:SetWidth(buttonSize)
self:SetHeight(buttonSize)
self.glow:SetWidth(buttonSize * 1.4)
self.glow:SetHeight(buttonSize * 1.4)
-- Mirror the pin rather than picking atlas cells ourselves, so whatever the client
-- decides to draw -- digit, "?", selected variant -- shows up here unchanged. The
-- 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
-- sample nonsense.
local isSuperTracked = TrackerUtils:GetSuperTrackedQuestId() == self.questId
local pinTexture = pin.GetNormalTexture and pin:GetNormalTexture()
if pinTexture then
local ownTexture = self:GetNormalTexture()
ownTexture:SetTexture(pinTexture:GetTexture())
ownTexture:SetTexCoord(pinTexture:GetTexCoord())
ApplySelectedVariant(ownTexture, isSuperTracked)
end
MirrorPinButtonTexture(self:GetHighlightTexture(), pin.GetHighlightTexture and pin:GetHighlightTexture())
local ownPushed = self:GetPushedTexture()
MirrorPinButtonTexture(ownPushed, pin.GetPushedTexture and pin:GetPushedTexture())
if ownPushed then
ApplySelectedVariant(ownPushed, isSuperTracked)
end
local pinSize = pin:GetWidth()
MirrorPinRegion(self.number, pin.number, buttonSize, pinSize)
MirrorPinRegion(self.turnin, pin.turnin, buttonSize, pinSize)
if self.number:IsShown() then
ApplySelectedVariant(self.number, isSuperTracked)
end
-- Undo any leftover pressed offset: the pool recycles buttons, and a line can be redrawn
-- while the mouse is still held down.
self:SetPressedOffset(false)
-- Flush with the left edge of the line, in the gutter GetSuperTrackMarginReserve keeps
-- clear. Anchored to the top rather than centred on the line so the button stays level
-- 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()
else
self.glow:Hide()
end
-- Has to sit above the tracker backdrop, which is what swallows a frame left at level 0.
self:SetFrameLevel(line:GetFrameLevel() + 10)
self:Show()
end
superTrackButton:EnableMouse(true)
superTrackButton:RegisterForClicks("LeftButtonUp")
superTrackButton:SetScript("OnMouseDown", function(self)
self:SetPressedOffset(true)
end)
superTrackButton:SetScript("OnMouseUp", function(self)
self:SetPressedOffset(false)
end)
superTrackButton:SetScript("OnClick", function(self)
if self.questId then
-- Same sound the client plays for its own quest pins.
PlaySound("igMainMenuOptionCheckBoxOn")
TrackerUtils:SetSuperTrackedQuest(self.questId)
end
end)
superTrackButton:Hide()
line.superTrackButton = superTrackButton
-- create expanding buttons for quests with objectives
local expandQuest = CreateFrame("Button", "linePool.expandQuest" .. i, line)
expandQuest.texture = expandQuest:CreateTexture(nil, "OVERLAY", nil, 0)
expandQuest.texture:SetWidth(trackerFontSizeQuest)
expandQuest.texture:SetHeight(trackerFontSizeQuest)
expandQuest.texture:SetAllPoints(expandQuest)
expandQuest:SetWidth(trackerFontSizeQuest)
expandQuest:SetHeight(trackerFontSizeQuest)
expandQuest:SetPoint("RIGHT", line, "LEFT", 0, 0)
expandQuest:SetFrameLevel(100)
expandQuest.SetMode = function(self, mode)
if mode ~= self.mode then
self.mode = mode
if mode == 1 then
self.texture:SetTexture("Interface\\Buttons\\UI-MinusButton-Up")
else
self.texture:SetTexture("Interface\\Buttons\\UI-PlusButton-Up")
end
self:SetWidth(Questie.db.profile.trackerFontSizeQuest + 3)
self:SetHeight(Questie.db.profile.trackerFontSizeQuest + 3)
end
end
expandQuest:SetMode(1) -- maximized
expandQuest:EnableMouse(true)
expandQuest:RegisterForClicks("LeftButtonUp", "RightButtonUp")
expandQuest:SetScript("OnClick", function(self)
if self.mode == 1 then
self:SetMode(0)
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:expandQuest] - Minimize")
else
self:SetMode(1)
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:expandQuest] - Maximize")
end
if Questie.db.char.collapsedQuests[self.questId] then
Questie.db.char.collapsedQuests[self.questId] = nil
-- This keeps both tables in sync so we can use them to maintain Min/Max states.
if Questie.db.char.minAllQuestsInZone[self.zoneId] and Questie.db.char.minAllQuestsInZone[self.zoneId][self.questId] then
Questie.db.char.minAllQuestsInZone[self.zoneId][self.questId] = nil
end
else
Questie.db.char.collapsedQuests[self.questId] = true
-- This keeps both tables in sync so we can use them to maintain Min/Max states.
if Questie.db.char.minAllQuestsInZone[self.zoneId] then
Questie.db.char.minAllQuestsInZone[self.zoneId][self.questId] = true
end
end
QuestieCombatQueue:Queue(function()
QuestieTracker:Update()
end)
end)
if Questie.IsWotlk or QuestieCompat.Is335 then
line:HookScript("OnUpdate", line.OnUpdate)
end
if Questie.db.profile.trackerFadeMinMaxButtons then
expandQuest:SetAlpha(0)
end
expandQuest:SetScript("OnEnter", function()
TrackerFadeTicker.Unfade()
end)
expandQuest:SetScript("OnLeave", function()
TrackerFadeTicker.Fade()
end)
expandQuest:Hide()
line.expandQuest = expandQuest
linePool[i] = line
nextFrame = line
end
-- create buttonPool for quest items
for i = 1, C_QuestLog.GetMaxNumQuestsCanAccept() do
local buttonName = "Questie_ItemButton" .. i
local btn = CreateFrame("Button", buttonName, UIParent, "SecureActionButtonTemplate")
local cooldown = CreateFrame("Cooldown", nil, btn, "CooldownFrameTemplate")
btn.range = btn:CreateFontString(nil, "OVERLAY", "NumberFontNormalSmallGray")
btn.count = btn:CreateFontString(nil, "ARTWORK", QuestieCompat.Is335 and "SystemFont_Outline_Small" or "Game10Font_o1")
btn:Hide()
if Questie.db.profile.trackerFadeQuestItemButtons then
btn:SetAlpha(0)
end
btn.SetItem = function(self, quest, buttonType, size)
local validTexture
local foundItemId
-- Check primary source item
if quest.sourceItemId and quest.sourceItemId ~= 0 and buttonType == "primary" then
-- For quests QuestieDB has no data on, sourceItemId was resolved live via
-- GetQuestLogSpecialItemInfo -- the client already vetted it as the quest's
-- special item, so the static-DB item class isn't known/needed here.
local isQuestItem = quest._liveSourceItem or QuestieDB.QueryItemSingle(quest.sourceItemId, "class") == 12
if isQuestItem and GetItemCount(quest.sourceItemId, false, false) > 0 then
foundItemId = quest.sourceItemId
end
end
-- Check secondary source items
if not foundItemId and type(quest.requiredSourceItems) == "table" then
if #quest.requiredSourceItems == 1 then
local questItemId = quest.requiredSourceItems[1]
if questItemId and questItemId ~= quest.sourceItemId and QuestieDB.QueryItemSingle(questItemId, "class") == 12 then
if GetItemCount(questItemId, false, false) > 0 then
foundItemId = questItemId
end
end
elseif #quest.requiredSourceItems > 1 and buttonType == "secondary" then
for _, questItemId in pairs(quest.requiredSourceItems) do
if questItemId and questItemId ~= quest.sourceItemId and QuestieDB.QueryItemSingle(questItemId, "class") == 12 then
if GetItemCount(questItemId, false, false) > 0 then
foundItemId = questItemId
break
end
end
end
end
end
if foundItemId then
self.itemId = foundItemId
validTexture = select(10, GetItemInfo(foundItemId)) or GetItemIcon(foundItemId)
end
if validTexture and self.itemId then
self.questID = quest.Id
self.charges = GetItemCount(self.itemId, nil, true)
self.rangeTimer = -1
self:SetNormalTexture(validTexture)
self:SetPushedTexture(validTexture)
self:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
self:SetSize(size, size)
self:RegisterForClicks("anyUp")
self:SetScript("OnEvent", self.OnEvent)
self:SetScript("OnShow", self.OnShow)
self:SetScript("OnHide", self.OnHide)
self:SetScript("OnEnter", self.OnEnter)
self:SetScript("OnLeave", self.OnLeave)
self:SetAttribute("type1", "item")
self:SetAttribute("item1", "item:" .. self.itemId)
self:Show()
-- Cooldown Updates
cooldown:SetSize(size - 4, size - 4)
cooldown:SetPoint("CENTER", self, "CENTER", 0, 0)
cooldown:Hide()
-- Range Updates
self.range:SetText("●")
self.range:SetPoint("TOPRIGHT", self, "TOPRIGHT", 3, 0)
self.range:Hide()
-- Charges Updates
self.count:Hide()
self.count:SetFont((LSM30 and LSM30.Fetch and LSM30:Fetch("font", Questie.db.profile.trackerFontQuest)) or Questie.db.profile.trackerFontQuest, Questie.db.profile.trackerFontSizeQuest, "OUTLINE")
if self.charges > 1 then
self.count:SetText(self.charges)
self.count:Show()
end
self.count:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -2, 3)
return true
else
self:SetAttribute("item1", nil)
self:Hide()
end
return false
end
btn.OnEvent = function(self, event, ...)
if (event == "PLAYER_TARGET_CHANGED") then
self.rangeTimer = -1
self.range:Hide()
end
end
btn.OnUpdate = function(self, elapsed)
if not self.itemId or not self:IsVisible() then
return
end
self.updateTimer = (self.updateTimer or 0) + elapsed
if self.updateTimer >= 0.2 then
local start, duration, enabled = QuestieCompat.GetItemCooldown(self.itemId)
if enabled == 1 and duration > 0 then
cooldown:SetCooldown(start, duration, enabled)
cooldown:Show()
else
cooldown:Hide()
end
local charges = GetItemCount(self.itemId, nil, true)
if (not charges or charges ~= self.charges) then
self.count:Hide()
self.charges = GetItemCount(self.itemId, nil, true)
if self.charges > 1 then
self.count:SetText(self.charges)
self.count:Show()
end
if self.charges == 0 then
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool: Button.OnUpdate]")
QuestieCombatQueue:Queue(function()
C_Timer.After(0.2, function()
QuestieTracker:Update()
end)
end)
end
end
self.updateTimer = 0
end
if UnitExists("target") then
if not self.itemName then
self.itemName = GetItemInfo(self.itemId)
end
local rangeTimer = self.rangeTimer
if (rangeTimer) then
rangeTimer = rangeTimer - elapsed
-- IsItemInRange is restricted to only be used either on hostile targets or friendly ones while NOT in combat
if (rangeTimer <= 0) and (not UnitIsFriend("player", "target") or (not InCombatLockdown())) then
local isInRange = IsItemInRange(self.itemName, "target")
if isInRange == false then
self.range:SetVertexColor(1.0, 0.1, 0.1)
self.range:Show()
elseif isInRange == true then
self.range:SetVertexColor(0.6, 0.6, 0.6)
self.range:Show()
end
rangeTimer = 0.3
end
self.rangeTimer = rangeTimer
end
end
end
btn.OnShow = function(self)
self:RegisterEvent("PLAYER_TARGET_CHANGED")
end
btn.OnHide = function(self)
self:UnregisterEvent("PLAYER_TARGET_CHANGED")
end
btn.OnEnter = function(self)
GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
GameTooltip:SetHyperlink("item:" .. tostring(self.itemId) .. ":0:0:0:0:0:0:0")
GameTooltip:Show()
TrackerFadeTicker.Unfade(self)
end
btn.OnLeave = function(self)
GameTooltip:Hide()
TrackerFadeTicker.Fade(self)
end
btn.FakeHide = function(self)
self:RegisterForClicks()
self:SetScript("OnEnter", nil)
self:SetScript("OnLeave", nil)
end
btn:HookScript("OnUpdate", btn.OnUpdate)
btn:FakeHide()
buttonPool[i] = btn
buttonPool[i]:Hide()
end
end
function TrackerLinePool.ResetLinesForChange()
if TrackerBaseFrame.isSizing == true or TrackerBaseFrame.isMoving == true then
Questie:Debug(Questie.DEBUG_SPAM, "[TrackerLinePool:ResetLinesForChange]")
else
Questie:Debug(Questie.DEBUG_INFO, "[TrackerLinePool:ResetLinesForChange]")
end
if InCombatLockdown() or not Questie.db.profile.trackerEnabled then
return
end
for _, line in pairs(linePool) do
line.mode = nil
line.trackTimedQuest = nil
if line.expandQuest then
line.expandQuest.mode = nil
line.expandQuest.questId = nil
end
if line.expandZone then
line.expandZone.mode = nil
line.expandZone.zoneId = nil
end
if line.criteriaMark then
line.criteriaMark.mode = nil
line.criteriaMark:SetCriteria(false)
line.criteriaMark:Hide()
end
if line.playButton then
line.playButton.mode = nil
line.playButton:SetAlpha(0)
line.playButton:Hide()
end
if line.superTrackButton then
line.superTrackButton.questId = nil
line.superTrackButton:Hide()
end
end
lineIndex = 0
end
-- Re-evaluates the supertrack buttons without rebuilding the tracker. Driven by the
-- SetSuperTrackedQuestID hook, which also fires on map open/close -- that is what makes buttons
-- appear once the world map has built its POI frames, since the tracker itself does not redraw then.
function TrackerLinePool.UpdateSuperTrackButtons()
-- Rebuild the map's POI frames first so a zone change is picked up even with the map closed.
TrackerUtils:PrimeSuperTrackFrames()
for _, line in pairs(linePool) do
if line.superTrackButton and line.superTrackButton.questId then
line.superTrackButton:RefreshSuperTrackButton()
end
end
end
function TrackerLinePool.ResetButtonsForChange()
if TrackerBaseFrame.isSizing == true or TrackerBaseFrame.isMoving == true then
Questie:Debug(Questie.DEBUG_SPAM, "[TrackerLinePool:ResetButtonsForChange]")
else
Questie:Debug(Questie.DEBUG_INFO, "[TrackerLinePool:ResetButtonsForChange]")
end
if InCombatLockdown() or not Questie.db.profile.trackerEnabled then
return
end
buttonIndex = 0
end
function TrackerLinePool.UpdateWrappedLineWidths(trackerLineWidth)
local trackerFontSizeQuest = Questie.db.profile.trackerFontSizeQuest
local trackerMarginLeft = 14
local trackerMarginRight = 30
local questMarginLeft = (trackerMarginLeft + trackerMarginRight) - (18 - trackerFontSizeQuest)
local objectiveMarginLeft = questMarginLeft + trackerFontSizeQuest
local questItemButtonSize = 12 + trackerFontSizeQuest
-- Updates all the line.label widths in the linePool for wrapped text only
for _, line in pairs(linePool) do
if Questie.db.profile.TrackerWidth == 0 then
if line.mode == "objective" then
if GetNumLines(line.label) > 1 and line:GetHeight() > Questie.db.profile.trackerFontSizeObjective then
line.label:SetText(line.label:GetText())
if line.altButton then
line.label:SetWidth(trackerLineWidth - objectiveMarginLeft - questItemButtonSize)
line:SetWidth(trackerLineWidth + questItemButtonSize)
else
line.label:SetWidth(trackerLineWidth - objectiveMarginLeft)
line:SetWidth(trackerLineWidth)
end
line:SetHeight(line.label:GetStringHeight() + 2 + Questie.db.profile.trackerQuestPadding)
line.label:SetHeight(line:GetHeight() - 2 - Questie.db.profile.trackerQuestPadding)
end
end
end
end
end
---@return table|nil lineIndex linePool[lineIndex + 1]
function TrackerLinePool.GetNextLine()
lineIndex = lineIndex + 1
if not linePool[lineIndex] then
return nil -- past the line limit
end
return linePool[lineIndex]
end
---@return table|nil buttonIndex buttonPool[buttonIndex]
function TrackerLinePool.GetNextItemButton()
buttonIndex = buttonIndex + 1
if not buttonPool[buttonIndex] then
return nil -- past the line limit
end
return buttonPool[buttonIndex]
end
---@return number lineIndex lineIndex == 1
function TrackerLinePool.IsFirstLine()
return linePool[1]
end
---@param index number
---@return table index linePool[index]
function TrackerLinePool.GetLine(index)
return linePool[index]
end
---@return table lineIndex linePool[lineIndex]
function TrackerLinePool.GetCurrentLine()
return linePool[lineIndex]
end
---@return table buttonIndex buttonPool[buttonIndex]
function TrackerLinePool.GetCurrentButton()
return buttonPool[buttonIndex]
end
---@return table|nil lineIndex linePool[lineIndex - 1]
function TrackerLinePool.GetPreviousLine()
lineIndex = lineIndex - 1
if not linePool[lineIndex] then
return nil -- past the line limit
end
return linePool[lineIndex]
end
---@return table linePool linePool[1]
function TrackerLinePool.GetFirstLine()
return linePool[1]
end
---@return table linePool linePool[linePoolSize]
function TrackerLinePool.GetLastLine()
return linePool[linePoolSize]
end
function TrackerLinePool.HideUnusedLines()
if TrackerBaseFrame.isSizing == true or TrackerBaseFrame.isMoving == true then
Questie:Debug(Questie.DEBUG_SPAM, "[TrackerLinePool:HideUnusedLines]")
else
Questie:Debug(Questie.DEBUG_INFO, "[TrackerLinePool:HideUnusedLines]")
end
local startUnusedLines = 0
if Questie.db.char.isTrackerExpanded then
startUnusedLines = lineIndex + 1
end
for i = startUnusedLines, linePoolSize do
local line = linePool[i]
if line then -- Safe Guard to really concurrent triggers
line:Hide()
line.mode = nil
line.ZoneId = nil
line.Quest = nil
line.Objective = nil
line.Button = nil
line.altButton = nil
line.trackTimedQuest = nil
line.expandQuest.mode = nil
line.expandQuest.questId = nil
line.expandZone.mode = nil
line.expandZone.zoneId = nil
line.criteriaMark.mode = nil
line.playButton.mode = nil
end
end
end
function TrackerLinePool.HideUnusedButtons()
if TrackerBaseFrame.isSizing == true or TrackerBaseFrame.isMoving == true then
Questie:Debug(Questie.DEBUG_SPAM, "[TrackerLinePool:HideUnusedButtons]")
else
Questie:Debug(Questie.DEBUG_INFO, "[TrackerLinePool:HideUnusedButtons]")
end
local startUnusedButtons = 0
if Questie.db.char.isTrackerExpanded then
startUnusedButtons = buttonIndex + 1
end
for i = startUnusedButtons, buttonPoolSize do
local button = buttonPool[i]
if button then
button:FakeHide()
button.itemId = nil
button.itemName = nil
button.lineID = nil
button.fontSize = nil
button:ClearAllPoints()
button:SetParent(UIParent)
button:Hide()
end
end
end
---@return number lineIndex
function TrackerLinePool.GetHighestIndex()
return lineIndex > linePoolSize and linePoolSize or lineIndex
end
---@param alpha number
function TrackerLinePool.SetAllPlayButtonAlpha(alpha)
if TrackerUtils:IsVoiceOverLoaded() then
local highestIndex = TrackerLinePool.GetHighestIndex()
for i = 1, highestIndex do
local line = linePool[i]
local questId = line.playButton.mode or 0
local button = VoiceOver.QuestOverlayUI.questPlayButtons[questId]
local sound = VoiceOver.DataModules:PrepareSound({ event = 1, questID = questId })
if button then
local isPlaying = button.soundData and VoiceOver.SoundQueue:Contains(button.soundData)
local texturePath = isPlaying and QuestieLib.AddonPath.."Icons\\QuestLogStopButton" or QuestieLib.AddonPath.."Icons\\QuestLogPlayButton"
line.playButton:SetNormalTexture(texturePath)
end
if IsShiftKeyDown() then
if sound then
line.playButton:SetAlpha(alpha)
else
line.playButton:SetAlpha(0.33)
end
line.playButton:SetFrameLevel(200)
else
line.playButton:SetAlpha(alpha)
line.playButton:SetFrameLevel(0)
end
end
end
end
---@param alpha number
function TrackerLinePool.SetAllExpandQuestAlpha(alpha)
local highestIndex = TrackerLinePool.GetHighestIndex()
for i = 1, highestIndex do
linePool[i].expandQuest:SetAlpha(alpha)
end
end
---@param alpha number
function TrackerLinePool.SetAllItemButtonAlpha(alpha)
local highestIndex = TrackerLinePool.GetHighestIndex()
-- TODO: I don't remember why I coded this hasButton variable. Going to leave it here for now.
--local hasButton = false
for i = 1, highestIndex do
local line = linePool[i]
if line.button then
line.button:SetAlpha(alpha)
--if line.button:GetAlpha() < 0.07 then
-- hasButton = true
--end
end
if line.altButton then
line.altButton:SetAlpha(alpha)
--if line.altButton:GetAlpha() < 0.07 then
-- hasButton = true
--end
end
end
--[[
if hasButton then
QuestieTracker:Update()
end
--]]
end
---@param button string
TrackerLinePool.OnClickQuest = function(self, button)
if (not self.Quest) then
return
end
if TrackerMenu.menuFrame:IsShown() then
LibDropDown:CloseDropDownMenus()
end
if TrackerUtils:IsBindTrue(Questie.db.profile.trackerbindSetTomTom, button) then
local spawn, zone, name = QuestieMap:GetNearestQuestSpawn(self.Quest)
if spawn then
TrackerUtils:SetTomTomTarget(name, zone, spawn[1], spawn[2])
end
elseif TrackerUtils:IsBindTrue(Questie.db.profile.trackerbindUntrack, button) then
if (IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
-- Follow Ascension's native pattern: get quest log index and use native linking
local questLogIndex = GetQuestLogIndexByID(self.Quest.Id)
if questLogIndex then
local questLink = GetQuestLink(questLogIndex)
if questLink then
ChatEdit_InsertLink(questLink)
end
end
else
local questLogIndex = GetQuestLogIndexByID(self.Quest.Id)
if questLogIndex and questLogIndex > 0 then
RemoveQuestWatch(questLogIndex)
end
QuestieTracker:UntrackQuestId(self.Quest.Id)
local questLogFrame = QuestLogExFrame or ClassicQuestLog or QuestLogFrame
if questLogFrame:IsShown() then
QuestLog_Update()
end
end
elseif TrackerUtils:IsBindTrue(Questie.db.profile.trackerbindOpenQuestLog, button) then
TrackerUtils:ShowQuestLog(self.Quest)
elseif button == "RightButton" then
local menu = TrackerMenu:GetMenuForQuest(self.Quest)
LibDropDown:EasyMenu(menu, TrackerMenu.menuFrame, "cursor", 0, 0, "MENU")
end
end
---@param button string
TrackerLinePool.OnClickAchieve = function(self, button)
Questie:Debug(Questie.DEBUG_DEVELOP, "[TrackerLinePool:_OnClickAchieve]")
if (not self.Quest) then
return
end
if TrackerMenu.menuFrame:IsShown() then
LibDropDown:CloseDropDownMenus()
end
if TrackerUtils:IsBindTrue(Questie.db.profile.trackerbindUntrack, button) then
if (IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow()) then
ChatEdit_InsertLink(GetAchievementLink(self.Quest.Id))
else
if Questie.db.char.trackedAchievementIds[self.Quest.Id] then
QuestieTracker:UntrackAchieveId(self.Quest.Id)
QuestieTracker:UpdateAchieveTrackerCache(self.Quest.Id)
if (not AchievementFrame) then
AchievementFrame_LoadUI()
end
AchievementFrameAchievements_ForceUpdate()
QuestieCombatQueue:Queue(function()
QuestieTracker:Update()
end)
else
-- Assume this is an Objective of an Achievement
UIErrorsFrame:AddMessage(format(l10n("You can't untrack an objective of an achievement.")), 1.0, 0.1, 0.1, 1.0)
end
end
elseif TrackerUtils:IsBindTrue(Questie.db.profile.trackerbindOpenQuestLog, button) then
if (not AchievementFrame) then
AchievementFrame_LoadUI()
end
if (not AchievementFrame:IsShown()) then
AchievementFrame_ToggleAchievementFrame()
AchievementFrame_SelectAchievement(self.Quest.Id)
else
if (AchievementFrameAchievements.selection ~= self.Quest.Id) then
AchievementFrame_SelectAchievement(self.Quest.Id)
end
end
elseif button == "RightButton" then
local menu = TrackerMenu:GetMenuForAchievement(self.Quest)
LibDropDown:EasyMenu(menu, TrackerMenu.menuFrame, "cursor", 0, 0, "MENU")
end
end
TrackerLinePool.OnHighlightEnter = function(self)
local highestIndex = TrackerLinePool.GetHighestIndex()
for i = 1, highestIndex do
local line = linePool[i]
line:SetAlpha(0.5)
if (line.Quest ~= nil and line.Quest == self.Quest) or (line.expandZone ~= nil and self:GetParent().expandZone ~= nil and line.expandZone.zoneId == self:GetParent().expandZone.zoneId) then
line:SetAlpha(1)
end
end
end
TrackerLinePool.OnHighlightLeave = function()
local highestIndex = TrackerLinePool.GetHighestIndex()
for i = 1, highestIndex do
linePool[i]:SetAlpha(1)
end
end
---@param mode string
TrackerLinePool.SetMode = function(self, mode)
if mode ~= self.mode then
self.mode = mode
-- Lines are recycled between zone headers, quest titles and objectives. Only quest title
-- lines own a supertrack button, so drop it whenever a line takes on another role.
if mode ~= "quest" and self.superTrackButton then
self.superTrackButton.questId = nil
self.superTrackButton:Hide()
end
if mode == "zone" then
local trackerFontSizeZone = Questie.db.profile.trackerFontSizeZone
self.label:SetFont((LSM30 and LSM30.Fetch and LSM30:Fetch("font", Questie.db.profile.trackerFontZone)) or Questie.db.profile.trackerFontZone, trackerFontSizeZone, Questie.db.profile.trackerFontOutline)
self.label:SetHeight(trackerFontSizeZone)
elseif mode == "quest" or mode == "achieve" then
local trackerFontSizeQuest = Questie.db.profile.trackerFontSizeQuest
self.label:SetFont((LSM30 and LSM30.Fetch and LSM30:Fetch("font", Questie.db.profile.trackerFontQuest)) or Questie.db.profile.trackerFontQuest, trackerFontSizeQuest, Questie.db.profile.trackerFontOutline)
self.label:SetHeight(trackerFontSizeQuest)
self.button = nil
elseif mode == "objective" then
local trackerFontSizeObjective = Questie.db.profile.trackerFontSizeObjective
self.label:SetFont((LSM30 and LSM30.Fetch and LSM30:Fetch("font", Questie.db.profile.trackerFontObjective)) or Questie.db.profile.trackerFontObjective, trackerFontSizeObjective, Questie.db.profile.trackerFontOutline)
self.label:SetHeight(trackerFontSizeObjective)
end
end
end