# HG changeset patch
# User Nenue
# Date 1472309468 14400
# Node ID 51f248dc02762adec13fa88d3f89db97334f6e9e
# Parent 83b3cdaae6a53730fe364641f2ed04dd5e6a55c0
setup working copy dingaling
diff -r 83b3cdaae6a5 -r 51f248dc0276 Veneer_Objectives/ObjectiveTracker.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Veneer_Objectives/ObjectiveTracker.lua Sat Aug 27 10:51:08 2016 -0400
@@ -0,0 +1,559 @@
+-- Veneer
+-- ObjectiveTracker.lua
+-- Created: 8/16/2016 8:19 AM
+-- %file-revision%
+-- This is more or less a copy of the blizzard code with some customization stuff added
+
+local plugin = VeneerObjectives
+local vn, print = LibStub("LibKraken").register(Veneer, VeneerObjectives)
+local ot
+local otvn
+
+local band, floor, min = bit.band, math.floor, math.min
+
+
+local X_QUEST = 0x00001;
+local X_QUEST_ADDED = 0x00002;
+local X_TASK_ADDED = 0x00004;
+local X_WORLD_QUEST_ADDED = 0x00008;
+local X_SCENARIO = 0x00010;
+local X_SCENARIO_NEW_STAGE = 0x00020;
+local X_ACHIEVEMENT = 0x00040;
+local X_ACHIEVEMENT_ADDED = 0x00080;
+local X_SCENARIO_BONUS_DELAYED = 0x00100;
+local X_SUPER_TRACK_CHANGED = 0x00200;
+-- these are for the specific module ONLY!
+local X_MODULE_QUEST = 0x00400;
+local X_MODULE_AUTO_QUEST_POPUP = 0x00800;
+local X_MODULE_BONUS_OBJECTIVE = 0x01000;
+local X_MODULE_WORLD_QUEST = 0x02000;
+local X_MODULE_SCENARIO = 0x04000;
+local X_MODULE_ACHIEVEMENT = 0x08000;
+local X_SCENARIO_SPELLS = 0x10000;
+-- special updates
+local X_STATIC = 0x0000;
+local X_ALL = 0xFFFF;
+
+-- state information
+local X_REASON = X_ALL; -- default
+local X_MONEY = 0
+local X_ANIMATION = 0
+local X_ID = 0;
+
+local INSET_V = -20
+
+
+
+local trackerWidth = 240
+local blockIndent = 12
+local blockSpacing = 3
+
+local tracker = {
+ freeBlocks = {},
+ usedBlocks = {},
+ freeProgressBars = {},
+ usedProgressBars = {},
+ freeTimers = {},
+ usedTimers = {},
+ freeLines = {},
+
+ headerText = 'Default Header',
+ contentHeight = 0,
+ animationHeight = 0,
+ updateReasonModule = 0,
+ updateReasonEvents = 0,
+}
+local GetTrackerHandler = function(handler)
+ handler = handler or {}
+ setmetatable(handler, {__index=tracker})
+ return handler
+end
+
+local Header_OnAnimationStart = function (self, forced)
+ local header = self:GetParent()
+ header.animating = true
+ plugin:UpdateAnimation(header)
+end
+
+local Header_OnAnimationFinished = function (self, forced)
+ local header = self:GetParent()
+ header.animating = nil
+ plugin:Update(X_ANIMATION)
+end
+
+-- reset generic flags for layout compilation
+function tracker:InitLayout (isStatic)
+ print('|cFF00FFFFlayout|r', self.headerText)
+ self.firstBlock = nil
+ self.lastBlock = nil
+ self.currentBlock = nil
+ self.oldContentHeight = self.contentHeight
+ self.oldAnimationHeight = self.animationHeight
+ self.numBlocks = 0
+ for id, block in pairs(self.usedBlocks) do
+ block.used = nil
+ end
+ if not isStatic then
+ self.hasSkippedBlocks = false
+ end
+
+ if not self.header then
+ self:SetHeader(self.headerText, X_REASON)
+ self.header:SetPoint('TOPLEFT', plugin, 'TOPLEFT', 0, -plugin.contentHeight)
+ plugin.contentHeight = plugin.contentHeight + self.header:GetHeight()
+ end
+
+
+ self.contentHeight = 0
+
+end
+
+-- clear out generic flags and set aside block frames for re-use
+tracker.EndLayout = function(self)
+ self.lastBlock = self.currentBlock
+ for id, block in pairs(self.usedBlocks) do
+ if not block.used then
+ self:FreeBlock(block)
+ end
+ end
+end
+
+function tracker:SetHeader (text, animateReason)
+ if self.header then
+ return self.header
+ end
+
+ local block = CreateFrame('Button', nil, plugin, 'VeneerObjectiveHeader')
+ block.handler = self
+ block.text:SetText(self.headerText)
+
+ self.currentBlock = block
+ self.header = block
+ return block
+end
+
+function tracker:FreeBlock(block)
+ self.usedBlocks[block.id] = nil
+ print('|cFF0088FFfree|r', block:GetName())
+ tinsert(self.freeBlocks, block)
+
+ block.numLines = 0
+ block:SetHeight(0)
+ block:Hide()
+end
+
+-- should only be used in an N-lastN loop
+function tracker:FreeLine(line)
+ if line.block then
+ line.block.lines[line.index] = nil
+ end
+ print('|cFF0088FFfree|r', line:GetName())
+ local freeLines = line.type or self.freeLines
+ tinsert(freeLines, line)
+end
+
+local blocksn = 0
+tracker.GetBlock = function(self, id)
+ local block = self.usedBlocks[id]
+ if not block then
+ local numFree = #self.freeBlocks
+ if numFree >= 1 then
+ block = tremove(self.freeBlocks, numFree)
+ else
+ blocksn = blocksn + 1
+ block = CreateFrame('Button', 'OTVNBlock'..blocksn, plugin, 'VeneerObjectiveBlock')
+ block.lines = {}
+ end
+ self.usedBlocks[id] = block
+ block.id = id
+ block.handler = self
+ end
+
+ block.used = true
+ block.currentLine = nil
+ block.numLines = 0
+
+ if block.lines then
+ for i, line in ipairs(block.lines) do
+ line.used = nil
+ end
+ end
+
+ block.contentHeight = blockSpacing
+ block:SetWidth(trackerWidth)
+ block:SetHeight(0)
+
+ return block
+end
+
+-- obtain line
+local linesn = 0
+function tracker:GetLine(block, index, lineType)
+ local line = block.lines[index]
+ if line and line.lineType ~= lineType then
+
+ tinsert(self.freeLines, line)
+ line = nil
+ end
+
+ if not line then
+ local freeLines = (lineType and lineType.freeLines) or self.freeLines
+ local numFreeLines = #freeLines
+ if numFreeLines >= 1 then
+ line = tremove(freeLines, numFreeLines)
+ else
+ linesn = linesn + 1
+ line = CreateFrame('Frame', 'OTVNLine'.. linesn, block, (lineType and lineType.template) or 'VeneerObjectiveLine')
+ end
+ line:SetParent(block)
+ end
+
+ line.type = lineType
+ line.index = index
+ line.used = true
+ line.block = block
+ line.text:SetPoint('TOPLEFT', line, 'TOPLEFT', blockIndent, 0)
+ line:SetHeight(0) -- in order for GetStringHeight to be useful
+
+ block.lines[index] = line
+
+ return line
+end
+
+function tracker:AddProgressBar(block, line, questID)
+end
+
+function tracker:FreeProgressBar(block, line)
+end
+
+function tracker:AddTimerBar(block, line, duration, startTime)
+end
+
+function tracker:FreeTimerBar(block, line)
+end
+
+-- Checks for space and anchors or frees the block accordingly
+function tracker:AddBlock (block, force)
+ local anchor = self.currentBlock or self.header
+ self.numBlocks = self.numBlocks + 1
+
+ if block.header then
+ print('header!', floor(block.contentHeight), '+', floor(block.header:GetStringHeight()))
+ block.contentHeight = block.contentHeight + block.header:GetStringHeight()
+ self.used = true
+ end
+
+
+ if self.currentBlock then
+ self.currentBlock.nextBlock = block
+ block.prevBlock = self.currentBlock
+ else
+ self.firstBlock = block
+ end
+
+ self.contentHeight = self.contentHeight + block.contentHeight
+ self.currentBlock = block
+
+ if not plugin.currentBlock then
+ plugin.firstBlock = block
+ end
+ plugin.currentBlock = block
+
+
+
+ block:SetHeight(block.contentHeight)
+ print('block|cFF88FF00', self.numBlocks, block, '|rto', anchor, 'size', block.contentHeight)
+ block:ClearAllPoints()
+ block:SetPoint('TOPLEFT', anchor, 'BOTTOMLEFT', 0, -blockSpacing)
+ block:Show()
+
+ -- free unused lines
+ local numLines = #block.lines
+ for i = 1, numLines do
+ local line = block.lines[i]
+ if not line.used or block.collapsed then
+ print('|cFFFF4400!|r')
+ self:FreeLine(line)
+ else
+ if not line:IsShown() then
+ line:Show()
+ end
+ end
+ end
+
+ return true
+end
+
+function tracker:SetLine(block, index, lineType, textOrFunc)
+ local anchor = block.currentLine or block.header
+ local line = self:GetLine(block, index, lineType)
+
+ if line.ticker then
+ line.ticker:Cancel()
+ line.ticker = nil
+ end
+
+ local text = textOrFunc
+ if type(textOrFunc) == 'function' then
+ text = textOrFunc()
+
+ line.ticker = C_Timer.NewTicker(10, function()
+ line.height = tracker:SetLineText(line.text, textOrTextFunc())
+ line:SetHeight(line.height)
+ end)
+ end
+ line.height = tracker:SetLineText(line.text, text)
+ line:SetHeight(line.height)
+
+ print('line|cFFFFFF00', line:GetName(), '|rto', anchor:GetName(), 'size', line.height)
+ line:SetPoint('TOPLEFT', anchor, 'BOTTOMLEFT', 0, 0)
+
+ block.contentHeight = block.contentHeight + line.height
+ block.numLines = block.numLines + 1
+
+ if block.currentLine then
+ line.prevLine = block.currentLine
+ block.currentLine.nextLine = line
+ else
+ block.firstLine = line
+ end
+
+ block.currentLine = line
+ plugin.currentLine = line
+
+end
+
+function tracker:SetLineText(fontString, text)
+ fontString:SetText(text)
+ return fontString:GetStringHeight()
+end
+
+-- Update lite
+function tracker:ResetAnchors ()
+ self:InitLayout()
+
+ self:EndLayout()
+end
+
+
+local UpdateQuestTracker = function(watchIndex, logIndex)
+ return true
+end
+
+-- top-down updaters
+
+local questTracker = GetTrackerHandler({
+ headerText = 'Quests',
+ updateReasonModule = X_MODULE_QUEST,
+ updateReasonEvents = (X_QUEST + X_QUEST_ADDED),
+})
+function questTracker:Update ()
+ self:InitLayout()
+ for watchIndex = 1, GetNumQuestWatches() do
+ local questID, title, questLogIndex, numObjectives, requiredMoney, isComplete, startEvent, isAutoComplete, failureTime, timeElapsed, questType, isTask, isBounty, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(watchIndex)
+ if not questID then
+ -- stop parsing; end of data or variables haven't completely loaded
+ break
+ end
+ local showQuest = true
+ if isTask or (isBounty and not IsQuestComplete(questID)) then
+ -- do nothing
+ else
+ -- obtain a block
+ local block = self:GetBlock(questID)
+
+ block.header:SetText(title)
+
+ for i = 1, numObjectives do
+ local text, objectiveType, finished = GetQuestLogLeaderBoard(i, questLogIndex)
+ if text then
+ self:SetLine(block, i, nil, text)
+ end
+ end
+
+ block:SetScript('OnClick', self.OnClick)
+ block:RegisterForClicks('AnyDown')
+
+ self:AddBlock(block)
+ end
+ end
+
+ self:EndLayout()
+end
+questTracker.OnClick = function(block, button)
+ if button == 'RightButton' then
+ ObjectiveTracker_ToggleDropDown(block, QuestObjectiveTracker_OnOpenDropDown)
+ else
+ CloseDropDownMenus()
+
+ local questLogIndex = GetQuestLogIndexByID(block.id)
+ if ( IsModifiedClick("QUESTWATCHTOGGLE") ) then
+ QuestObjectiveTracker_UntrackQuest(nil, block.id);
+ else
+ if ( IsQuestComplete(block.id) and GetQuestLogIsAutoComplete(questLogIndex) ) then
+ AutoQuestPopupTracker_RemovePopUp(block.id);
+ ShowQuestComplete(questLogIndex);
+ else
+ QuestLogPopupDetailFrame_Show(questLogIndex);
+ end
+ end
+ end
+end
+
+local UpdateAchievementTracker = function() end
+local UpdateTaskTracker = function() end
+local UpdateScenarioTracker = function() end
+
+function plugin:Update(reason, id)
+
+ print('update', reason, #plugin.trackers)
+
+ if plugin.minimized then
+ for i, tracker in ipairs(plugin.trackers) do
+ tracker:Hide()
+ end
+ return
+ end
+
+
+ local X_REASON = reason or X_ALL
+ local X_ID = id
+
+ plugin.maxHeight = plugin:GetHeight()
+ plugin.oldContentsHeight = plugin.contentHeight
+ plugin.contentHeight = 0
+ plugin.currentBlock = nil
+ plugin.firstBlock = nil
+ plugin:SetWidth(trackerWidth)
+
+ -- pad for header
+ plugin.contentHeight = plugin.header:GetHeight()
+
+ for i, header in ipairs(plugin.trackers) do
+ header.used = nil
+ end
+
+
+ local addedSpace = false
+ for i, tracker in ipairs(plugin.trackers) do
+ if ( band(X_REASON, tracker.updateReasonModule + tracker.updateReasonEvents ) > 0 ) then
+ print('->', tracker.headerText)
+ tracker:Update()
+ if tracker.oldContentHeight - tracker.contentHeight >= 1 then
+ addedSpace = true
+ end
+ else
+ -- if we can fit another header or an animation handler popped, contents need to be generated
+ if addedSpace or (tracker.header and tracker.header.animating) then
+ print('->', tracker.headerText, 'added space')
+ tracker:Update()
+ else
+ print('->', tracker.headerText, 'lite update')
+ -- otherwise, measure contents and hide anything that won't fit
+ tracker:ResetAnchors()
+ end
+ end
+ end
+
+ for i, tracker in ipairs(plugin.trackers) do
+ if tracker.currentBlock then
+ if not tracker.header:IsShown() then
+ tracker.header:Show()
+ end
+ else
+ if tracker.header:IsShown() then
+ tracker.header:Hide()
+ end
+ end
+ end
+
+ if VeneerBuffFrame and VeneerBuffFrame.lastBuff then
+ plugin:ClearAllPoints()
+ plugin:SetPoint('TOP', VeneerBuffFrame.lastBuff, 'BOTTOM', 0, -4)
+ plugin:SetPoint('RIGHT', UIParent, 'RIGHT', -6, 0)
+ else
+ plugin:ClearAllPoints()
+ plugin:SetPoint('TOPRIGHT', UIParent, 'TOPRIGHT', -6, -120)
+ end
+
+ plugin:Show()
+end
+
+plugin.init = function()
+
+ plugin:RegisterEvent("QUEST_LOG_UPDATE")
+ plugin:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED")
+ plugin:RegisterEvent("QUEST_WATCH_LIST_CHANGED")
+ plugin:RegisterEvent("QUEST_AUTOCOMPLETE")
+ plugin:RegisterEvent("QUEST_ACCEPTED")
+ plugin:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED")
+ plugin:RegisterEvent("SCENARIO_UPDATE")
+ plugin:RegisterEvent("SCENARIO_CRITERIA_UPDATE")
+ plugin:RegisterEvent("SCENARIO_SPELL_UPDATE")
+ plugin:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE")
+ plugin:RegisterEvent("ZONE_CHANGED_NEW_AREA");
+ plugin:RegisterEvent("ZONE_CHANGED");
+ plugin:RegisterEvent("QUEST_POI_UPDATE");
+ plugin:RegisterEvent("VARIABLES_LOADED");
+ plugin:RegisterEvent("QUEST_TURNED_IN");
+ plugin:RegisterEvent("PLAYER_MONEY");
+
+ plugin.trackers = {
+ questTracker,
+ }
+ print('bub')
+end
+function plugin:event(event, ...)
+ print('|cFFFF0088' .. event, ...)
+ if event == 'QUEST_WATCH_LIST_CHANGED' then
+ local questID, added = ...
+ if added then
+ if not IsQuestBounty(questID) or IsQuestComplete(questId) then
+ print(questID, added)
+ plugin:Update(X_QUEST_ADDED, questID)
+ end
+ else
+ print()
+ plugin:Update(X_QUEST)
+ end
+ elseif event == 'QUEST_LOG_UPDATE' then
+ plugin:Update(X_MODULE_QUEST)
+ elseif event == 'QUEST_POI_UPDATE' then
+
+ if GetCVar("trackQuestSorting") == "proximity" then
+ -- todo: sort blocks
+ end
+ plugin:Update(X_MODULE_QUEST)
+ elseif event == 'PLAYER_MONEY' then
+ plugin:Update(X_MONEY)
+ end
+
+end
+
+-- adjusts money events bitcode when a tracker is displaying money data
+function plugin:UpdateMoneyFlag(watchMoney, reason)
+ if watchMoney then
+ if (band(X_MONEY, reason) == 0) then
+ X_MONEY = X_MONEY - reason
+ end
+ else
+ if (band(X_MONEY, reason) > 0) then
+ X_MONEY = X_MONEY + reason
+ end
+ end
+end
+
+-- used by framescripts to poke the updater when an animation has ended
+function plugin:UpdateAnimation(block)
+
+ local reason = block.handler.updateReasonEvents
+ if block.animating then
+ if (band(X_ANIMATION, reason) == 0) then
+ X_ANIMATION = X_ANIMATION - reason
+ end
+ else
+ if (band(X_ANIMATION, reason) > 0) then
+ X_ANIMATION = X_ANIMATION + reason
+ end
+ end
+end
\ No newline at end of file
diff -r 83b3cdaae6a5 -r 51f248dc0276 Veneer_Objectives/Veneer_Objectives.iml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Veneer_Objectives/Veneer_Objectives.iml Sat Aug 27 10:51:08 2016 -0400
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 83b3cdaae6a5 -r 51f248dc0276 Veneer_Objectives/Veneer_Objectives.toc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Veneer_Objectives/Veneer_Objectives.toc Sat Aug 27 10:51:08 2016 -0400
@@ -0,0 +1,13 @@
+## Interface: 70000
+## Title: Veneer |cFF00FF00Objective Tracker|r
+## Notes: Objectives frame hooker-upper
+## Author: Krakyn
+## Version: 1.0-@project-revision@
+## SavedVariables: VeneerData
+## X-Category: Interface Enhancements
+## DefaultState: Enabled
+## LoadOnDemand: 0
+## Dependencies: Veneer
+
+Veneer_Objectives.xml
+ObjectiveTracker.lua
\ No newline at end of file
diff -r 83b3cdaae6a5 -r 51f248dc0276 Veneer_Objectives/Veneer_Objectives.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Veneer_Objectives/Veneer_Objectives.xml Sat Aug 27 10:51:08 2016 -0400
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file