initial commit
This commit is contained in:
247
Modules/Tracker/GroupTrackerFrames.lua
Normal file
247
Modules/Tracker/GroupTrackerFrames.lua
Normal file
@@ -0,0 +1,247 @@
|
||||
local ADDON_NAME = "HailMaryGuildTools"
|
||||
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
||||
if not HMGT or not HMGT.TrackerManager then return end
|
||||
|
||||
local Manager = HMGT.TrackerManager
|
||||
local S = Manager._shared or {}
|
||||
|
||||
function Manager:EnsurePlayerFrame(tracker, playerName)
|
||||
local frameKey = S.GetTrackerFrameKey(tracker.id)
|
||||
self.perPlayerFrames[frameKey] = self.perPlayerFrames[frameKey] or {}
|
||||
local frame = self.perPlayerFrames[frameKey][playerName]
|
||||
if not frame then
|
||||
frame = HMGT.TrackerFrame:CreateTrackerFrame(S.GetTrackerPlayerFrameName(tracker.id, playerName), tracker)
|
||||
frame._hmgtTrackerId = tonumber(tracker.id) or 0
|
||||
frame._hmgtPlayerName = playerName
|
||||
self.perPlayerFrames[frameKey][playerName] = frame
|
||||
end
|
||||
frame._settings = tracker
|
||||
HMGT.TrackerFrame:SetTitle(frame, string.format("%s - %s", S.GetTrackerLabel(tracker), S.ShortName(playerName)))
|
||||
HMGT.TrackerFrame:SetLocked(frame, tracker.locked)
|
||||
return frame
|
||||
end
|
||||
|
||||
function Manager:HidePlayerFrames(frameKey)
|
||||
local frames = self.perPlayerFrames[frameKey]
|
||||
if type(frames) ~= "table" then
|
||||
self.activeOrders[frameKey] = nil
|
||||
self.unitByPlayer[frameKey] = nil
|
||||
self.anchorLayoutSignatures[frameKey] = nil
|
||||
self.nextAnchorRetryAt[frameKey] = nil
|
||||
self._displaySignatures[frameKey] = "0"
|
||||
return
|
||||
end
|
||||
for _, frame in pairs(frames) do
|
||||
frame:Hide()
|
||||
end
|
||||
self.activeOrders[frameKey] = nil
|
||||
self.unitByPlayer[frameKey] = nil
|
||||
self.anchorLayoutSignatures[frameKey] = nil
|
||||
self.nextAnchorRetryAt[frameKey] = nil
|
||||
self._displaySignatures[frameKey] = "0"
|
||||
end
|
||||
|
||||
function Manager:BuildEntriesByPlayerForTracker(tracker)
|
||||
local frameKey = S.GetTrackerFrameKey(tracker.id)
|
||||
local ownName = HMGT:NormalizePlayerName(UnitName("player")) or "Player"
|
||||
if tracker.testMode then
|
||||
local entries = self:CollectTestEntries(tracker)
|
||||
if S.IsGroupTracker(tracker) and tracker.attachToPartyFrame == true then
|
||||
return S.BuildPartyPreviewEntries(entries)
|
||||
end
|
||||
local byPlayer, order, unitByPlayer = {}, {}, {}
|
||||
if #entries > 0 then
|
||||
byPlayer[ownName] = entries
|
||||
order[1] = ownName
|
||||
unitByPlayer[ownName] = "player"
|
||||
end
|
||||
return byPlayer, order, unitByPlayer, true
|
||||
end
|
||||
if tracker.demoMode then
|
||||
local entries = HMGT:GetDemoEntries(frameKey, S.GetTrackerSpellPool(tracker.categories), tracker)
|
||||
if S.IsGroupTracker(tracker) and tracker.attachToPartyFrame == true then
|
||||
return S.BuildPartyPreviewEntries(entries)
|
||||
end
|
||||
for _, entry in ipairs(entries) do
|
||||
entry.playerName = ownName
|
||||
end
|
||||
local byPlayer, order, unitByPlayer = {}, {}, {}
|
||||
if #entries > 0 then
|
||||
byPlayer[ownName] = entries
|
||||
order[1] = ownName
|
||||
unitByPlayer[ownName] = "player"
|
||||
end
|
||||
return byPlayer, order, unitByPlayer, true
|
||||
end
|
||||
if not tracker.enabled or not HMGT:IsVisibleForCurrentGroup(tracker) then
|
||||
return {}, {}, {}, false
|
||||
end
|
||||
if IsInRaid() or not IsInGroup() then
|
||||
return {}, {}, {}, false
|
||||
end
|
||||
local byPlayer, order, unitByPlayer = {}, {}, {}
|
||||
for _, playerInfo in ipairs(S.GetGroupPlayers(tracker)) do
|
||||
local entries = S.CollectEntriesForPlayer(tracker, playerInfo)
|
||||
if #entries > 0 then
|
||||
local playerName = playerInfo.name
|
||||
byPlayer[playerName] = entries
|
||||
order[#order + 1] = playerName
|
||||
unitByPlayer[playerName] = playerInfo.unitId
|
||||
end
|
||||
end
|
||||
return byPlayer, order, unitByPlayer, true
|
||||
end
|
||||
|
||||
function Manager:RefreshPerGroupAnchors(tracker, force)
|
||||
local frameKey = S.GetTrackerFrameKey(tracker.id)
|
||||
local frames = self.perPlayerFrames[frameKey] or {}
|
||||
local ordered = {}
|
||||
for _, playerName in ipairs(self.activeOrders[frameKey] or {}) do
|
||||
local frame = frames[playerName]
|
||||
if frame and frame:IsShown() then
|
||||
ordered[#ordered + 1] = playerName
|
||||
end
|
||||
end
|
||||
if #ordered == 0 then
|
||||
self.anchorLayoutSignatures[frameKey] = nil
|
||||
self.nextAnchorRetryAt[frameKey] = nil
|
||||
return
|
||||
end
|
||||
local now = GetTime()
|
||||
local signature = S.BuildAnchorLayoutSignature(tracker, ordered, self.unitByPlayer[frameKey])
|
||||
if not force and self.anchorLayoutSignatures[frameKey] == signature then
|
||||
local retryAt = tonumber(self.nextAnchorRetryAt[frameKey]) or 0
|
||||
if retryAt <= 0 or now < retryAt then
|
||||
return
|
||||
end
|
||||
end
|
||||
for _, playerName in ipairs(ordered) do
|
||||
local frame = frames[playerName]
|
||||
if frame and frame._hmgtDragging then
|
||||
return
|
||||
end
|
||||
end
|
||||
if tracker.attachToPartyFrame == true then
|
||||
local side = tracker.partyAttachSide or "RIGHT"
|
||||
local extraX = tonumber(tracker.partyAttachOffsetX) or 8
|
||||
local extraY = tonumber(tracker.partyAttachOffsetY) or 0
|
||||
local growsUp = tracker.showBar == true and tracker.growDirection == "UP"
|
||||
local barHeight = tonumber(tracker.barHeight) or 20
|
||||
local growUpAttachOffset = barHeight + 20
|
||||
local prevPlaced = nil
|
||||
local missingTargets = 0
|
||||
for _, playerName in ipairs(ordered) do
|
||||
local frame = frames[playerName]
|
||||
local unitId = self.unitByPlayer[frameKey] and self.unitByPlayer[frameKey][playerName]
|
||||
local target = S.ResolveUnitAnchorFrame(unitId)
|
||||
local contentTopInset = HMGT.TrackerFrame.GetContentTopInset and HMGT.TrackerFrame:GetContentTopInset(frame) or 0
|
||||
frame:ClearAllPoints()
|
||||
if target then
|
||||
if side == "LEFT" then
|
||||
if growsUp then
|
||||
frame:SetPoint("BOTTOMRIGHT", target, "TOPLEFT", -extraX, extraY - growUpAttachOffset)
|
||||
else
|
||||
frame:SetPoint("TOPRIGHT", target, "TOPLEFT", -extraX, extraY + contentTopInset)
|
||||
end
|
||||
else
|
||||
if growsUp then
|
||||
frame:SetPoint("BOTTOMLEFT", target, "TOPRIGHT", extraX, extraY - growUpAttachOffset)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", target, "TOPRIGHT", extraX, extraY + contentTopInset)
|
||||
end
|
||||
end
|
||||
elseif prevPlaced then
|
||||
missingTargets = missingTargets + 1
|
||||
HMGT:DebugScoped("verbose", HMGT:GetTrackerDebugScope(tracker), "TrackerAttach fallback-stack tracker=%s player=%s unit=%s", tostring(tracker.id), tostring(playerName), tostring(unitId))
|
||||
if growsUp then
|
||||
frame:SetPoint("BOTTOMLEFT", prevPlaced, "TOPLEFT", 0, (tracker.barSpacing or 2) + 10)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", prevPlaced, "BOTTOMLEFT", 0, -((tracker.barSpacing or 2) + 10))
|
||||
end
|
||||
else
|
||||
missingTargets = missingTargets + 1
|
||||
HMGT:DebugScoped("info", HMGT:GetTrackerDebugScope(tracker), "TrackerAttach fallback-anchor tracker=%s player=%s unit=%s", tostring(tracker.id), tostring(playerName), tostring(unitId))
|
||||
HMGT.TrackerFrame:ApplyAnchor(frame)
|
||||
end
|
||||
frame:EnableMouse(false)
|
||||
prevPlaced = frame
|
||||
end
|
||||
if missingTargets > 0 then
|
||||
self.anchorLayoutSignatures[frameKey] = nil
|
||||
self.nextAnchorRetryAt[frameKey] = now + 1.0
|
||||
else
|
||||
self.anchorLayoutSignatures[frameKey] = signature
|
||||
self.nextAnchorRetryAt[frameKey] = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
local primary = frames[ordered[1]]
|
||||
HMGT.TrackerFrame:ApplyAnchor(primary)
|
||||
primary:EnableMouse(not tracker.locked)
|
||||
local gap = (tracker.barSpacing or 2) + 10
|
||||
local growsUp = tracker.showBar == true and tracker.growDirection == "UP"
|
||||
for index = 2, #ordered do
|
||||
local prev = frames[ordered[index - 1]]
|
||||
local frame = frames[ordered[index]]
|
||||
frame:ClearAllPoints()
|
||||
if growsUp then
|
||||
frame:SetPoint("BOTTOMLEFT", prev, "TOPLEFT", 0, gap)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", prev, "BOTTOMLEFT", 0, -gap)
|
||||
end
|
||||
frame:EnableMouse(false)
|
||||
end
|
||||
self.anchorLayoutSignatures[frameKey] = signature
|
||||
self.nextAnchorRetryAt[frameKey] = nil
|
||||
end
|
||||
|
||||
function Manager:UpdatePerGroupMemberTracker(tracker)
|
||||
local frameKey = S.GetTrackerFrameKey(tracker.id)
|
||||
local byPlayer, order, unitByPlayer, shouldShow = self:BuildEntriesByPlayerForTracker(tracker)
|
||||
self.activeOrders[frameKey] = order
|
||||
self.unitByPlayer[frameKey] = unitByPlayer
|
||||
local active, shownOrder = {}, {}
|
||||
local shownByPlayer = {}
|
||||
local entryCount, shouldTick = 0, false
|
||||
for _, playerName in ipairs(order) do
|
||||
local frame = self:EnsurePlayerFrame(tracker, playerName)
|
||||
local entries = byPlayer[playerName] or {}
|
||||
if HMGT.FilterDisplayEntries then
|
||||
entries = HMGT:FilterDisplayEntries(tracker, entries) or entries
|
||||
end
|
||||
if HMGT.SortDisplayEntries then
|
||||
HMGT:SortDisplayEntries(entries)
|
||||
end
|
||||
if #entries > 0 then
|
||||
HMGT.TrackerFrame:UpdateFrame(frame, entries, true)
|
||||
frame:Show()
|
||||
active[playerName] = true
|
||||
shownOrder[#shownOrder + 1] = playerName
|
||||
shownByPlayer[playerName] = entries
|
||||
entryCount = entryCount + #entries
|
||||
for _, entry in ipairs(entries) do
|
||||
if S.EntryNeedsVisualTicker(entry) then
|
||||
shouldTick = true
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
frame:Hide()
|
||||
end
|
||||
end
|
||||
for playerName, frame in pairs(self.perPlayerFrames[frameKey] or {}) do
|
||||
if not active[playerName] then
|
||||
frame:Hide()
|
||||
end
|
||||
end
|
||||
self.activeOrders[frameKey] = shownOrder
|
||||
self.unitByPlayer[frameKey] = unitByPlayer
|
||||
self._displaySignatures[frameKey] = S.BuildGroupDisplaySignature and S.BuildGroupDisplaySignature(shownOrder, shownByPlayer) or nil
|
||||
if shouldShow and #shownOrder > 0 then
|
||||
self:RefreshPerGroupAnchors(tracker, false)
|
||||
return true, entryCount, shouldTick
|
||||
end
|
||||
self:HidePlayerFrames(frameKey)
|
||||
self._displaySignatures[frameKey] = "0"
|
||||
return false, 0, false
|
||||
end
|
||||
Reference in New Issue
Block a user