You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1576 lines
54 KiB
1576 lines
54 KiB
-- Who objects to the ObjectiveTracker...?
|
|
|
|
KT_OBJECTIVE_TRACKER_ITEM_WIDTH = 33; -- 1
|
|
KT_OBJECTIVE_TRACKER_HEADER_HEIGHT = 25;
|
|
KT_OBJECTIVE_TRACKER_LINE_WIDTH = 248;
|
|
KT_OBJECTIVE_TRACKER_HEADER_OFFSET_X = -10;
|
|
-- calculated values
|
|
KT_OBJECTIVE_TRACKER_DASH_WIDTH = 0;
|
|
KT_OBJECTIVE_TRACKER_TEXT_WIDTH = 0;
|
|
|
|
KT_OBJECTIVE_TRACKER_COLOR = {
|
|
["Normal"] = { r = 0.8, g = 0.8, b = 0.8 },
|
|
["NormalHighlight"] = { r = HIGHLIGHT_FONT_COLOR.r, g = HIGHLIGHT_FONT_COLOR.g, b = HIGHLIGHT_FONT_COLOR.b },
|
|
["Failed"] = { r = DIM_RED_FONT_COLOR.r, g = DIM_RED_FONT_COLOR.g, b = DIM_RED_FONT_COLOR.b },
|
|
["FailedHighlight"] = { r = RED_FONT_COLOR.r, g = RED_FONT_COLOR.g, b = RED_FONT_COLOR.b },
|
|
["Header"] = { r = 0.75, g = 0.61, b = 0 },
|
|
["HeaderHighlight"] = { r = NORMAL_FONT_COLOR.r, g = NORMAL_FONT_COLOR.g, b = NORMAL_FONT_COLOR.b },
|
|
["Complete"] = { r = 0.6, g = 0.6, b = 0.6 },
|
|
["TimeLeft"] = { r = DIM_RED_FONT_COLOR.r, g = DIM_RED_FONT_COLOR.g, b = DIM_RED_FONT_COLOR.b },
|
|
["TimeLeftHighlight"] = { r = RED_FONT_COLOR.r, g = RED_FONT_COLOR.g, b = RED_FONT_COLOR.b },
|
|
};
|
|
KT_OBJECTIVE_TRACKER_COLOR["Normal"].reverse = KT_OBJECTIVE_TRACKER_COLOR["NormalHighlight"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["NormalHighlight"].reverse = KT_OBJECTIVE_TRACKER_COLOR["Normal"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["Failed"].reverse = KT_OBJECTIVE_TRACKER_COLOR["FailedHighlight"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["FailedHighlight"].reverse = KT_OBJECTIVE_TRACKER_COLOR["Failed"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["Header"].reverse = KT_OBJECTIVE_TRACKER_COLOR["HeaderHighlight"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["HeaderHighlight"].reverse = KT_OBJECTIVE_TRACKER_COLOR["Header"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["TimeLeft"].reverse = KT_OBJECTIVE_TRACKER_COLOR["TimeLeftHighlight"];
|
|
KT_OBJECTIVE_TRACKER_COLOR["TimeLeftHighlight"].reverse = KT_OBJECTIVE_TRACKER_COLOR["TimeLeft"];
|
|
|
|
|
|
-- these are generally from events
|
|
KT_OBJECTIVE_TRACKER_UPDATE_QUEST = 0x00001;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED = 0x00002;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_TASK_ADDED = 0x00004;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_WORLD_QUEST_ADDED = 0x00008;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO = 0x00010;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE = 0x00020;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT = 0x00040;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED = 0x00080;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED = 0x00100;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_SUPER_TRACK_CHANGED = 0x00200;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MOVED = 0x80000;
|
|
-- these are for the specific module ONLY!
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST = 0x00400;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP = 0x00800;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE = 0x01000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_WORLD_QUEST = 0x02000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO = 0x04000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT = 0x08000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO_SPELLS = 0x10000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_UI_WIDGETS = 0x20000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_PROFESSION_RECIPE = 0x40000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_MODULE_MONTHLY_ACTIVITIES = 0x100000; -- fix Blizz bug (0x80000)
|
|
|
|
-- special updates
|
|
KT_OBJECTIVE_TRACKER_UPDATE_STATIC = 0x0000;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_ALL = 0xFFFFFFFF;
|
|
|
|
KT_OBJECTIVE_TRACKER_UPDATE_REASON = KT_OBJECTIVE_TRACKER_UPDATE_ALL; -- default
|
|
KT_OBJECTIVE_TRACKER_UPDATE_ID = 0;
|
|
|
|
-- speed optimizations
|
|
local floor = math.floor;
|
|
local min = min;
|
|
local band = bit.band;
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** MODULE STUFF
|
|
-- *****************************************************************************************************
|
|
|
|
--[[
|
|
blockTemplate: template for the blocks - a quest would be a single block
|
|
blockType: type of object
|
|
lineTemplate: template for the lines - a quest objective would be a single line (even if it wordwraps); only FRAME supported
|
|
lineSpacing: spacing between lines; for the first line it'll be the distance from the top of its block
|
|
blockOffsetX: offset from the left edge of the blocksframe \__These are both added to a table indexed by blockTemplate.
|
|
blockOffsetY: offset from the block above /
|
|
fromHeaderOffsetY: offset from the header for the first block, if there's a header; used instead of blockOffsetY
|
|
fromModuleOffsetY: offset from the previous module
|
|
poolCollection: pool of (potentially) multiple frame types for use in a module
|
|
usedBlocks: table of used blocks; a module should always have its own, this table uses template type so that GetBlock(id) ALWAYS returns
|
|
the correct frame that already exists (for animation purposes)
|
|
freelines: table of free lines; a module needs it own if not using default line template
|
|
there's no table of used lines, that's per block
|
|
updateReasonModule: the update for this module alone
|
|
updateReasonEvents: the events which should update the module
|
|
=== modules do not need to change these, they're keyed by block & line ===
|
|
usedTimerBars: table of used timer bars
|
|
freeTimerBars: table of free timer bars
|
|
=== modules should NOT change these ===
|
|
contentsHeight: the current combined height of all the blocks in the module
|
|
contentsAnimHeight: the current combined animation height of all the blocks in the module
|
|
oldContentsHeight: the previous height on the last update
|
|
hasSkippedBlocks: if the module couldn't display all its blocks because of not enough space
|
|
--]]
|
|
|
|
KT_DEFAULT_OBJECTIVE_TRACKER_MODULE = {};
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:OnLoad(friendlyName, defaultTemplate)
|
|
self.friendlyName = friendlyName or "UnnamedTrackerModule";
|
|
self.blockTemplate = defaultTemplate or "KT_ObjectiveTrackerBlockTemplate";
|
|
self.blockType = "Frame";
|
|
self.lineTemplate = "KT_ObjectiveTrackerLineTemplate";
|
|
self.lineSpacing = 2;
|
|
self.lineWidth = KT_OBJECTIVE_TRACKER_TEXT_WIDTH;
|
|
self.poolCollection = CreateFramePoolCollection();
|
|
self.usedBlocks = { };
|
|
self.freeLines = { };
|
|
self.fromHeaderOffsetY = -10;
|
|
self.fromModuleOffsetY = -10;
|
|
self.contentsHeight = 0;
|
|
self.contentsAnimHeight = 0;
|
|
self.oldContentsHeight = 0;
|
|
self.hasSkippedBlocks = false;
|
|
self.usedTimerBars = { };
|
|
self.freeTimerBars = { };
|
|
self.usedProgressBars = { };
|
|
self.freeProgressBars = { };
|
|
self.updateReasonModule = 0;
|
|
self.updateReasonEvents = 0;
|
|
|
|
self.BlocksFrame = KT_ObjectiveTrackerFrame.BlocksFrame;
|
|
|
|
KT_DEFAULT_OBJECTIVE_TRACKER_MODULE.AddBlockOffset(self, self.blockTemplate, 0, -6);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_GetModuleInfoTable(friendlyName, baseModule, defaultTemplate)
|
|
local info = CreateFromMixins(baseModule or KT_DEFAULT_OBJECTIVE_TRACKER_MODULE);
|
|
info:OnLoad(friendlyName, defaultTemplate);
|
|
return info;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:BeginLayout(isStaticReanchor)
|
|
self.topBlock = nil; -- this is the header or the first block for header-less modules
|
|
self.firstBlock = nil; -- this is the first non-header block
|
|
self.lastBlock = nil;
|
|
self.oldContentsHeight = self.contentsHeight;
|
|
self.contentsHeight = 0;
|
|
self.contentsAnimHeight = 0;
|
|
self.potentialBlocksAddedThisLayout = 0; -- this isn't a ref count, this is the total number of blocks that the module tried to add.
|
|
-- if it's not a static reanchor, reset whether we've skipped blocks
|
|
if ( not isStaticReanchor ) then
|
|
self.hasSkippedBlocks = false;
|
|
|
|
if not self:UsesSharedHeader() and self.Header then
|
|
self.Header:Hide();
|
|
end
|
|
end
|
|
self:MarkBlocksUnused();
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:EndLayout(isStaticReanchor)
|
|
-- isStaticReanchor not used yet
|
|
self.lastBlock = self.BlocksFrame.currentBlock;
|
|
self:FreeUnusedBlocks();
|
|
end
|
|
|
|
-- ***** BLOCKS
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:SetHeader(block, text, animateReason)
|
|
block.module = self;
|
|
block.isHeader = true;
|
|
block.Text:SetText(text);
|
|
block.animateReason = animateReason or 0;
|
|
self.Header = block;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:SetSharedHeader(block)
|
|
self.Header = block;
|
|
self.usesSharedHeader = true;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:UsesSharedHeader()
|
|
return self.usesSharedHeader;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetBlock(id, overrideType, overrideTemplate)
|
|
local blockType = overrideType or self.blockType;
|
|
local blockTemplate = overrideTemplate or self.blockTemplate;
|
|
|
|
if not self.usedBlocks[blockTemplate] then
|
|
self.usedBlocks[blockTemplate] = {};
|
|
end
|
|
|
|
-- first try to return existing block
|
|
local block = self.usedBlocks[blockTemplate][id];
|
|
|
|
if not block then
|
|
local pool = self.poolCollection:GetOrCreatePool(blockType, self.BlocksFrame or KT_ObjectiveTrackerFrame.BlocksFrame, blockTemplate);
|
|
|
|
local isNewBlock = nil;
|
|
block, isNewBlock = pool:Acquire(blockTemplate);
|
|
|
|
if isNewBlock then
|
|
block.blockTemplate = blockTemplate; -- stored so we can use it to free from the lookup later
|
|
block.lines = {};
|
|
end
|
|
|
|
self.usedBlocks[blockTemplate][id] = block;
|
|
block.id = id;
|
|
block.module = self;
|
|
end
|
|
|
|
block.used = true;
|
|
block.height = 0;
|
|
block.currentLine = nil;
|
|
|
|
-- prep lines
|
|
if block.lines then
|
|
for objectiveKey, line in pairs(block.lines) do
|
|
line.used = nil;
|
|
end
|
|
end
|
|
|
|
return block;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetExistingBlock(id, overrideTemplate)
|
|
local template = overrideTemplate or self.blockTemplate;
|
|
assert(template);
|
|
assert(self.usedBlocks)
|
|
|
|
local blocks = self.usedBlocks[template];
|
|
if blocks then
|
|
return blocks[id];
|
|
end
|
|
|
|
return nil;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:MarkBlocksUnused()
|
|
for blockTemplate, blockTable in pairs(self.usedBlocks) do
|
|
for blockID, block in pairs(blockTable) do
|
|
block.used = nil;
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeBlock(block)
|
|
-- free all the lines
|
|
for _, line in pairs(block.lines) do
|
|
self:FreeLine(block, line);
|
|
end
|
|
block.lines = { };
|
|
|
|
-- free the block
|
|
self.usedBlocks[block.blockTemplate][block.id] = nil;
|
|
self.poolCollection:Release(block);
|
|
|
|
-- callback
|
|
if ( self.OnFreeBlock ) then
|
|
self:OnFreeBlock(block);
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeUnusedBlocks()
|
|
for blockTemplate, blockTable in pairs(self.usedBlocks) do
|
|
for blockID, block in pairs(blockTable) do
|
|
if not block.used then
|
|
self:FreeBlock(block);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetBlockCount()
|
|
local count = 0;
|
|
local modules = self:GetRelatedModules();
|
|
for index, module in ipairs(modules) do
|
|
count = count + (module.potentialBlocksAddedThisLayout or 0);
|
|
end
|
|
|
|
return count;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetActiveBlocks(blockTemplate)
|
|
-- By default use the module's preferred block type.
|
|
blockTemplate = blockTemplate or self.blockTemplate;
|
|
if not self.usedBlocks[blockTemplate] then
|
|
self.usedBlocks[blockTemplate] = {};
|
|
end
|
|
|
|
return self.usedBlocks[blockTemplate];
|
|
end
|
|
|
|
-- ***** LINES
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeLine(block, line)
|
|
block.lines[line.objectiveKey] = nil;
|
|
-- if the line has a type, the freeLines will be the cache for that type of line, otherwise use the module's default
|
|
local freeLines = (line.type and line.type.freeLines) or self.freeLines;
|
|
tinsert(freeLines, line);
|
|
-- remove timer bar
|
|
if ( line.TimerBar ) then
|
|
self:FreeTimerBar(block, line);
|
|
end
|
|
if ( line.ProgressBar ) then
|
|
self:FreeProgressBar(block, line);
|
|
end
|
|
if ( line.type and self.OnFreeTypedLine ) then
|
|
self:OnFreeTypedLine(line);
|
|
elseif ( self.OnFreeLine ) then
|
|
self:OnFreeLine(line);
|
|
end
|
|
|
|
line:Hide();
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeUnusedLines(block)
|
|
for objectiveKey, line in pairs(block.lines) do
|
|
if ( not line.used ) then
|
|
self:FreeLine(block, line);
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetLine(block, objectiveKey, lineType)
|
|
-- first look for existing line
|
|
local line = block.lines[objectiveKey];
|
|
|
|
-- if existing line is not of the same type, discard it
|
|
if ( line and line.type ~= lineType ) then
|
|
self:FreeLine(block, line);
|
|
line = nil;
|
|
end
|
|
|
|
if ( line ) then
|
|
line.used = true;
|
|
return line;
|
|
end
|
|
|
|
local freeLines = (lineType and lineType.freeLines) or self.freeLines;
|
|
local numFreeLines = #freeLines;
|
|
local parent = block.ScrollContents or block;
|
|
if ( numFreeLines > 0 ) then
|
|
-- get a free line
|
|
line = freeLines[numFreeLines];
|
|
tremove(freeLines, numFreeLines);
|
|
line:SetParent(parent);
|
|
line:Show();
|
|
else
|
|
-- create a new line
|
|
line = CreateFrame("Frame", nil, parent, (lineType and lineType.template) or self.lineTemplate);
|
|
line.type = lineType;
|
|
end
|
|
block.lines[objectiveKey] = line;
|
|
line.objectiveKey = objectiveKey;
|
|
line.used = true;
|
|
return line;
|
|
end
|
|
|
|
-- ***** OBJECTIVES
|
|
KT_OBJECTIVE_DASH_STYLE_SHOW = 1;
|
|
KT_OBJECTIVE_DASH_STYLE_HIDE = 2;
|
|
KT_OBJECTIVE_DASH_STYLE_HIDE_AND_COLLAPSE = 3;
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddObjective(block, objectiveKey, text, lineType, useFullHeight, dashStyle, colorStyle, adjustForNoText, overrideHeight)
|
|
local line = self:GetLine(block, objectiveKey, lineType);
|
|
-- width
|
|
if ( block.lineWidth ~= line.width ) then
|
|
line.Text:SetWidth(block.lineWidth or self.lineWidth);
|
|
line.width = block.lineWidth; -- default should be nil
|
|
end
|
|
-- dash
|
|
if ( line.Dash ) then
|
|
if ( not dashStyle ) then
|
|
dashStyle = KT_OBJECTIVE_DASH_STYLE_SHOW;
|
|
end
|
|
if ( line.dashStyle ~= dashStyle ) then
|
|
if ( dashStyle == KT_OBJECTIVE_DASH_STYLE_SHOW ) then
|
|
line.Dash:Show();
|
|
line.Dash:SetText(QUEST_DASH);
|
|
elseif ( dashStyle == KT_OBJECTIVE_DASH_STYLE_HIDE ) then
|
|
line.Dash:Hide();
|
|
line.Dash:SetText(QUEST_DASH);
|
|
elseif ( dashStyle == KT_OBJECTIVE_DASH_STYLE_HIDE_AND_COLLAPSE ) then
|
|
line.Dash:Hide();
|
|
line.Dash:SetText(nil);
|
|
else
|
|
error("Invalid dash style: " .. tostring(dashStyle));
|
|
end
|
|
line.dashStyle = dashStyle;
|
|
end
|
|
end
|
|
|
|
-- set the text
|
|
local textHeight = self:SetStringText(line.Text, text, useFullHeight, colorStyle, block.isHighlighted);
|
|
local height = overrideHeight or textHeight;
|
|
line:SetHeight(height);
|
|
|
|
local yOffset;
|
|
|
|
if ( adjustForNoText and text == "" ) then
|
|
-- don't change the height
|
|
-- move the line up so the next object ends up in the same position as if there had been no line
|
|
yOffset = height;
|
|
else
|
|
block.height = block.height + height + block.module.lineSpacing;
|
|
yOffset = -block.module.lineSpacing;
|
|
end
|
|
-- anchor the line
|
|
local anchor = block.currentLine or block.HeaderText;
|
|
if ( anchor ) then
|
|
line:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, yOffset);
|
|
else
|
|
line:SetPoint("TOPLEFT", 0, yOffset);
|
|
end
|
|
block.currentLine = line;
|
|
return line;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:SetStringText(fontString, text, useFullHeight, colorStyle, useHighlight)
|
|
if useFullHeight then
|
|
fontString:SetMaxLines(0);
|
|
else
|
|
fontString:SetMaxLines(2);
|
|
end
|
|
fontString:SetText(text);
|
|
|
|
local stringHeight = fontString:GetHeight();
|
|
colorStyle = colorStyle or KT_OBJECTIVE_TRACKER_COLOR["Normal"];
|
|
if ( useHighlight and colorStyle.reverse ) then
|
|
colorStyle = colorStyle.reverse;
|
|
end
|
|
if ( fontString.colorStyle ~= colorStyle ) then
|
|
fontString:SetTextColor(colorStyle.r, colorStyle.g, colorStyle.b);
|
|
fontString.colorStyle = colorStyle;
|
|
end
|
|
return stringHeight;
|
|
end
|
|
|
|
-- ***** BLOCK HEADER
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:SetBlockHeader(block, text)
|
|
local height = self:SetStringText(block.HeaderText, text, nil, KT_OBJECTIVE_TRACKER_COLOR["Header"], block.isHighlighted);
|
|
block.height = height;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:OnBlockHeaderClick(block, mouseButton)
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:OnBlockHeaderEnter(block)
|
|
--block.isHighlighted = true; -- MSA
|
|
if not block.isHighlighted then -- MSA
|
|
if ( block.HeaderText ) then
|
|
local headerColorStyle = KT_OBJECTIVE_TRACKER_COLOR["HeaderHighlight"];
|
|
block.HeaderText:SetTextColor(headerColorStyle.r, headerColorStyle.g, headerColorStyle.b);
|
|
block.HeaderText.colorStyle = headerColorStyle;
|
|
end
|
|
for objectiveKey, line in pairs(block.lines) do
|
|
local colorStyle = line.Text.colorStyle.reverse;
|
|
if ( colorStyle ) then
|
|
line.Text:SetTextColor(colorStyle.r, colorStyle.g, colorStyle.b);
|
|
line.Text.colorStyle = colorStyle;
|
|
if ( line.Dash ) then
|
|
line.Dash:SetTextColor(KT_OBJECTIVE_TRACKER_COLOR["NormalHighlight"].r, KT_OBJECTIVE_TRACKER_COLOR["NormalHighlight"].g, KT_OBJECTIVE_TRACKER_COLOR["NormalHighlight"].b);
|
|
end
|
|
end
|
|
end
|
|
block.isHighlighted = true; -- MSA
|
|
end -- MSA
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:OnBlockHeaderLeave(block)
|
|
block.isHighlighted = nil;
|
|
if ( block.HeaderText ) then
|
|
local headerColorStyle = KT_OBJECTIVE_TRACKER_COLOR["Header"];
|
|
block.HeaderText:SetTextColor(headerColorStyle.r, headerColorStyle.g, headerColorStyle.b);
|
|
block.HeaderText.colorStyle = headerColorStyle;
|
|
end
|
|
for objectiveKey, line in pairs(block.lines) do
|
|
local colorStyle = line.Text.colorStyle.reverse;
|
|
if ( colorStyle ) then
|
|
line.Text:SetTextColor(colorStyle.r, colorStyle.g, colorStyle.b);
|
|
line.Text.colorStyle = colorStyle;
|
|
if ( line.Dash ) then
|
|
line.Dash:SetTextColor(KT_OBJECTIVE_TRACKER_COLOR["Normal"].r, KT_OBJECTIVE_TRACKER_COLOR["Normal"].g, KT_OBJECTIVE_TRACKER_COLOR["Normal"].b);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ***** TIMER BAR
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddTimerBar(block, line, duration, startTime)
|
|
local timerBar = self.usedTimerBars[block] and self.usedTimerBars[block][line];
|
|
if ( not timerBar ) then
|
|
local numFreeTimerBars = #self.freeTimerBars;
|
|
local parent = block.ScrollContents or block;
|
|
if ( numFreeTimerBars > 0 ) then
|
|
timerBar = self.freeTimerBars[numFreeTimerBars];
|
|
tremove(self.freeTimerBars, numFreeTimerBars);
|
|
timerBar:SetParent(parent);
|
|
timerBar:Show();
|
|
else
|
|
timerBar = CreateFrame("Frame", nil, parent, "KT_ObjectiveTrackerTimerBarTemplate");
|
|
timerBar.Label:SetPoint("LEFT", KT_OBJECTIVE_TRACKER_DASH_WIDTH, 0);
|
|
timerBar.height = timerBar:GetHeight();
|
|
end
|
|
if ( not self.usedTimerBars[block] ) then
|
|
self.usedTimerBars[block] = { };
|
|
end
|
|
self.usedTimerBars[block][line] = timerBar;
|
|
timerBar:Show();
|
|
end
|
|
-- anchor the status bar
|
|
local anchor = block.currentLine or block.HeaderText;
|
|
if ( anchor ) then
|
|
timerBar:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -block.module.lineSpacing);
|
|
else
|
|
timerBar:SetPoint("TOPLEFT", 0, -block.module.lineSpacing);
|
|
end
|
|
|
|
timerBar.Bar:SetMinMaxValues(0, duration);
|
|
timerBar.duration = duration;
|
|
timerBar.startTime = startTime;
|
|
timerBar.block = block;
|
|
|
|
line.TimerBar = timerBar;
|
|
block.height = block.height + timerBar.height + block.module.lineSpacing;
|
|
block.currentLine = timerBar;
|
|
return timerBar;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeTimerBar(block, line)
|
|
local timerBar = line.TimerBar;
|
|
if ( timerBar ) then
|
|
self.usedTimerBars[block][line] = nil;
|
|
tinsert(self.freeTimerBars, timerBar);
|
|
timerBar:Hide();
|
|
line.TimerBar = nil;
|
|
end
|
|
end
|
|
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** PROGRESS BAR
|
|
-- *****************************************************************************************************
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddProgressBar(block, line, questID)
|
|
local progressBar = self.usedProgressBars[block] and self.usedProgressBars[block][line];
|
|
if ( not progressBar ) then
|
|
local numFreeProgressBars = #self.freeProgressBars;
|
|
local parent = block.ScrollContents or block;
|
|
if ( numFreeProgressBars > 0 ) then
|
|
progressBar = self.freeProgressBars[numFreeProgressBars];
|
|
tremove(self.freeProgressBars, numFreeProgressBars);
|
|
progressBar:SetParent(parent);
|
|
progressBar:Show();
|
|
else
|
|
progressBar = CreateFrame("Frame", nil, parent, "KT_ObjectiveTrackerProgressBarTemplate");
|
|
progressBar.height = progressBar:GetHeight();
|
|
end
|
|
if ( not self.usedProgressBars[block] ) then
|
|
self.usedProgressBars[block] = { };
|
|
end
|
|
self.usedProgressBars[block][line] = progressBar;
|
|
progressBar:RegisterEvent("QUEST_LOG_UPDATE");
|
|
progressBar:Show();
|
|
-- initialize to the right values
|
|
progressBar.questID = questID;
|
|
KT_ObjectiveTrackerProgressBar_SetValue(progressBar, GetQuestProgressBarPercent(questID));
|
|
end
|
|
-- anchor the status bar
|
|
local anchor = block.currentLine or block.HeaderText;
|
|
if ( anchor ) then
|
|
progressBar:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -block.module.lineSpacing);
|
|
else
|
|
progressBar:SetPoint("TOPLEFT", 0, -block.module.lineSpacing);
|
|
end
|
|
|
|
progressBar.block = block;
|
|
progressBar.questID = questID;
|
|
|
|
|
|
line.ProgressBar = progressBar;
|
|
block.height = block.height + progressBar.height + block.module.lineSpacing;
|
|
block.currentLine = progressBar;
|
|
return progressBar;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:FreeProgressBar(block, line)
|
|
local progressBar = line.ProgressBar;
|
|
if ( progressBar ) then
|
|
self.usedProgressBars[block][line] = nil;
|
|
tinsert(self.freeProgressBars, progressBar);
|
|
progressBar:Hide();
|
|
line.ProgressBar = nil;
|
|
progressBar:UnregisterEvent("QUEST_LOG_UPDATE");
|
|
end
|
|
end
|
|
|
|
local function ObjectiveTracker_SetModulesCollapsed(collapsed, modules)
|
|
for index, module in ipairs(modules) do
|
|
module.collapsed = collapsed;
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:GetRelatedModules()
|
|
-- Default implementation, most single/shared modules can be found this way
|
|
-- NOTE: This actually inserts self as well, since the header matches, that's fine.
|
|
local modules = {};
|
|
local header = self.Header;
|
|
for index, module in ipairs(KT_ObjectiveTrackerFrame.MODULES) do
|
|
if module.Header == header then
|
|
table.insert(modules, module);
|
|
end
|
|
end
|
|
|
|
return modules;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:SetCollapsed(collapsed)
|
|
ObjectiveTracker_SetModulesCollapsed(collapsed, self:GetRelatedModules());
|
|
|
|
if self.Header and self.Header.MinimizeButton then
|
|
self.Header.MinimizeButton:SetCollapsed(collapsed);
|
|
end
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:IsCollapsed()
|
|
return self.collapsed;
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** MODULE/BLOCK CUSTOMIZATION
|
|
-- *****************************************************************************************************
|
|
|
|
local function ObjectiveTracker_AddCustomizationData(module, customizationKey, template, data)
|
|
if not module[customizationKey] then
|
|
module[customizationKey] = {};
|
|
end
|
|
|
|
module[customizationKey][template] = data;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddButtonOffsets(template, offsets)
|
|
ObjectiveTracker_AddCustomizationData(self, "buttonOffsets", template, offsets);
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddBlockOffset(template, x, y)
|
|
ObjectiveTracker_AddCustomizationData(self, "blockOffset", template, { x or 0, y or 0 });
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:AddPaddingBetweenButtons(template, padding)
|
|
ObjectiveTracker_AddCustomizationData(self, "paddingBetweenButtons", template, padding);
|
|
end
|
|
|
|
local function GetBlockTemplate(block)
|
|
return block.blockTemplate or block.module.blockTemplate;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_GetButtonOffsets(block, offsetTag)
|
|
local offsets = block.module.buttonOffsets;
|
|
if offsets then
|
|
return unpack(offsets[GetBlockTemplate(block)][offsetTag]);
|
|
end
|
|
|
|
return 0, 0;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_GetBlockOffset(block)
|
|
local offset = block.module.blockOffset;
|
|
if offset then
|
|
return unpack(offset[GetBlockTemplate(block)]);
|
|
end
|
|
|
|
return 0, 0;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_GetPaddingBetweenButtons(block)
|
|
local padding = block.module.paddingBetweenButtons;
|
|
if padding then
|
|
return padding[GetBlockTemplate(block)];
|
|
end
|
|
|
|
return 0;
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** BLOCK HEADER HANDLERS
|
|
-- *****************************************************************************************************
|
|
|
|
function KT_ObjectiveTrackerBlockHeader_OnLoad(self)
|
|
|
|
self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
|
|
self.GetDebugReportInfo = KT_ObjectiveTrackerBlockHeader_GetDebugReportInfo;
|
|
end
|
|
|
|
function KT_ObjectiveTrackerBlockHeader_OnClick(self, mouseButton)
|
|
local block = self:GetParent();
|
|
block.module:OnBlockHeaderClick(block, mouseButton);
|
|
end
|
|
|
|
function KT_ObjectiveTrackerBlockHeader_OnEnter(self)
|
|
local block = self:GetParent();
|
|
block.module:OnBlockHeaderEnter(block);
|
|
end
|
|
|
|
function KT_ObjectiveTrackerBlockHeader_OnLeave(self)
|
|
local block = self:GetParent();
|
|
block.module:OnBlockHeaderLeave(block);
|
|
end
|
|
|
|
function KT_ObjectiveTrackerBlockHeader_GetDebugReportInfo(self)
|
|
local block = self:GetParent();
|
|
|
|
if block.module.GetDebugReportInfo then
|
|
return block.module:GetDebugReportInfo(block);
|
|
end
|
|
|
|
return nil;
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** OBJECTIVE TRACKER LINES
|
|
-- *****************************************************************************************************
|
|
|
|
function KT_ObjectiveTrackerCheckLine_OnHide(self)
|
|
self.Glow.Anim:Stop();
|
|
self.Sheen.Anim:Stop();
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** TIMER BARS
|
|
-- *****************************************************************************************************
|
|
|
|
function KT_ObjectiveTrackerTimerBar_OnUpdate(self, elapsed)
|
|
local timeNow = GetTime();
|
|
local timeRemaining = self.duration - (timeNow - self.startTime);
|
|
self.Bar:SetValue(timeRemaining);
|
|
if ( timeRemaining < 0 ) then
|
|
-- hold at 0 for a moment
|
|
if ( timeRemaining > -1 ) then
|
|
timeRemaining = 0;
|
|
else
|
|
KT_ObjectiveTracker_Update(self.block.module.updateReasonModule);
|
|
return;
|
|
end
|
|
end
|
|
self.Label:SetText(SecondsToClock(timeRemaining));
|
|
self.Label:SetTextColor(KT_ObjectiveTrackerTimerBar_GetTextColor(self.duration, self.duration - timeRemaining));
|
|
end
|
|
|
|
function KT_ObjectiveTrackerTimerBar_GetTextColor(duration, elapsed)
|
|
local START_PERCENTAGE_YELLOW = .66
|
|
local START_PERCENTAGE_RED = .33
|
|
|
|
local percentageLeft = 1 - ( elapsed / duration )
|
|
if ( percentageLeft > START_PERCENTAGE_YELLOW ) then
|
|
return 1, 1, 1;
|
|
elseif ( percentageLeft > START_PERCENTAGE_RED ) then -- Start fading to yellow by eliminating blue
|
|
local blueOffset = (percentageLeft - START_PERCENTAGE_RED) / (START_PERCENTAGE_YELLOW - START_PERCENTAGE_RED);
|
|
return 1, 1, blueOffset;
|
|
else
|
|
local greenOffset = percentageLeft / START_PERCENTAGE_RED; -- Fade to red by eliminating green
|
|
return 1, greenOffset, 0;
|
|
end
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** PROGRESS BARS
|
|
-- *****************************************************************************************************
|
|
function KT_ObjectiveTrackerProgressBar_SetValue(self, percent)
|
|
self.Bar:SetValue(percent);
|
|
self.Bar.Label:SetFormattedText(PERCENTAGE_STRING, percent);
|
|
end
|
|
|
|
function KT_ObjectiveTrackerProgressBar_OnEvent(self)
|
|
KT_ObjectiveTrackerProgressBar_SetValue(self, GetQuestProgressBarPercent(self.questID));
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** FRAME HANDLERS
|
|
-- *****************************************************************************************************
|
|
|
|
function KT_ObjectiveTracker_OnLoad(self)
|
|
KT_DEFAULT_OBJECTIVE_TRACKER_MODULE.OnLoad(self, "KT_DEFAULT_OBJECTIVE_TRACKER_MODULE");
|
|
|
|
-- create a line so we can get some measurements
|
|
local line = CreateFrame("Frame", nil, self, self.lineTemplate);
|
|
line.Text:SetText("Double line|ntest");
|
|
-- reuse it
|
|
tinsert(self.freeLines, line);
|
|
-- get measurements
|
|
KT_OBJECTIVE_TRACKER_DASH_WIDTH = line.Dash:GetWidth();
|
|
KT_OBJECTIVE_TRACKER_TEXT_WIDTH = KT_OBJECTIVE_TRACKER_LINE_WIDTH - KT_OBJECTIVE_TRACKER_DASH_WIDTH - 12;
|
|
line.Text:SetWidth(KT_OBJECTIVE_TRACKER_TEXT_WIDTH);
|
|
|
|
local frameLevel = self.BlocksFrame:GetFrameLevel();
|
|
self.HeaderMenu:SetFrameLevel(frameLevel + 2);
|
|
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD");
|
|
|
|
--UIDropDownMenu_Initialize(self.BlockDropDown, nil, "MENU");
|
|
QuestPOI_Initialize(self.BlocksFrame, function(self) self:SetScale(0.9); self:RegisterForClicks("LeftButtonUp", "RightButtonUp"); end );
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnShow(self)
|
|
-- UIParentManagedFrameMixin.OnShow(self);
|
|
-- KT_ObjectiveTracker_UpdateHeight();
|
|
end
|
|
|
|
function KT_ObjectiveTracker_Initialize(self)
|
|
self.MODULES = { KT_SCENARIO_CONTENT_TRACKER_MODULE,
|
|
KT_UI_WIDGET_TRACKER_MODULE,
|
|
KT_BONUS_OBJECTIVE_TRACKER_MODULE,
|
|
KT_WORLD_QUEST_TRACKER_MODULE,
|
|
KT_CAMPAIGN_QUEST_TRACKER_MODULE,
|
|
KT_QUEST_TRACKER_MODULE,
|
|
KT_ACHIEVEMENT_TRACKER_MODULE,
|
|
KT_PROFESSION_RECIPE_TRACKER_MODULE,
|
|
KT_MONTHLY_ACTIVITIES_TRACKER_MODULE,
|
|
};
|
|
self.MODULES_UI_ORDER = { KT_SCENARIO_CONTENT_TRACKER_MODULE,
|
|
KT_UI_WIDGET_TRACKER_MODULE,
|
|
KT_CAMPAIGN_QUEST_TRACKER_MODULE,
|
|
KT_QUEST_TRACKER_MODULE,
|
|
KT_BONUS_OBJECTIVE_TRACKER_MODULE,
|
|
KT_WORLD_QUEST_TRACKER_MODULE,
|
|
KT_ACHIEVEMENT_TRACKER_MODULE,
|
|
KT_PROFESSION_RECIPE_TRACKER_MODULE,
|
|
KT_MONTHLY_ACTIVITIES_TRACKER_MODULE,
|
|
};
|
|
|
|
self:RegisterEvent("QUEST_LOG_UPDATE");
|
|
self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED");
|
|
self:RegisterEvent("PERKS_ACTIVITIES_TRACKED_UPDATED");
|
|
self:RegisterEvent("PERKS_ACTIVITY_COMPLETED");
|
|
self:RegisterEvent("QUEST_WATCH_LIST_CHANGED");
|
|
self:RegisterEvent("QUEST_AUTOCOMPLETE");
|
|
self:RegisterEvent("QUEST_ACCEPTED");
|
|
self:RegisterEvent("SUPER_TRACKING_CHANGED");
|
|
self:RegisterEvent("SCENARIO_UPDATE");
|
|
self:RegisterEvent("SCENARIO_CRITERIA_UPDATE");
|
|
self:RegisterEvent("SCENARIO_SPELL_UPDATE");
|
|
self:RegisterEvent("SCENARIO_BONUS_VISIBILITY_UPDATE");
|
|
self:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE");
|
|
self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
|
|
self:RegisterEvent("ZONE_CHANGED");
|
|
self:RegisterEvent("QUEST_POI_UPDATE");
|
|
self:RegisterEvent("VARIABLES_LOADED");
|
|
self:RegisterEvent("QUEST_TURNED_IN");
|
|
self:RegisterEvent("PLAYER_MONEY");
|
|
self:RegisterEvent("CVAR_UPDATE");
|
|
self:RegisterEvent("WAYPOINT_UPDATE");
|
|
self.watchMoneyReasons = 0;
|
|
|
|
WorldMapFrame:RegisterCallback("SetFocusedQuestID", KT_ObjectiveTracker_OnFocusedQuestChanged, self);
|
|
WorldMapFrame:RegisterCallback("ClearFocusedQuestID", KT_ObjectiveTracker_OnFocusedQuestChanged, self);
|
|
|
|
KT_ProfessionsRecipeTracking_Initialize();
|
|
|
|
self.initialized = true;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnFocusedQuestChanged(self)
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnEvent(self, event, ...)
|
|
if ( event == "QUEST_LOG_UPDATE" ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_QUEST);
|
|
elseif ( event == "TRACKED_ACHIEVEMENT_UPDATE" ) then
|
|
KT_AchievementObjectiveTracker_OnAchievementUpdate(...);
|
|
elseif ( event == "PERKS_ACTIVITIES_TRACKED_UPDATED" ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_MODULE_MONTHLY_ACTIVITIES);
|
|
elseif ( event == "PERKS_ACTIVITY_COMPLETED" ) then
|
|
KT_MonthlyActivitiesObjectiveTracker_OnActivityCompleted(...);
|
|
elseif ( event == "QUEST_ACCEPTED" ) then
|
|
local questID = ...;
|
|
if ( not C_QuestLog.IsQuestBounty(questID) ) then
|
|
if ( C_QuestLog.IsQuestTask(questID) ) then
|
|
if ( QuestUtils_IsQuestWorldQuest(questID) ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_WORLD_QUEST_ADDED, questID);
|
|
else
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_TASK_ADDED, questID);
|
|
end
|
|
else
|
|
if ( GetCVarBool("autoQuestWatch") and C_QuestLog.GetNumQuestWatches() < Constants.QuestWatchConsts.MAX_QUEST_WATCHES ) then
|
|
C_QuestLog.AddQuestWatch(questID, Enum.QuestWatchType.Automatic);
|
|
KT_QuestSuperTracking_OnQuestTracked(questID);
|
|
end
|
|
end
|
|
end
|
|
elseif ( event == "TRACKED_ACHIEVEMENT_LIST_CHANGED" ) then
|
|
local achievementID, added = ...;
|
|
if ( added ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED, achievementID);
|
|
else
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT);
|
|
end
|
|
elseif ( event == "QUEST_WATCH_LIST_CHANGED" ) then
|
|
local questID, added = ...;
|
|
if ( added ) then
|
|
if ( not C_QuestLog.IsQuestBounty(questID) or C_QuestLog.IsComplete(questID) ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID);
|
|
end
|
|
else
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_QUEST);
|
|
end
|
|
elseif ( event == "QUEST_POI_UPDATE" ) then
|
|
QuestPOIUpdateIcons();
|
|
if ( GetCVar("trackQuestSorting") == "proximity" ) then
|
|
C_QuestLog.SortQuestWatches();
|
|
end
|
|
-- C_QuestLog.SortQuestWatches might not trigger a QUEST_WATCH_LIST_CHANGED due to unique signals, so force an update
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST);
|
|
KT_QuestSuperTracking_OnPOIUpdate();
|
|
elseif ( event == "SCENARIO_CRITERIA_UPDATE" ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO);
|
|
elseif ( event == "SCENARIO_SPELL_UPDATE" ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO_SPELLS);
|
|
elseif ( event == "SCENARIO_BONUS_VISIBILITY_UPDATE") then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE);
|
|
elseif ( event == "SUPER_TRACKING_CHANGED" ) then
|
|
KT_ObjectiveTracker_UpdateSuperTrackedQuest(self);
|
|
elseif ( event == "ZONE_CHANGED" ) then
|
|
local lastMapID = C_Map.GetBestMapForUnit("player");
|
|
if ( lastMapID ~= self.lastMapID ) then
|
|
C_QuestLog.SortQuestWatches();
|
|
self.lastMapID = lastMapID;
|
|
end
|
|
elseif ( event == "QUEST_AUTOCOMPLETE" ) then
|
|
local questId = ...;
|
|
KT_AutoQuestPopupTracker_AddPopUp(questId, "COMPLETE");
|
|
elseif ( event == "SCENARIO_UPDATE" ) then
|
|
local newStage = ...;
|
|
if ( newStage ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE);
|
|
else
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_SCENARIO);
|
|
end
|
|
elseif ( event == "ZONE_CHANGED_NEW_AREA" ) then
|
|
C_QuestLog.SortQuestWatches();
|
|
elseif ( event == "QUEST_TURNED_IN" ) then
|
|
local questID, xp, money = ...;
|
|
if ( C_QuestLog.IsQuestTask(questID) and not C_QuestLog.IsQuestBounty(questID) ) then
|
|
KT_BonusObjectiveTracker_OnTaskCompleted(...);
|
|
end
|
|
elseif ( event == "PLAYER_MONEY" and self.watchMoneyReasons > 0 ) then
|
|
KT_ObjectiveTracker_Update(self.watchMoneyReasons);
|
|
elseif ( event == "PLAYER_ENTERING_WORLD" ) then
|
|
if ( not self.initialized ) then
|
|
KT_ObjectiveTracker_Initialize(self);
|
|
end
|
|
KT_ObjectiveTracker_Update();
|
|
|
|
if not KT_QuestSuperTracking_IsSuperTrackedQuestValid() then
|
|
KT_QuestSuperTracking_ChooseClosestQuest();
|
|
end
|
|
|
|
self.lastMapID = C_Map.GetBestMapForUnit("player");
|
|
elseif ( event == "CVAR_UPDATE" ) then
|
|
local arg1 =...;
|
|
if ( arg1 == "questPOI" ) then
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST);
|
|
end
|
|
elseif ( event == "VARIABLES_LOADED" ) then
|
|
KT_ObjectiveTracker_Update();
|
|
elseif ( event == "WAYPOINT_UPDATE" ) then
|
|
KT_ObjectiveTracker_Update();
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnSizeChanged(self)
|
|
KT_ObjectiveTracker_Update();
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnUpdate(self)
|
|
if self.isUpdateDirty then
|
|
KT_ObjectiveTracker_Update();
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTrackerHeader_OnAnimFinished(self)
|
|
local header = self:GetParent();
|
|
header.animating = nil;
|
|
end
|
|
|
|
KT_ObjectiveTrackerHeaderMixin = {};
|
|
|
|
function KT_ObjectiveTrackerHeaderMixin:OnLoad()
|
|
self.height = KT_OBJECTIVE_TRACKER_HEADER_HEIGHT;
|
|
end
|
|
|
|
function KT_ObjectiveTrackerHeaderMixin:PlayAddAnimation()
|
|
self.animating = true;
|
|
self.HeaderOpenAnim:Restart();
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** BUTTONS
|
|
-- *****************************************************************************************************
|
|
|
|
KT_ObjectiveTrackerMinimizeButtonMixin = {};
|
|
|
|
function KT_ObjectiveTrackerMinimizeButtonMixin:OnLoad()
|
|
local collapsed = false;
|
|
self:SetAtlases(collapsed);
|
|
end
|
|
|
|
function KT_ObjectiveTrackerMinimizeButtonMixin:SetAtlases(collapsed)
|
|
local normalTexture = self:GetNormalTexture();
|
|
local pushedTexture = self:GetPushedTexture();
|
|
|
|
if self.buttonType == "module" then
|
|
if collapsed then
|
|
normalTexture:SetAtlas("UI-QuestTrackerButton-Expand-Section", true);
|
|
pushedTexture:SetAtlas("UI-QuestTrackerButton-Expand-Section-Pressed", true);
|
|
else
|
|
normalTexture:SetAtlas("UI-QuestTrackerButton-Collapse-Section", true);
|
|
pushedTexture:SetAtlas("UI-QuestTrackerButton-Collapse-Section-Pressed", true);
|
|
end
|
|
else
|
|
if collapsed then
|
|
normalTexture:SetAtlas("UI-QuestTrackerButton-Expand-All", true);
|
|
pushedTexture:SetAtlas("UI-QuestTrackerButton-Expand-All-Pressed", true);
|
|
else
|
|
normalTexture:SetAtlas("UI-QuestTrackerButton-Collapse-All", true);
|
|
pushedTexture:SetAtlas("UI-QuestTrackerButton-Collapse-All-Pressed", true);
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTrackerMinimizeButtonMixin:SetCollapsed(collapsed)
|
|
self:SetAtlases(collapsed);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_MinimizeButton_OnClick(self)
|
|
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
|
|
if ( KT_ObjectiveTrackerFrame.collapsed ) then
|
|
KT_ObjectiveTracker_Expand();
|
|
else
|
|
KT_ObjectiveTracker_Collapse();
|
|
end
|
|
KT_ObjectiveTracker_Update();
|
|
end
|
|
|
|
function KT_ObjectiveTracker_MinimizeModuleButton_OnClick(self)
|
|
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
|
|
local module = self:GetParent().module;
|
|
module:SetCollapsed(not module:IsCollapsed());
|
|
KT_ObjectiveTracker_Update(0, nil, module);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_Collapse()
|
|
KT_ObjectiveTrackerFrame.collapsed = true;
|
|
KT_ObjectiveTrackerFrame.BlocksFrame:Hide();
|
|
KT_ObjectiveTrackerFrame.HeaderMenu.MinimizeButton:SetCollapsed(true);
|
|
KT_ObjectiveTrackerFrame.HeaderMenu.Title:Show();
|
|
end
|
|
|
|
function KT_ObjectiveTracker_Expand()
|
|
KT_ObjectiveTrackerFrame.collapsed = nil;
|
|
KT_ObjectiveTrackerFrame.BlocksFrame:Show();
|
|
KT_ObjectiveTrackerFrame.HeaderMenu.MinimizeButton:SetCollapsed(false);
|
|
KT_ObjectiveTrackerFrame.HeaderMenu.Title:Hide();
|
|
end
|
|
|
|
function KT_ObjectiveTracker_ToggleDropDown(frame, handlerFunc)
|
|
--[[local dropDown = ObjectiveTrackerBlockDropDown;
|
|
if ( dropDown.activeFrame ~= frame ) then
|
|
CloseDropDownMenus();
|
|
end
|
|
dropDown.activeFrame = frame;
|
|
dropDown.initialize = handlerFunc;
|
|
ToggleDropDownMenu(1, nil, dropDown, "cursor", 3, -3);
|
|
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);]]
|
|
end
|
|
|
|
-- *****************************************************************************************************
|
|
-- ***** BLOCK CONTROL
|
|
-- *****************************************************************************************************
|
|
|
|
local function AnchorBlock(block, anchorBlock, checkFit)
|
|
local module = block.module;
|
|
local blocksFrame = module.BlocksFrame;
|
|
local offsetX, offsetY = KT_ObjectiveTracker_GetBlockOffset(block);
|
|
block:ClearAllPoints();
|
|
if ( anchorBlock ) then
|
|
if ( anchorBlock.isHeader ) then
|
|
offsetY = module.fromHeaderOffsetY;
|
|
end
|
|
-- check if the block can fit
|
|
if ( checkFit and (blocksFrame.contentsHeight + block.height - offsetY > blocksFrame.maxHeight) ) then
|
|
return;
|
|
end
|
|
if ( block.isHeader ) then
|
|
offsetY = offsetY + anchorBlock.module.fromModuleOffsetY;
|
|
block:SetPoint("LEFT", KT_OBJECTIVE_TRACKER_HEADER_OFFSET_X, 0);
|
|
else
|
|
block:SetPoint("LEFT", offsetX, 0);
|
|
end
|
|
block:SetPoint("TOP", anchorBlock, "BOTTOM", 0, offsetY);
|
|
else
|
|
offsetY = 0;
|
|
-- check if the block can fit
|
|
if ( checkFit and (blocksFrame.contentsHeight + block.height > blocksFrame.maxHeight) ) then
|
|
return;
|
|
end
|
|
-- if the blocks frame is a scrollframe, attach to its scrollchild
|
|
if ( block.isHeader ) then
|
|
block:SetPoint("TOPLEFT", blocksFrame.ScrollContents or blocksFrame, "TOPLEFT", KT_OBJECTIVE_TRACKER_HEADER_OFFSET_X, offsetY);
|
|
else
|
|
block:SetPoint("TOPLEFT", blocksFrame.ScrollContents or blocksFrame, "TOPLEFT", offsetX, offsetY);
|
|
end
|
|
end
|
|
return offsetY;
|
|
end
|
|
|
|
local function InternalAddBlock(block)
|
|
local module = block.module or KT_DEFAULT_OBJECTIVE_TRACKER_MODULE;
|
|
local blocksFrame = module.BlocksFrame;
|
|
block.nextBlock = nil;
|
|
|
|
-- This doesn't take fit into account, it just assumes that there's content to be added, so the potential count
|
|
-- should increase (this is related to showing the collapse buttons on the headers, see Reorder)
|
|
-- NOTE: Never count headers as added blocks
|
|
if not block.isHeader then
|
|
module.potentialBlocksAddedThisLayout = (module.potentialBlocksAddedThisLayout or 0) + 1;
|
|
end
|
|
|
|
-- Only allow headers to be added if the module is collapsed.
|
|
if not block.isHeader and module:IsCollapsed() then
|
|
return false;
|
|
end
|
|
|
|
local offsetY = AnchorBlock(block, blocksFrame.currentBlock, not module.ignoreFit);
|
|
if ( not offsetY ) then
|
|
return false;
|
|
end
|
|
|
|
if ( not module.topBlock ) then
|
|
module.topBlock = block;
|
|
end
|
|
if ( not module.firstBlock and not block.isHeader ) then
|
|
module.firstBlock = block;
|
|
end
|
|
if ( blocksFrame.currentBlock ) then
|
|
blocksFrame.currentBlock.nextBlock = block;
|
|
end
|
|
blocksFrame.currentBlock = block;
|
|
blocksFrame.contentsHeight = blocksFrame.contentsHeight + block.height - offsetY;
|
|
module.contentsAnimHeight = module.contentsAnimHeight + block.height;
|
|
module.contentsHeight = module.contentsHeight + block.height - offsetY;
|
|
return true;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_AddHeader(header, isStaticReanchor)
|
|
if InternalAddBlock(header) then
|
|
header.added = true;
|
|
header:Show();
|
|
return true;
|
|
end
|
|
|
|
return false;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_AddBlock(block)
|
|
local header = block.module.Header;
|
|
local blockAdded = false;
|
|
|
|
-- if there's no header or it's been added, just add the block...
|
|
if not header or header.added then
|
|
blockAdded = InternalAddBlock(block);
|
|
elseif KT_ObjectiveTracker_CanFitBlock(block, header) then
|
|
-- try to add header and maybe block
|
|
if KT_ObjectiveTracker_AddHeader(header) then
|
|
blockAdded = InternalAddBlock(block);
|
|
end
|
|
end
|
|
|
|
if not blockAdded then
|
|
block.module.hasSkippedBlocks = true;
|
|
end
|
|
|
|
return blockAdded;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_CanFitBlock(block, header)
|
|
local module = block.module;
|
|
local blocksFrame = module.BlocksFrame;
|
|
local offsetY;
|
|
if ( not blocksFrame.currentBlock ) then
|
|
offsetY = 0;
|
|
elseif ( blocksFrame.currentBlock.isHeader ) then
|
|
offsetY = module.fromHeaderOffsetY;
|
|
else
|
|
offsetY = select(2, KT_ObjectiveTracker_GetBlockOffset(block));
|
|
end
|
|
|
|
local totalHeight;
|
|
if header then
|
|
totalHeight = header.height - offsetY + block.height - module.fromHeaderOffsetY;
|
|
else
|
|
totalHeight = block.height - offsetY;
|
|
end
|
|
return (blocksFrame.contentsHeight + totalHeight) <= blocksFrame.maxHeight;
|
|
end
|
|
|
|
-- ***** SLIDING
|
|
|
|
function KT_ObjectiveTracker_SlideBlock(block, slideData)
|
|
block.slideData = slideData;
|
|
if ( slideData.startDelay ) then
|
|
block.slideTime = -slideData.startDelay;
|
|
else
|
|
block.slideTime = 0;
|
|
end
|
|
block.slideHeight = slideData.startHeight;
|
|
block:SetHeight(slideData.startHeight);
|
|
block:SetScript("OnUpdate", KT_ObjectiveTracker_OnSlideBlockUpdate);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_EndSlideBlock(block)
|
|
block:SetScript("OnUpdate", nil);
|
|
if ( block.slideData ) then
|
|
block:SetHeight(block.slideData.endHeight);
|
|
if ( block.slideData.scroll ) then
|
|
block:SetVerticalScroll(0);
|
|
end
|
|
end
|
|
block.slidingAction = nil;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_OnSlideBlockUpdate(block, elapsed)
|
|
local slideData = block.slideData;
|
|
|
|
block.slideTime = block.slideTime + elapsed;
|
|
if ( block.slideTime <= 0 ) then
|
|
return;
|
|
end
|
|
|
|
local height = floor(slideData.startHeight + (slideData.endHeight - slideData.startHeight) * (min(block.slideTime, slideData.duration) / slideData.duration));
|
|
if ( height ~= block.slideHeight ) then
|
|
block.slideHeight = height;
|
|
block:SetHeight(height);
|
|
if ( slideData.scroll ) then
|
|
block:UpdateScrollChildRect();
|
|
-- scrolling means the bottom of the content comes in first or leaves last
|
|
if (slideData.expanding) then
|
|
block:SetVerticalScroll(0);
|
|
else
|
|
block:SetVerticalScroll(max(slideData.endHeight, slideData.startHeight) - height);
|
|
end
|
|
end
|
|
end
|
|
|
|
if ( block.slideTime >= slideData.duration + (slideData.endDelay or 0) ) then
|
|
block:SetScript("OnUpdate", nil);
|
|
if ( slideData.onFinishFunc ) then
|
|
slideData.onFinishFunc(block);
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTracker_CancelSlideBlock(block)
|
|
block:SetScript("OnUpdate", nil);
|
|
local slideData = block.slideData;
|
|
if( slideData ) then
|
|
block:SetHeight(slideData.startHeight);
|
|
if ( slideData.scroll ) then
|
|
block:UpdateScrollChildRect();
|
|
-- scrolling means the bottom of the content comes in first or leaves last
|
|
block:SetVerticalScroll(0);
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ***** UPDATE
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:StaticReanchorCheckAddHeaderOnly()
|
|
if self:IsCollapsed() and not self.Header.added and self:GetBlockCount() > 0 then
|
|
KT_ObjectiveTracker_AddHeader(self.Header, true); -- the header was marked as not being added, make sure to add it again...
|
|
return true;
|
|
end
|
|
|
|
return false;
|
|
end
|
|
|
|
function KT_DEFAULT_OBJECTIVE_TRACKER_MODULE:StaticReanchor()
|
|
-- If this module is collapsed, don't process anything, it will result in the entire module being hidden, since just the header
|
|
-- is showing, there's nothing to update.
|
|
if self:StaticReanchorCheckAddHeaderOnly() then
|
|
return;
|
|
end
|
|
|
|
local block = self.firstBlock;
|
|
self:BeginLayout(true);
|
|
while ( block ) do
|
|
if ( block.module == self ) then
|
|
local nextBlock = block.nextBlock;
|
|
if ( KT_ObjectiveTracker_AddBlock(block) ) then
|
|
block.used = true;
|
|
block:Show();
|
|
block = nextBlock;
|
|
else
|
|
-- a prior module reduced the previously available space
|
|
block.used = false;
|
|
block:Hide();
|
|
break;
|
|
end
|
|
else
|
|
break;
|
|
end
|
|
end
|
|
self:EndLayout(true);
|
|
end
|
|
|
|
local function GetRelatedModulesForUpdate(module)
|
|
if module then
|
|
return tInvert(module:GetRelatedModules())
|
|
end
|
|
|
|
return nil;
|
|
end
|
|
|
|
local function IsRelatedModuleForUpdate(module, moduleLookup)
|
|
if moduleLookup then
|
|
return moduleLookup[module] ~= nil;
|
|
end
|
|
|
|
return false;
|
|
end
|
|
|
|
local function ObjectiveTracker_GetVisibleHeaders()
|
|
local headers = {};
|
|
for index, module in ipairs(KT_ObjectiveTrackerFrame.MODULES) do
|
|
local header = module.Header;
|
|
if header.added and header:IsVisible() then
|
|
headers[header] = true;
|
|
end
|
|
end
|
|
|
|
return headers;
|
|
end
|
|
|
|
local function ObjectiveTracker_AnimateHeaders(previouslyVisibleHeaders)
|
|
local currentHeaders = ObjectiveTracker_GetVisibleHeaders();
|
|
for header, isVisible in pairs(currentHeaders) do
|
|
if isVisible and not previouslyVisibleHeaders[header] then
|
|
header:PlayAddAnimation();
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTracker_UpdateSuperTrackedQuest(self)
|
|
local questID = C_SuperTrack.GetSuperTrackedQuestID();
|
|
KT_ObjectiveTracker_Update(KT_OBJECTIVE_TRACKER_UPDATE_SUPER_TRACK_CHANGED, questID);
|
|
QuestPOI_SelectButtonByQuestID(self.BlocksFrame, questID);
|
|
end
|
|
|
|
function KT_ObjectiveTracker_Update(reason, id, moduleWhoseCollapseChanged)
|
|
local tracker = KT_ObjectiveTrackerFrame;
|
|
|
|
if tracker.isUpdating then
|
|
-- Trying to update while we're already updating, try again next frame
|
|
tracker.isUpdateDirty = true;
|
|
return;
|
|
end
|
|
tracker.isUpdating = true;
|
|
|
|
if ( not tracker.initialized ) then
|
|
tracker.isUpdating = false;
|
|
return;
|
|
end
|
|
|
|
tracker.BlocksFrame.maxHeight = KT_ObjectiveTrackerFrame.BlocksFrame:GetHeight();
|
|
if ( tracker.BlocksFrame.maxHeight == 0 ) then
|
|
tracker.isUpdating = false;
|
|
return;
|
|
end
|
|
|
|
tracker.isUpdateDirty = false;
|
|
|
|
KT_OBJECTIVE_TRACKER_UPDATE_REASON = reason or KT_OBJECTIVE_TRACKER_UPDATE_ALL;
|
|
KT_OBJECTIVE_TRACKER_UPDATE_ID = id;
|
|
|
|
tracker.BlocksFrame.currentBlock = nil;
|
|
tracker.BlocksFrame.contentsHeight = 0;
|
|
|
|
-- Gather existing headers, only newly added ones will animate
|
|
local currentHeaders = ObjectiveTracker_GetVisibleHeaders();
|
|
|
|
-- mark headers unused
|
|
for index, module in ipairs(tracker.MODULES) do
|
|
if module.Header then
|
|
module.Header.added = nil;
|
|
end
|
|
end
|
|
|
|
-- These can be nil, it's fine, trust the API.
|
|
local relatedModules = GetRelatedModulesForUpdate(moduleWhoseCollapseChanged);
|
|
|
|
-- run module updates
|
|
local gotMoreRoomThisPass = false;
|
|
for i = 1, #tracker.MODULES do
|
|
local module = tracker.MODULES[i];
|
|
if IsRelatedModuleForUpdate(moduleWhoseCollapseChanged, relatedModules) or (band(KT_OBJECTIVE_TRACKER_UPDATE_REASON, module.updateReasonModule + module.updateReasonEvents) > 0) then
|
|
-- run a full update on this module
|
|
module:Update();
|
|
-- check if it's now taking up less space, using subtraction because of floats
|
|
if ( module.oldContentsHeight - module.contentsHeight >= 1 ) then
|
|
-- it is taking up less space, might have freed room for other modules
|
|
gotMoreRoomThisPass = true;
|
|
end
|
|
else
|
|
-- this module's contents have not have changed
|
|
-- but if we got more room and this module has unshown content, do a full update
|
|
-- also do a full update if the header is animating since the module does not technically have any blocks at that point
|
|
if ( (module.hasSkippedBlocks and gotMoreRoomThisPass) or (module.Header and module.Header.animating) ) then
|
|
module:Update();
|
|
else
|
|
module:StaticReanchor();
|
|
end
|
|
end
|
|
end
|
|
|
|
KT_ObjectiveTracker_ReorderModules();
|
|
KT_ObjectiveTracker_UpdatePOIs();
|
|
ObjectiveTracker_AnimateHeaders(currentHeaders);
|
|
|
|
-- hide unused headers
|
|
for i = 1, #tracker.MODULES do
|
|
KT_ObjectiveTracker_CheckAndHideHeader(tracker.MODULES[i].Header);
|
|
end
|
|
|
|
if ( tracker.BlocksFrame.currentBlock ) then
|
|
tracker.HeaderMenu:Show();
|
|
else
|
|
tracker.HeaderMenu:Hide();
|
|
end
|
|
|
|
tracker.BlocksFrame.currentBlock = nil;
|
|
tracker.isUpdating = false;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_CheckAndHideHeader(moduleHeader)
|
|
if ( moduleHeader and not moduleHeader.added and moduleHeader:IsShown() ) then
|
|
moduleHeader:Hide();
|
|
if ( moduleHeader.animating ) then
|
|
moduleHeader.animating = nil;
|
|
moduleHeader.HeaderOpenAnim:Stop();
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTracker_WatchMoney(watchMoney, reason)
|
|
if ( watchMoney ) then
|
|
if ( band(KT_ObjectiveTrackerFrame.watchMoneyReasons, reason) == 0 ) then
|
|
KT_ObjectiveTrackerFrame.watchMoneyReasons = KT_ObjectiveTrackerFrame.watchMoneyReasons + reason;
|
|
end
|
|
else
|
|
if ( band(KT_ObjectiveTrackerFrame.watchMoneyReasons, reason) > 0 ) then
|
|
KT_ObjectiveTrackerFrame.watchMoneyReasons = KT_ObjectiveTrackerFrame.watchMoneyReasons - reason;
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ObjectiveTracker_CountVisibleModules()
|
|
local count = 0;
|
|
local seen = {};
|
|
for index, module in ipairs(KT_ObjectiveTrackerFrame.MODULES) do
|
|
local header = module.Header;
|
|
if header and not seen[header] then
|
|
seen[header] = true;
|
|
|
|
if header:IsVisible() and module:GetBlockCount() > 0 then -- testing out the whole active block count concept....
|
|
count = count + 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
return count;
|
|
end
|
|
|
|
function KT_ObjectiveTracker_ReorderModules()
|
|
local visibleCount = ObjectiveTracker_CountVisibleModules();
|
|
local showAllModuleMinimizeButtons = visibleCount > 1;
|
|
local detachIndex = nil;
|
|
local anchorBlock = nil;
|
|
|
|
local header = KT_ObjectiveTrackerFrame.HeaderMenu;
|
|
header:ClearAllPoints();
|
|
|
|
for index, module in ipairs(KT_ObjectiveTrackerFrame.MODULES_UI_ORDER) do
|
|
local topBlock = module.topBlock;
|
|
if topBlock then
|
|
if module:UsesSharedHeader() then
|
|
AnchorBlock(topBlock, module.Header);
|
|
|
|
local containingModule = module.Header.module;
|
|
if containingModule and containingModule.firstBlock then
|
|
containingModule.firstBlock:ClearAllPoints();
|
|
AnchorBlock(containingModule.firstBlock, module.lastBlock);
|
|
end
|
|
else
|
|
AnchorBlock(topBlock, anchorBlock);
|
|
anchorBlock = module.lastBlock;
|
|
end
|
|
|
|
local headerPoint = KT_ObjectiveTrackerFrame.isOnLeftSideOfScreen and "LEFT" or "RIGHT";
|
|
if header then
|
|
header:ClearAllPoints();
|
|
header:SetPoint(headerPoint, module.Header, headerPoint, KT_ObjectiveTrackerFrame.isOnLeftSideOfScreen and -10 or 0, 0);
|
|
header = nil;
|
|
end
|
|
|
|
module.Header.Text:ClearAllPoints();
|
|
module.Header.Text:SetPoint("LEFT", module.Header, "LEFT", KT_ObjectiveTrackerFrame.isOnLeftSideOfScreen and 30 or 4, -1);
|
|
|
|
-- Side-step annoying "uncollapse" issue by allowing a collapsed module to continue showing its minimize button even if
|
|
-- it's the only remaining visible module
|
|
local shouldShowThisModuleMinimizeButton = showAllModuleMinimizeButtons or module:IsCollapsed();
|
|
|
|
module.Header.MinimizeButton:SetShown(shouldShowThisModuleMinimizeButton);
|
|
if shouldShowThisModuleMinimizeButton then
|
|
module.Header.MinimizeButton:ClearAllPoints();
|
|
module.Header.MinimizeButton:SetPoint(headerPoint, module.Header, headerPoint, KT_ObjectiveTrackerFrame.isOnLeftSideOfScreen and 9 or -20, 0);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function KT_ObjectiveTracker_UpdatePOIs()
|
|
if not KT_ObjectiveTrackerFrame.MODULES then
|
|
return;
|
|
end
|
|
|
|
local blocksFrame = KT_ObjectiveTrackerFrame.BlocksFrame;
|
|
QuestPOI_ResetUsage(blocksFrame);
|
|
|
|
local showPOIs = GetCVarBool("questPOI");
|
|
if ( not showPOIs ) then
|
|
QuestPOI_HideUnusedButtons(blocksFrame);
|
|
return;
|
|
end
|
|
|
|
local numPOINumeric = 0; -- This is tied to the QuestPOI system, it must be maintained across tracker instances.
|
|
for i, module in ipairs(KT_ObjectiveTrackerFrame.MODULES) do
|
|
if module.UpdatePOIs then
|
|
numPOINumeric = module:UpdatePOIs(numPOINumeric);
|
|
end
|
|
end
|
|
|
|
QuestPOI_SelectButtonByQuestID(blocksFrame, C_SuperTrack.GetSuperTrackedQuestID());
|
|
QuestPOI_HideUnusedButtons(blocksFrame);
|
|
end
|
|
|
|
KT_QuestHeaderMixin = {};
|
|
|
|
function KT_QuestHeaderMixin:OnShow()
|
|
self:RegisterEvent("QUEST_SESSION_JOINED");
|
|
self:RegisterEvent("QUEST_SESSION_LEFT");
|
|
self:UpdateHeader();
|
|
end
|
|
|
|
function KT_QuestHeaderMixin:OnHide()
|
|
self:UnregisterEvent("QUEST_SESSION_JOINED");
|
|
self:UnregisterEvent("QUEST_SESSION_LEFT");
|
|
end
|
|
|
|
function KT_QuestHeaderMixin:OnEvent()
|
|
self:UpdateHeader();
|
|
end
|
|
|
|
function KT_QuestHeaderMixin:UpdateHeader()
|
|
if C_QuestSession.HasJoined() then
|
|
self.Text:SetText(TRACKER_HEADER_PARTY_QUESTS);
|
|
else
|
|
self.Text:SetText(TRACKER_HEADER_QUESTS);
|
|
end
|
|
end
|
|
|
|
|