Nenue@1: --- ${PACKAGE_NAME} Nenue@1: -- @file-author@ Nenue@1: -- @project-revision@ @project-hash@ Nenue@1: -- @file-revision@ @file-hash@ Nenue@1: -- Created: 3/30/2016 12:49 AM Nenue@1: local B = select(2,...).frame Nenue@2: local ipairs, max, min, unpack, floor, pairs, tostring, type = ipairs, max, min, unpack, floor, pairs, tostring, type Nenue@2: local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion Nenue@2: local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent Nenue@1: local CreateFrame = CreateFrame Nenue@1: local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') Nenue@1: local print = B.print('Objectives') Nenue@1: -------------------------------------------------------------------- Nenue@1: --- Global frame layout Nenue@1: -------------------------------------------------------------------- Nenue@1: Nenue@1: --- Upvalues Nenue@2: local Wrapper = VeneerObjectiveWrapper Nenue@1: local Scroller = Wrapper.scrollArea Nenue@2: local Scroll = VeneerObjectiveScroll Nenue@1: local orderedHandlers = mod.orderedHandlers Nenue@1: local orderedNames = mod.orderedNames Nenue@1: Nenue@1: --- Temp values set during updates Nenue@1: local wrapperWidth, wrapperHeight Nenue@1: local scrollWidth, scrollHeight Nenue@1: local previousBlock Nenue@1: local currentBlock Nenue@1: --- todo: map these into config table when its sorted out Nenue@1: local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]] Nenue@1: local titleSize, textSize = 15, 15 Nenue@1: local titleOutline, textOutline = "OUTLINE", "OUTLINE" Nenue@1: local titleSpacing, textSpacing = 4, 3 Nenue@1: local textIndent = 5 Nenue@1: local wrapperMaxWidth, wrapperMaxHeight = 280, 490 -- these are the hard bounds, actual *Height variables are changed Nenue@2: local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE' Nenue@1: local headerFont, headerSize, headerHeight = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 18, 24 Nenue@2: local headerOutline, headerColor, headerSpacing = 'OUTLINE', {1,1,1,1}, 2 Nenue@1: local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0} Nenue@1: Nenue@2: --- These are mostly aesthetic choices so it lives here Nenue@1: mod.defaults = { Nenue@1: ObjectiveTrackerAnchor = {'BOTTOM', 'RIGHT'}, Nenue@1: ObjectiveTrackerParent = 'DebuffButton', Nenue@1: ObjectiveTrackerSize = {250, 600}, Nenue@1: ObjectiveWrapperParent = '', Nenue@2: WrapperStyle = { Nenue@2: Header = { Nenue@2: Background = {Left = [[Objective-Header]], Right = [[Objective-Header]], Tile = [[Objective-Header]]}, Nenue@2: BackgroundCrop = {Left = {0, 0.4, 0,1}, Right={0.6,1,0,1}, Tile = {0.4,.6,0,1,}}, Nenue@2: BackgroundScale = {Left = 100, Right = 100}, Nenue@2: Font = {wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline} Nenue@2: } Nenue@2: }, Nenue@2: ObjectiveHeaderStyle = { Nenue@2: Normal = { Nenue@3: Gradient = {MinColor = {0,0,0,0.5}, MaxColor = {0,0,0,.25}}, Nenue@2: Font = {headerFont, headerSize, headerOutline}, Spacing = headerSpacing, Nenue@2: } Nenue@2: }, Nenue@1: ObjectiveTrackerStyle = { Nenue@1: Normal = { Nenue@1: Title = { Nenue@1: Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, 0}}, Nenue@1: Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, Nenue@1: }, Nenue@1: Text = { Nenue@1: Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, 0}}, Nenue@1: Font = {textFont, textSize, textOutline}, Spacing = textSpacing, Nenue@1: }, Nenue@1: }, Nenue@1: Super = { Nenue@1: Title = { Nenue@1: Gradient = { MinColor = {0, .7, .6, .8}, MaxColor = {0, .7, .6, 0.2}}, Nenue@1: Font = {titleFont, titleSize, titleOutline}, Nenue@1: Spacing = titleSpacing, BackgroundFullWidth = true Nenue@1: }, Nenue@1: Text = { Nenue@1: Gradient = { MinColor = {0, .7, .6, 0.5}, MaxColor = {0, .7, .6, 0.1} }, Nenue@1: Font = {textFont, textSize, textOutline}, Spacing = textSpacing, Nenue@1: }, Nenue@1: }, Nenue@1: Active = { Nenue@1: Title = { Nenue@1: Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, Nenue@1: Font = {titleFont, titleSize, titleOutline}, Nenue@1: Spacing = titleSpacing, Nenue@1: BackgroundFullWidth = true Nenue@1: }, Nenue@1: Text = { Nenue@1: Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, Nenue@1: Font = {textFont, textSize, textOutline}, Nenue@1: Spacing = textSpacing, Nenue@1: BackgroundFullWidth = true Nenue@1: } Nenue@1: }, Nenue@1: Complete = { Nenue@1: Title = { Nenue@1: Gradient = { MinColor = {0, 1, 0, 0.34}, MaxColor = {0, 1, 0, .17}, }, Nenue@1: Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, Nenue@1: BackgroundFullWidth = true Nenue@1: }, Nenue@1: Text = { Nenue@1: Gradient = { MinColor = {0, 1, 0, .25}, MaxColor = {0, 1, 0, 0.12}, }, Nenue@1: Font = {textFont, textSize, textOutline}, Spacing = textSpacing, Nenue@1: BackgroundFullWidth = true Nenue@1: } Nenue@1: }, Nenue@1: } Nenue@1: } Nenue@1: Nenue@3: local FontBank = { Nenue@3: ['Normal'] = VeneerCriteriaFontNormal, Nenue@3: ['Progress'] = VeneerCriteriaFontProgress, Nenue@3: ['Complete'] = VeneerCriteriaFontComplete, Nenue@3: ['Failed'] = VeneerCriteriaFontFailed, Nenue@3: } Nenue@3: Nenue@2: local Scroller_OnShow = function() Nenue@2: Wrapper.watchMoneyReasons = 0; Nenue@2: mod.UpdateWrapper() Nenue@2: mod.SetEvents() Nenue@2: for i, region in ipairs(Wrapper.header) do Nenue@2: region:Show() Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: local Scroller_OnHide = function() Nenue@2: local self = Wrapper Nenue@2: Wrapper:UnregisterAllEvents() Nenue@2: Wrapper:SetScript('OnEvent', nil) Nenue@2: for i, region in ipairs(Wrapper.header) do Nenue@2: region:Hide() Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: local Scroller_OnMouseWheel = function(self, delta) Nenue@2: local r = Scroll:GetHeight() - Scroller:GetHeight() Nenue@2: local s = self:GetVerticalScroll() - delta * floor(r/5+.5) Nenue@2: if r == 0 then return end Nenue@2: if s >= r then Nenue@2: s = r Nenue@2: elseif s < 1 then Nenue@2: s = 0 Nenue@2: end Nenue@2: self:SetVerticalScroll(s) Nenue@2: print(s, r, self:GetVerticalScroll()) Nenue@2: Nenue@2: mod.UpdateActionButtons() Nenue@2: end Nenue@2: Nenue@2: local WrapperCloseButton_OnClick = function(self) Nenue@2: if Scroller:IsVisible() then Nenue@2: Scroller:Hide() Nenue@2: else Nenue@2: Scroller:Show() Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: mod.InitializeTrackers = function() Nenue@2: Nenue@2: local c = mod.defaults.ObjectiveHeaderStyle.Normal Nenue@2: local g1, g2, g3, g4 = unpack(c.Gradient.MinColor) Nenue@2: local h1, h2, h3, h4 = unpack(c.Gradient.MaxColor) Nenue@2: Nenue@2: for i, name in ipairs(orderedNames) do Nenue@2: if not mod.orderedHandlers[i] then Nenue@2: if mod.Tracker(name, i) then Nenue@2: local handler = mod[name] Nenue@2: Nenue@2: local tracker = CreateFrame('Frame', 'Veneer'..name..'Tracker', Scroll, 'VeneerTrackerTemplate') Nenue@2: tracker.header:SetText(handler.name) Nenue@2: tracker.header:SetHeight(headerHeight) Nenue@2: tracker.header:SetFont(unpack(c.Font)) Nenue@2: tracker.header:SetTextColor(unpack(headerColor)) Nenue@2: Nenue@2: tracker.headerbg:SetGradientAlpha('HORIZONTAL', g1, g2 ,g3, g4, h1, h2, h3, h4) Nenue@2: tracker.headerbg:SetHeight(headerHeight) Nenue@2: Nenue@2: handler.Tracker = tracker Nenue@2: mod.orderedTrackers[i] = tracker Nenue@2: mod.namedTrackers[name] = tracker Nenue@2: mod.indexedTrackers[handler] = tracker Nenue@2: print('created new tracker frames for new handler') Nenue@2: end Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: Scroller:SetScrollChild(Scroll) Nenue@2: Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel) Nenue@2: Scroller:SetScript('OnShow', Scroller_OnShow) Nenue@2: Scroller:SetScript('OnHide', Scroller_OnHide) Nenue@2: Wrapper.close:SetScript('OnClick', WrapperCloseButton_OnClick) Nenue@2: Wrapper:SetPoint(unpack(wrapperPosition)) Nenue@2: Scroller_OnShow(Scroller) Nenue@2: Nenue@2: mod.UpdateWrapperStyle() Nenue@2: end Nenue@2: Nenue@2: mod.InitializeXPTracker = function() Nenue@2: local XPBar = Wrapper.XPBar Nenue@2: if UnitLevel('player') == 100 then Nenue@2: XPBar:Hide() Nenue@2: return Nenue@2: end Nenue@2: Nenue@2: --- xp bar Nenue@2: XPBar:Show() Nenue@2: XPBar.rested:SetTexture(2,.6,1,1) Nenue@2: XPBar.fg:SetTexture(.3,.1,.95,1) Nenue@2: XPBar.bg:SetTexture(0,0,0,.25) Nenue@2: XPBar:RegisterEvent('PLAYER_XP_UPDATE') Nenue@2: XPBar:RegisterEvent('PLAYER_LEVEL_UP') Nenue@2: XPBar:RegisterEvent('PLAYER_UPDATE_RESTING') Nenue@2: XPBar:SetScript('OnEvent', mod.UpdateXP) Nenue@2: mod.UpdateXP(Wrapper.xpBar) Nenue@2: end Nenue@2: Nenue@2: mod.UpdateXP = function() Nenue@2: local XPBar = Wrapper.XPBar Nenue@2: local xp = UnitXP('player') Nenue@2: local xpmax = UnitXPMax('player') Nenue@2: local rest = GetXPExhaustion() Nenue@2: Nenue@2: XPBar.bg:SetAllPoints(XPBar) Nenue@2: XPBar.fg:SetWidth((xp/xpmax) * XPBar:GetWidth()) Nenue@2: Nenue@2: if IsResting() then Nenue@2: XPBar.bg:SetTexture(.2,.8,.2,.5) Nenue@2: else Nenue@2: XPBar.bg:SetTexture(0,0,0,.25) Nenue@2: end Nenue@2: Nenue@2: if rest then Nenue@2: XPBar.rested:ClearAllPoints() Nenue@2: if xp == 0 then Nenue@3: XPBar.rested:SetPoint('TOPLEFT', XPBar, 'TOPLEFT', 0, 0) Nenue@2: else Nenue@3: XPBar.rested:SetPoint('TOPLEFT', XPBar.fg, 'TOPRIGHT', 0, 0) Nenue@2: end Nenue@2: Nenue@2: if (xp + rest) > xpmax then Nenue@3: XPBar.rested:SetPoint('BOTTOMRIGHT', XPBar, 'BOTTOMRIGHT', 0, 0) Nenue@2: else Nenue@3: XPBar.rested:SetWidth((rest/xpmax) * XPBar:GetWidth()) Nenue@2: end Nenue@3: XPBar.rested:SetPoint('BOTTOM', XPBar, 'BOTTOM') Nenue@2: XPBar.rested:Show() Nenue@2: else Nenue@2: XPBar.rested:Hide() Nenue@2: end Nenue@2: Nenue@2: XPBar.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or '')) Nenue@2: end Nenue@2: Nenue@2: mod.UpdateReputation = function(self) Nenue@2: end Nenue@1: Nenue@1: --- Argument containers Nenue@1: local a1, a2, a3, a4, b1, b2, b3, b4, f1, f2, f3, w1, w2 Nenue@1: mod.SetBlockStyle = function(block, name) Nenue@1: -- var names intended to reflect argument order Nenue@2: --@debug@ Nenue@1: local c = mod.defaults.ObjectiveTrackerStyle[name] Nenue@2: --@end-debug@ Nenue@2: --[===[@non-debug Nenue@2: local c = mod.Conf Nenue@2: --@end-non-debug]===] Nenue@1: a1, a2, a3, a4 = unpack(c.Title.Gradient.MinColor) Nenue@1: b1, b2, b3, b4 = unpack(c.Title.Gradient.MaxColor) Nenue@1: block.titlebg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4) Nenue@1: Nenue@1: a1, a2, a3, a4 = unpack(c.Text.Gradient.MinColor) Nenue@1: b1, b2, b3, b4 = unpack(c.Text.Gradient.MaxColor) Nenue@1: block.bg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4) Nenue@1: Nenue@1: f1, f2, f3 = unpack(c.Title.Font) Nenue@1: block.title:SetFont(f1, f2, f3) Nenue@1: Nenue@1: f1, f2 ,f3 = unpack(c.Text.Font) Nenue@1: block.objectives:SetFont(f1,f2,f3) Nenue@1: Nenue@1: w1 = Wrapper:GetWidth() Nenue@1: w2 = (c.Title.BackgroundFullWidth and w1 or block.title:GetStringWidth()) Nenue@1: Nenue@1: local titleSpacing, titleSpacing2 = c.Title.Spacing, (c.Title.Spacing * 2) Nenue@1: local textSpacing, textSpacing2 = c.Text.Spacing, (c.Text.Spacing * 2) Nenue@1: Nenue@1: if block.info.isTrivial then Nenue@1: block.title:SetTextColor(0.7, 0.7, 0.7, 1) Nenue@1: elseif block.info.isComplete then Nenue@1: block.title:SetTextColor(1,1,1,1) Nenue@1: else Nenue@1: block.title:SetTextColor(0,.7,1,1) Nenue@1: end Nenue@1: block.title:SetSpacing(titleSpacing) Nenue@1: block.objectives:SetSpacing(textSpacing) Nenue@1: block.objectives:SetWordWrap(true) Nenue@1: Nenue@1: local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight() Nenue@1: local blockHeight = titleHeight + titleSpacing2 + textHeight + textSpacing2 Nenue@1: local blockWidth = wrapperMaxWidth Nenue@1: Nenue@1: block.titlebg:SetSize(min(w1, w2), titleHeight + titleSpacing2) Nenue@1: block.bg:SetSize(w1, textHeight + textSpacing2) Nenue@1: block:SetSize(blockWidth, blockHeight) Nenue@1: Nenue@1: block.title:SetPoint('TOPLEFT', block.titlebg, 'TOPLEFT', 0, -titleSpacing) Nenue@1: block.objectives:SetPoint('TOPLEFT', block.titlebg, 'BOTTOMLEFT', textIndent, -textSpacing) Nenue@1: Nenue@1: -- store Nenue@1: block.titleHeight = titleHeight Nenue@1: block.textHeight = textHeight Nenue@1: block.width = blockWidth Nenue@1: block.height = blockHeight Nenue@1: Nenue@2: print(' |cFF00FFFF'..block:GetName()..'|r:|cFF0088FFSetStyle|r(', blockWidth, 'x', blockHeight, '(textH', textHeight,', titleH', titleHeight, ')') Nenue@2: end Nenue@2: Nenue@2: local segments = {'Left', 'Right', 'Tile'} Nenue@2: mod.UpdateWrapperStyle = function() Nenue@2: local c = mod.defaults.WrapperStyle Nenue@2: for _, segment in ipairs(segments) do Nenue@2: Wrapper['Background'..segment]:SetAtlas(c.Header.Background[segment]) Nenue@2: Wrapper['Background'..segment]:SetTexCoord(unpack(c.Header.BackgroundCrop[segment])) Nenue@2: if c.Header.BackgroundScale[segment] then Nenue@2: Wrapper['Background'..segment]:SetWidth(c.Header.BackgroundScale[segment]) Nenue@2: end Nenue@2: end Nenue@1: end Nenue@1: Nenue@1: --- Updates the selected block frame to display the given info batch Nenue@1: -- If `previousBlock` is set, it will attempt to anchor to that Nenue@1: -- @param blockNum the ordered block to be updated, not a watchIndex value Nenue@1: -- @param info the reference returned by the GetXInfo functions Nenue@1: -- REMEMBER: t.info and questData[questID] are the same table Nenue@1: mod.UpdateTrackerBlock = function (handler, blockIndex, info) Nenue@2: print(' |cFF00FFFFUpdateTrackerBlock('..blockIndex..'|r') Nenue@1: if not blockIndex or not info then Nenue@1: return Nenue@1: end Nenue@1: Nenue@1: local tracker = handler.Tracker Nenue@1: Nenue@1: local t = handler:GetBlock(blockIndex) Nenue@1: if previousBlock then Nenue@1: if blockIndex == 1 then Nenue@1: t:SetPoint('TOPLEFT', previousBlock, 'TOPLEFT', 0, -headerHeight) Nenue@1: else Nenue@1: t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0) Nenue@1: end Nenue@1: t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) Nenue@1: end Nenue@2: --print(t:GetName(), t:GetSize()) Nenue@2: --print(t:GetPoint(1)) Nenue@1: Nenue@1: t.info = info Nenue@1: Nenue@1: if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end Nenue@1: if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end Nenue@1: Nenue@1: info.blockIndex = blockIndex Nenue@1: handler.BlockInfo[blockIndex] = info Nenue@1: t.Select = handler.Select Nenue@1: t.Open = handler.Open Nenue@1: t.Remove = handler.Remove Nenue@1: t.Link = handler.Link Nenue@1: t:SetScript('OnMouseUp', handler.OnMouseUp) Nenue@1: t:SetScript('OnMouseDown', handler.OnMouseDown) Nenue@1: t.title:SetText(info.title) Nenue@1: Nenue@1: if info.isComplete then Nenue@1: t.objectives:Show() Nenue@1: t.objectives:SetText(info.completionText) Nenue@1: elseif info.numObjectives >= 1 then Nenue@1: t.objectives:Show() Nenue@2: print(' - objective lines:', info.numObjectives, 'can wrap:', t.objectives:CanWordWrap()) Nenue@3: Nenue@1: local text = '' Nenue@3: if info.description then Nenue@3: print(' -- has description text:', select('#', info.description), info.description) Nenue@3: text = info.description Nenue@3: end Nenue@3: Nenue@3: --- todo: implement objective displays Nenue@3: -- in an accumulator loop, call upon handler for the appropriate display frame, each defining: Nenue@3: -- * height of whatever display widget is involved in conveying the task Nenue@3: -- * number of non-wrapped text lines to account for line space; may be discarded depending on things Nenue@3: -- * boolean that determines listening for money events or not Nenue@3: t.attachmentHeight = 0 Nenue@1: for o, obj in ipairs(t.info.objectives) do Nenue@3: --- achievement criteria Nenue@3: if obj.flags then Nenue@3: Nenue@3: if bit.band(obj.flags, 0x00000001) > 0 then Nenue@3: obj.type = 'ProgressBar' Nenue@3: obj.widget = mod.SetWidget(obj, info) Nenue@3: elseif bit.band(obj.flags, 0x00000002) then Nenue@3: obj.type = 'Hidden' Nenue@3: obj.widget = nil Nenue@3: else Nenue@3: obj.type = 'Text' Nenue@3: obj.widget = nil Nenue@3: text = text .. ((text == '') and "" or "\n") .. obj.text Nenue@3: end Nenue@3: Nenue@3: print(obj.type, obj.text, obj.quantityString) Nenue@3: --- none of the above (most quests) Nenue@3: else Nenue@3: local line = obj.text Nenue@3: if obj.type == 'monster' then Nenue@3: line = '|cFFFFFF00' .. line .. '|r' Nenue@3: elseif obj.type == 'item' then Nenue@3: line = '|cFF44BBFF' .. line .. '|r' Nenue@3: elseif obj.type == 'object' then Nenue@3: line = '|cFFFFFFFF' .. line .. '|r' Nenue@3: end Nenue@3: text = text .. ((text == '') and "" or "\n") .. line Nenue@1: end Nenue@3: Nenue@3: if obj.widget then Nenue@3: t.attachmentHeight = t.attachmentHeight + obj.widget.height Nenue@3: end Nenue@3: Nenue@1: end Nenue@1: t.objectives:SetText(text) Nenue@3: t.objectives:SetWordWrap(true) Nenue@1: Nenue@1: Nenue@1: -- todo: set up a SecureActionButton template Nenue@2: if info.specialItem and not info.itemButton then Nenue@2: print(' - |cFF00FFFFupdate item button') Nenue@1: mod.SetItemButton(t, info) Nenue@1: end Nenue@1: Nenue@1: Nenue@1: elseif info.description then Nenue@1: t.objectives:SetText(info.description) Nenue@1: t.objectives:SetWordWrap(true) Nenue@1: else Nenue@1: t.objectives:SetText(nil) Nenue@1: end Nenue@1: local style = 'Normal' Nenue@1: if info.isComplete then Nenue@1: style = 'Complete' Nenue@1: elseif info.superTracked then Nenue@1: style = 'Super' Nenue@1: end Nenue@1: Nenue@3: --- metrics are calculated in SetStyle Nenue@1: t:SetStyle(style) Nenue@3: t:Show() Nenue@1: Nenue@3: print(' |cFF00FFFF)|r -> ', t, t:GetHeight()) Nenue@1: return t Nenue@1: end Nenue@1: Nenue@1: mod.UpdateTracker = function(handler) Nenue@1: print('|cFF00FF88UpdateTracker(|r|cFFFF4400' .. type(handler) .. '|r :: |cFF88FFFF' .. tostring(handler) .. '|r') Nenue@1: local tracker = handler.Tracker Nenue@1: local blockIndex = 0 Nenue@1: local trackerHeight = headerHeight Nenue@1: local w = 300 Nenue@1: Nenue@1: previousBlock = handler.Tracker Nenue@1: local numWatched = handler.GetNumWatched() Nenue@1: local numBlocks = handler.numBlocks Nenue@1: local actualBlocks = handler.actualBlocks Nenue@1: for watchIndex = 1, 25 do Nenue@1: blockIndex = blockIndex + 1 Nenue@1: if watchIndex <= numWatched then Nenue@1: local info = handler:GetInfo(watchIndex) Nenue@1: if info then Nenue@1: local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info) Nenue@1: previousBlock = currentBlock Nenue@1: trackerHeight = trackerHeight + currentBlock.height Nenue@1: numBlocks = max(numBlocks, watchIndex) Nenue@1: actualBlocks = actualBlocks + 1 Nenue@1: else Nenue@1: print('|cFFFF0000Failed to draw info for index #'..watchIndex) Nenue@1: end Nenue@1: Nenue@1: elseif watchIndex <= numBlocks then Nenue@1: local used = handler.usedBlocks Nenue@1: local free = handler.freeBlocks Nenue@1: print('clean up dead quest block') Nenue@1: if used[blockIndex] then Nenue@1: used[blockIndex]:Hide() Nenue@1: used[blockIndex]:ClearAllPoints() Nenue@1: free[#free+1]= used[blockIndex] Nenue@1: used[blockIndex] = nil Nenue@1: end Nenue@1: else Nenue@1: print('Stopping scan at', blockIndex) Nenue@1: break -- done with quest stuff Nenue@1: end Nenue@1: end Nenue@1: handler.numWatched = numWatched Nenue@1: handler.numBlocks = numBlocks Nenue@1: handler.actualBlocks = actualBlocks Nenue@1: handler:Report() Nenue@1: previousBlock = nil Nenue@1: if numBlocks > 0 then Nenue@1: tracker.height = trackerHeight Nenue@1: else Nenue@1: tracker.height = 0 Nenue@1: end Nenue@1: Nenue@1: print('|cFF00FF88)|r ->', numBlocks, 'blocks; height', tracker.height, 'last block: ') Nenue@1: end Nenue@1: Nenue@1: mod.Quest.numButtons = 0 Nenue@1: local usedButtons = mod.Quest.itemButtons Nenue@1: local freeButtons = mod.Quest.freeButtons Nenue@1: mod.UpdateWrapper = function() Nenue@1: wrapperWidth = wrapperMaxWidth Nenue@1: scrollWidth = wrapperWidth Nenue@1: local wrapperBlocks = 0 Nenue@1: -- Update scroll child vertical size Nenue@1: scrollHeight = 0 Nenue@1: for i, handler in ipairs(orderedHandlers) do Nenue@1: mod.UpdateTracker(handler) Nenue@1: if handler.actualBlocks >= 1 then Nenue@1: local tracker = handler.Tracker Nenue@1: print('setting', handler.Tracker, 'to anchor to offset', -scrollHeight) Nenue@1: tracker:SetParent(Scroll) -- this doesn't do anything that relativeTo doesn't Nenue@1: tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) Nenue@1: tracker:SetSize(wrapperWidth, tracker.height) Nenue@1: print('adding ', tracker.height) Nenue@1: scrollHeight = scrollHeight + tracker.height Nenue@1: end Nenue@1: wrapperBlocks = wrapperBlocks + handler.actualBlocks Nenue@1: end Nenue@1: print('final scrollHeight:', scrollHeight) Nenue@1: Nenue@1: Nenue@1: Nenue@1: -- Update frame dimensions Nenue@1: if scrollHeight > wrapperMaxHeight then Nenue@1: print(' is larger than', wrapperMaxHeight) Nenue@1: --ScrollBar:Show() Nenue@1: --scrollWidth = wrapperMaxWidth - scrollBarWidth Nenue@1: wrapperHeight = wrapperMaxHeight Nenue@1: -- Make ThumbTexture reflect the viewing scale (smaller for longer scroll, bigger for shorter) Nenue@1: --ScrollBar:GetThumbTexture():SetHeight((wrapperMaxHeight/scrollHeight) * (wrapperMaxHeight)) Nenue@1: --ScrollBar:SetWidth(scrollBarWidth) Nenue@1: --ScrollBar:SetPoint('TOPRIGHT', Scroller, 'TOPRIGHT', 0, 0) Nenue@1: --ScrollBar:SetPoint('BOTTOMLEFT', Scroller, 'BOTTOMRIGHT', -scrollBarWidth, 0) Nenue@1: --ScrollBar:SetMinMaxValues(1, scrollHeight - wrapperMaxHeight) Nenue@1: else Nenue@1: --ScrollBar:Hide() Nenue@1: wrapperHeight = scrollHeight Nenue@1: end Nenue@1: scrollWidth = floor(scrollWidth+.5) Nenue@1: scrollHeight = floor(scrollHeight+.5) Nenue@1: wrapperWidth = floor(wrapperWidth+.5) Nenue@1: wrapperHeight = floor(wrapperHeight+.5) Nenue@1: headerHeight = floor(headerHeight+.5) Nenue@1: Nenue@1: if wrapperBlocks >= 1 then Nenue@2: for i, region in ipairs(Wrapper.header) do Nenue@2: region:Show() Nenue@2: end Nenue@1: else Nenue@2: for i, region in ipairs(Wrapper.header) do Nenue@2: region:Hide() Nenue@2: end Nenue@1: return Nenue@1: end Nenue@1: --wrapperHeight = scrollHeight Nenue@1: Nenue@1: print('|cFFFFFF00params:|r scroller:', scrollWidth, 'x', scrollHeight) Nenue@1: print('|cFFFFFF00params:|r scroll:', scrollWidth, 'x', scrollHeight) Nenue@1: print('|cFFFFFF00params:|r wrapper:', wrapperWidth, 'x', wrapperHeight) Nenue@1: print('|cFFFFFF00params:|r header:', headerHeight) Nenue@1: Nenue@1: Scroller:SetSize(wrapperWidth, wrapperHeight) Nenue@1: Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, -headerHeight) Nenue@1: Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT') Nenue@1: Nenue@1: Scroll:SetSize(scrollWidth, scrollHeight) Nenue@1: Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, 0) Nenue@1: Scroll:SetPoint('RIGHT', Scroller, 'RIGHT') Nenue@1: Nenue@1: --Scroller:UpdateScrollChildRect() Nenue@1: Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight) Nenue@1: Nenue@1: -- update action buttons Nenue@1: Nenue@1: Nenue@1: print('scroll size:', Scroll:GetSize()) Nenue@1: print('scroller size:',Scroller:GetSize()) Nenue@1: print('wrapper size:', Wrapper:GetSize()) Nenue@1: print('scroll range :', floor(Scroller:GetVerticalScrollRange()+.5)) Nenue@1: Nenue@1: Nenue@1: mod.UpdateActionButtons() Nenue@1: end Nenue@1: Nenue@1: --- Queue any active item buttons for update for that frame Nenue@1: mod.UpdateActionButtons = function() Nenue@1: local previousItem Nenue@2: for questID, itemButton in pairs(usedButtons) do Nenue@2: local questIndex = mod.Quest.Info[questID].questLogIndex Nenue@3: print('|cFF00FFFF', questID, itemButton:GetName()) Nenue@3: local block = mod.Quest.LogBlock[questID] Nenue@1: print(block:GetTop()) Nenue@1: if block then Nenue@1: if IsQuestWatched(questIndex) then Nenue@1: -- Dispatch the probe Nenue@1: block:SetScript('OnUpdate', function() Nenue@1: print('|cFFFFFF00probing', block:GetName()) Nenue@1: if block:GetBottom() then Nenue@1: print('|cFF00FF00ding ding ding!') Nenue@1: mod.UpdateBlockAction(block, itemButton, previousItem) Nenue@1: block:SetScript('OnUpdate', nil) Nenue@1: end Nenue@1: end) Nenue@1: return Nenue@1: else Nenue@2: mod.FreeItemButtons(block) Nenue@1: end Nenue@1: end Nenue@1: end Nenue@1: end Nenue@1: Nenue@1: mod.UpdateBlockAction = function (block, itemButton, previousItem) Nenue@2: if block.itemButton ~= itemButton then Nenue@2: block.itemButton = itemButton Nenue@2: end Nenue@2: if itemButton.block ~= block then Nenue@2: itemButton.block = block Nenue@2: end Nenue@2: Nenue@1: if block:GetBottom() < Scroller:GetBottom() then Nenue@1: print('|cFFFFFF00bottom not fully visible') Nenue@1: if previousItem then Nenue@1: previousItem:ClearAllPoints() Nenue@1: previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, 4) Nenue@1: end Nenue@1: itemButton:ClearAllPoints() Nenue@1: itemButton:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', Wrapper:GetLeft(), Wrapper:GetBottom()) Nenue@1: itemButton:Show() Nenue@1: else Nenue@1: print('|cFF00FF00visible positions') Nenue@1: itemButton:ClearAllPoints() Nenue@1: itemButton:SetPoint('TOPRIGHT', UIParent, 'BOTTOMLEFT', block:GetLeft(), block:GetTop()) Nenue@1: itemButton:Show() Nenue@1: end Nenue@1: end Nenue@1: Nenue@1: mod.UpdateItemButtonCooldown = function(button) Nenue@1: Nenue@1: end