c2b1b82b2f
Drops the left-margin reserve the marker used to get: the quest list goes back to its original indent and the marker tucks in to the left of whatever owns the head of the line -- the quest item button where there is one, the collapse button where there is not -- hanging over the tracker's left edge, and off it entirely at larger sizes. A marker that reaches past the edge is reparented above the scroll frame, which would otherwise clip it. It is also centred on the quest's whole text block rather than on the title alone. The block is added up from the line heights the tracker itself sets: measuring the frames with GetTop/GetBottom reads positions from a half-built tracker on login and flings the marker off it.
1451 lines
58 KiB
Lua
1451 lines
58 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
|
|
|
|
-- Gap kept between the supertrack button and whatever it is tucked in next to.
|
|
local superTrackButtonGap = 2
|
|
|
|
-- Left edge of a quest line's collapse button. QuestieTracker anchors it at questMarginLeft - 8
|
|
-- with a width of trackerFontSizeQuest, and questMarginLeft carries a matching + trackerFontSizeQuest,
|
|
-- so it lands on a flat 18 whatever the font size is.
|
|
local superTrackCollapseButtonLeft = 18
|
|
|
|
---@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
|
|
-- Back to the title line on its own: the objective lines below have not been laid out
|
|
-- yet, so the tracker measures the block and calls SetBlockHeight once they are. Same
|
|
-- for the quest item button, which is set up further down and owns this slot.
|
|
self.blockHeight = nil
|
|
self.itemButtonShown = nil
|
|
self:RefreshSuperTrackButton()
|
|
end
|
|
|
|
-- Horizontally: tucked in to the left of whatever else owns the head of the line -- the
|
|
-- quest item button where there is one, the collapse button where there is not. It hangs
|
|
-- over the line's left edge, and off the tracker entirely at larger sizes; giving the
|
|
-- marker a column of its own would mean indenting every quest in the tracker for it.
|
|
-- Vertically: centred on the quest's whole text block, title plus objectives, the height
|
|
-- the tracker hands us. Without one, centred on the quest title alone, which is all that
|
|
-- exists at the point the button is first set up.
|
|
superTrackButton.AnchorSuperTrackButton = function(self)
|
|
local buttonSize = Questie.db.profile.trackerSuperTrackButtonSize or 25
|
|
local blockHeight = self.blockHeight or Questie.db.profile.trackerFontSizeQuest
|
|
local slotLeft = self.itemButtonShown and 0 or superTrackCollapseButtonLeft
|
|
local offsetX = slotLeft - superTrackButtonGap - buttonSize
|
|
|
|
-- The lines live inside the tracker's scroll frame, which clips anything hanging over
|
|
-- its edge, so a marker that reaches past it is reparented above the clip. It stays
|
|
-- anchored to its line either way, and every redraw hides it by hand
|
|
-- (ResetLinesForChange) before deciding whether to show it again.
|
|
self:SetParent(((offsetX + lineMarginLeft) < 0) and trackerQuestFrame or line)
|
|
|
|
self:ClearAllPoints()
|
|
self:SetPoint("TOPLEFT", line, "TOPLEFT", offsetX, (buttonSize - blockHeight) / 2 + 1)
|
|
|
|
-- Has to sit above the tracker backdrop, which is what swallows a frame left at level 0.
|
|
-- Strata comes from the line rather than from whichever parent it ended up with, so the
|
|
-- two cases draw the same.
|
|
self:SetFrameStrata(line:GetFrameStrata())
|
|
self:SetFrameLevel(line:GetFrameLevel() + 10)
|
|
end
|
|
|
|
superTrackButton.SetBlockHeight = function(self, blockHeight)
|
|
if self.blockHeight == blockHeight then
|
|
return
|
|
end
|
|
|
|
self.blockHeight = blockHeight
|
|
self:AnchorSuperTrackButton()
|
|
end
|
|
|
|
superTrackButton.SetItemButtonShown = function(self, shown)
|
|
shown = shown and true or false
|
|
if (self.itemButtonShown or false) == shown then
|
|
return
|
|
end
|
|
|
|
self.itemButtonShown = shown
|
|
self:AnchorSuperTrackButton()
|
|
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)
|
|
|
|
self:AnchorSuperTrackButton()
|
|
|
|
-- 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
|
|
|
|
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
|
|
|
|
-- Its own slot in the pool, so a run of lines drawn for one quest can be walked back over.
|
|
line.lineIndex = i
|
|
|
|
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
|
|
|
|
-- Height of the block of lines a single quest was drawn into, title line through last objective.
|
|
-- Added up from the heights the tracker itself set rather than measured off the frames: on login
|
|
-- the tracker has not been laid out yet, and GetTop/GetBottom then report positions from a
|
|
-- half-built frame, which is enough to fling a marker centred on the result off the tracker.
|
|
---@return number|nil blockHeight
|
|
function TrackerLinePool.GetQuestBlockHeight(firstLine, lastLine)
|
|
if (not firstLine) or (not lastLine) or (not firstLine.lineIndex) or (not lastLine.lineIndex) then
|
|
return nil
|
|
end
|
|
|
|
if lastLine.lineIndex < firstLine.lineIndex then
|
|
return nil
|
|
end
|
|
|
|
local blockHeight = 0
|
|
for i = firstLine.lineIndex, lastLine.lineIndex do
|
|
local line = linePool[i]
|
|
if not line then
|
|
return nil
|
|
end
|
|
|
|
blockHeight = blockHeight + line:GetHeight()
|
|
end
|
|
|
|
-- The last line of a quest carries the padding to the next one. That is empty space below the
|
|
-- text, so it plays no part in where the block's centre is. A quest collapsed down to its title
|
|
-- is the exception: that single line is the whole quest, and neither reference reads right on
|
|
-- its own -- against the text alone the marker rides high over the row's empty half, against
|
|
-- the whole row it sits low under the title it belongs to -- so it splits the difference.
|
|
local trailingPadding = Questie.db.profile.trackerQuestPadding + 2
|
|
if lastLine.lineIndex == firstLine.lineIndex then
|
|
trailingPadding = trailingPadding / 2
|
|
end
|
|
|
|
blockHeight = blockHeight - trailingPadding
|
|
|
|
if blockHeight <= 0 then
|
|
return nil
|
|
end
|
|
|
|
return blockHeight
|
|
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
|
|
-- Hidden by hand: a marker that overflows to the left of its line is parented above the
|
|
-- scroll frame's clip, so hiding the line no longer hides it.
|
|
line.superTrackButton.questId = nil
|
|
line.superTrackButton:Hide()
|
|
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
|