Mercurial > wow > buffalo2
view ObjectiveTracker/ObjectiveFrame.lua @ 27:c3aa94bc6be2
collating module-specific function into their own files and dropping the UI and Style scripts
author | Nenue |
---|---|
date | Wed, 13 Apr 2016 20:18:50 -0400 |
parents | 4b3da1b221de |
children |
line wrap: on
line source
--- ${PACKAGE_NAME} -- @file-author@ -- @project-revision@ @project-hash@ -- @file-revision@ @file-hash@ -- Created: 3/30/2016 12:49 AM local B = select(2,...).frame local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame local print = B.print('Tracker') local unitLevel = 1 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON local debug = false -------------------------------------------------------------------- --- Global frame layout -------------------------------------------------------------------- --- Upvalues local Wrapper = _G.VeneerObjectiveWrapper local Scroller = Wrapper.scrollArea local Scroll = _G.VeneerObjectiveScroll local orderedHandlers = T.orderedHandlers local orderedNames = T.orderedNames --- Temp values set during updates local wrapperWidth, wrapperHeight local scrollWidth, scrollHeight local previousBlock local currentBlock --- todo: source these from config local itemButtonSize, itemButtonSpacing = 36, 1 local headerHeight, headerColor, headerSpacing = 16, {1,1,1,1}, 2 local headerbg = {'VERTICAL', 1, 1, 0.5, 0.5, 1, 1, 0.5, 0} local headerFont, headerSize, headerOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 14, 'OUTLINE' local titlebg = {'HORIZONTAL', 1, 0, .7, .25, 1, 0, .7, .125} local titlebg_daily = {'HORIZONTAL', 0, .7, 1, .25, 0, 1, .7, .125 } local titlebg_account = {'HORIZONTAL', 0, .45, 1, .25, 0, .45, 1, .125} local titleFont, titleSize, titleOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE' local textbg = {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 } local textbg_daily = {'HORIZONTAL', 0, .7, 1, .1, 0, 1, .7, .075 } local textbg_account = {'HORIZONTAL', 0, .45, 1, 0.4, 0, .41, 1, .085 } local textFont, textSize, textOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE' local selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225} local titleSpacing, textSpacing, blockSpacing = 3, 3, 1 local titleIndent, textIndent,selectionIndent = 2, 5, 50 local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE' local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 } local rewardSize = 32 local oprint = B.print('Objectives') local bprint = B.print('Block') local tprint = B.print('Tracker') local lprint = B.print('Line') local currentPosition, anchorFrame, anchorPoint T.AddBlock = function(handler, block) local print = bprint end --- Used as an iterator of sorts for cascaded tag icon placements (the daily/faction/account icons) T.AddTag = function (block, tagName, tagPoint, tagAnchor, tagRelative) local print = bprint local tag = block[tagName] if block.info[tagName] and tag then tag:SetTexCoord(unpack(block.info[tagName])) tag:Show() tag:SetPoint(tagPoint, tagAnchor, tagRelative, 0, 0) tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', tag, 'TOPLEFT' else block[tagName]:Hide() end return tagPoint, tagAnchor, tagRelative end --- Adds the given line to the current content and advances the anchor pointer to that new line for the following call. T.AddLine = function(block, line) local print = lprint line:ClearAllPoints() line:SetPoint('LEFT', block, 'LEFT', 0, 0) line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) line:SetPoint('RIGHT', block, 'RIGHT', 0, 0) line:SetHeight(line.height) line:Show() block.endIndex = line.index block.numLines = block.numLines + 1 block.attachmentHeight = block.attachmentHeight + (line.height + textSpacing) print(' |cFF0088FFsetting line #'..block.numLines..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, "|cFF0088FFpoint:|r", line:GetPoint(1), "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) block.endPoint = line end --- Creates or retrieves a complete line data object T.GetLine = function(handler, block, lineIndex) local print = lprint local blockIndex = block.index if not block.lines then block.lines = {} end local lines = block.lines if not lines[lineIndex] then print(' |cFF00FF88created line #'..lineIndex..' from for '..handler.name..' block #'..blockIndex) lines[lineIndex] = CreateFrame('Frame', 'Vn'..handler.name .. blockIndex..'ObjectiveLine'..lineIndex, block, 'VeneerTrackerObjective') local line = lines[lineIndex] line.index = lineIndex line.height = 0 line.status:SetSpacing(textSpacing) line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) B.SetConfigLayers(line) if lines[lineIndex+1] then lines[lineIndex+1]:ClearAllPoints() end if debug then for _, region in ipairs(lines[lineIndex].debug) do region:Show() end end end return lines[lineIndex] end --- Creates or retrieves a complete block frame object T.GetBlock = function(handler, blockIndex) local print = bprint local block = handler.usedBlocks[blockIndex] if not handler.usedBlocks[blockIndex] then if #handler.freeBlocks >= 1 then block = handler.freeBlocks[#handler.freeBlocks] handler.freeBlocks[#handler.freeBlocks] = nil else block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock') local c = T.Conf.Wrapper block.index = blockIndex block.SetStyle = T.SetBlockStyle block:SetWidth(c.Width) block.title:SetSpacing(c.TitleSpacing) block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing) block.titlebg:SetTexture(1,1,1,1) block.titlebg:SetGradientAlpha(unpack(T.colors.default.titlebg)) block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0) block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing) block.status:SetSpacing(c.TextSpacing) block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing) block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0) block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0) block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0) block.statusbg:SetTexture(1,1,1,1) block.statusbg:SetGradientAlpha(unpack(T.colors.default.textbg)) block.SelectionOverlay:SetGradientAlpha(unpack(T.colors.default.selectionbg)) block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0) block.SelectionOverlay:SetPoint('BOTTOMRIGHT') block.icon:SetSize(rewardSize, rewardSize) block.icon:SetPoint('TOPRIGHT', block, 'TOPRIGHT', -2, -2) --- methods for event handlers block.Select = handler.Select block.Open = handler.Open block.Remove = handler.Remove block.Link = handler.Link block.clickZone:SetScript('OnMouseUp', function(self, ...) handler.OnMouseUp(block, ...) end) block.clickZone:SetScript('OnMouseDown', function(self, ...) handler.OnMouseDown(block, ...) end) block.attachmentHeight = 0 block:ClearAllPoints() B.SetConfigLayers(block) if debug then for _, region in ipairs(block.debug) do region:Show() end end end handler.usedBlocks[blockIndex] = block end return handler.usedBlocks[blockIndex] end --- Module-specific data wrangling that has to happen during UpdateBlock() -- Most of this is sculpting objectives data into a parsible list. -- Some of it is additional block manipulation that doesn't quite fit with the other modules.. Bonus.UpdateObjectives = function(handler, block) Default.UpdateObjectives(handler, block) end --- They are not exactly quests, but the aliases used to signal that a quest was pushed into your log by the environment. -- Once accepted they never appear again unless the quest is dropped (daily reset/abandon quest) local CLICK_TO_COMPLETE = 'Click to Complete' local CLICK_TO_ACCEPT = 'Click to Accept' AutoQuest.UpdateObjectives = function(handler, block) local print = lprint if block.info.type == 'OFFER' then block.status:SetText(CLICK_TO_ACCEPT) end end --- Does the main iterations for populating block content. -- Hooked by corresponding handler functions where additional details need to be sorted. Default.UpdateObjectives = function(handler, block) local print = lprint local info = block.info print(' |cFF00FF00default objectives routine', block:GetName()) -- reset the starting positions block.attachmentHeight = 0 block.endPoint = block.titlebg local completionScore, completionMax = 0, 0 local displayObjectiveHeader = false --- The first line is going to be used no matter what, so it is hard-pulled. -- It also ensures that we're in the right position for cleaning up the leftover lines. local lineIndex = 1 local line = T.GetLine(handler, block, lineIndex) block.numLines = 0 block.attachmentHeight = 0 if info.description and #info.description >= 1 then print(' |cFF00FFFF header line:|r', info.description) line.status:SetText(info.description) line.height = floor(line.status:GetStringHeight()+.5) + textSpacing if line.widget then line.widget:Hide() end T.AddLine(block, line) lineIndex = lineIndex + 1 line = T.GetLine(handler, block, lineIndex) end if (info.isComplete == true or info.isComplete == nil) and info.completionText then print(' overriding line #1 for completion text:', info.completionText) line.status:SetText(info.completionText) line.height = floor(line.status:GetStringHeight()+.5) + textSpacing if line.widget then line.widget:Hide() end T.AddLine(block, line) else if info.objectives then for i, data in ipairs(info.objectives) do print(' |cFF88FF00#', i, data.type, data.text) displayObjectiveHeader = true line.height = 0 handler:UpdateLine(block, line, data) -- For progressbar and timer lines, status text may be used as the title heading if line.widget then local widgetPosition = 0 --- WIDGET POSITION ------------------------------------------------- line.widget:SetPoint('TOP', line, 'TOP', 0, -widgetPosition) line.widget:Show() line.height = line.widget:GetHeight() + textSpacing --------------------------------------------------------------------- if line.displayText and #line.displayText >= 1 then widgetPosition = line.status:GetHeight() + textSpacing line.status:SetText(line.displayText) line.height = floor(line.status:GetStringHeight()+.5) + textSpacing + line.widget.height print(' - progressbar has text, adjust') end elseif line.displayText then line.status:SetText(line.displayText) line.height = floor(line.status:GetStringHeight()+.5) end T.AddLine(block, line) --print(' sz', line:GetWidth(), line:GetHeight(), 'pt', line:GetPoint(1)) --print(' |cFF44BBFF#', i, 'anchoring line, size:', line.height, 'current endpoint:', line.statusbg) lineIndex = lineIndex + 1 line = T.GetLine(handler, block, lineIndex) end end end while (block.lines[lineIndex+1]) do print(' - hide |cFFFF0088'..lineIndex..'|r') block.lines[lineIndex]:Hide() lineIndex = lineIndex +1 end if lineIndex > 0 then block.attachmentHeight = block.attachmentHeight + textSpacing * 2 print(' |cFF00FF00attachment:', block.attachmentHeight) end --[[ local lines = handler.lines[block.index] if lines and #lines > block.numLines then print(' |cFFFF008' .. (#lines - block.numLines) .. ' extra lines to hide.') for i = block.numLines + 1, #lines do print(' hide', i, lines[i]:GetName()) lines[i]:Hide() end end ]] if debug then for i, region in ipairs(block.debug) do for j = 1, region:GetNumPoints() do local _, target = region:GetPoint(j) if target:IsVisible() then region:Hide() else region:Show() end end end end block.completionScore = completionScore / completionMax end --- Module-specific display variables -- * height - height of whatever display widget is involved in conveying the task -- * money - boolean that determines listening for money events or not -- * progress - number ranging 0 to 2 indicating none/partial/full completion respectively Bonus.UpdateLine = function(handler, block, line, data) local info = block.info local print = lprint line.displayColor = 'FFFFFF' line.displayText = data.text line.progress = 0 print(' ', data.objectiveIndex,'|cFFFF0088-|r', data.objectiveType, data.text) if data.objectiveType == 'progressbar' then line.widgetType = 'ProgressBar' print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) data.value = GetQuestProgressBarPercent(info.questID) or 0 data.maxValue = 100 if data.value >= data.maxValue then line.progress = 1 elseif data.value > 0 then line.progress = 2 end line.format = PERCENTAGE_STRING local widget = T.SetWidget(line, data, 'ProgressBar', info.questID..'-'..data.objectiveIndex) print(' |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue) widget:SetPoint('TOP', line, 'TOP', 0, 0) line.widget = widget line.height = widget.height else line.displayText = data.text line.widget = nil end return line end Cheevs.UpdateLine = function(handler, block, line, data) local print = B.print('CheevsLine') line.progress = 0 print(' ', data.objectiveIndex,'|cFF0088FF-|r', data.objectiveType, data.text) if data.flags then if band(data.flags, 0x00000001) > 0 then line.format = "%d/%d" line.widget = T.SetWidget(line, data, 'ProgressBar', data.criteriaID) line.height = line.widget.height elseif band(data.flags, 0x00000002) then line.widget = nil else line.widget = nil line.displayColor = 'FFFFFF' line.displayText = line.text end else line.displayText = data.text end print('line.type =', data.type) print(' ** qtyStr:', data.quantityString, 'qty:', data.quantity, 'assetID:', data.assetID) end Default.UpdateLine = function(block, line) if line.finished then line.progress = 2 elseif line.quantity > 0 then line.progress = 1 else line.progress = 0 end return line end T.Quest.numButtons = 0 local usedButtons = T.Quest.itemButtons local freeButtons = T.Quest.freeButtons --[=[ T.UpdateWrapper = function(reason) print('|cFF00FFFFUpdateWrapper:|r', reason) unitLevel = UnitLevel('player') wrapperWidth = T.Conf.Wrapper.WrapperWidth scrollWidth = T.Conf.Wrapper.WrapperWidth local wrapperBlocks = 0 -- Update scroll child vertical size scrollHeight = 0 for i, handler in ipairs(orderedHandlers) do T.UpdateTracker(handler) local frame = handler.frame if handler.actualBlocks >= 1 then frame:SetParent(Scroll) frame:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) frame:SetSize(wrapperWidth, frame.height) print('|cFF00FFFF'..frame:GetName()..'|r h:|cFF00FF00', frame.height, '|r y:|cFF00FF00', -scrollHeight) scrollHeight = scrollHeight + frame.height frame:Show() else frame:Hide() end wrapperBlocks = wrapperBlocks + handler.actualBlocks end print('final scrollHeight:', scrollHeight) -- Update frame dimensions if scrollHeight > wrapperMaxHeight then print(' is larger than', wrapperMaxHeight) wrapperHeight = wrapperMaxHeight else wrapperHeight = scrollHeight B.Conf.ObjectiveScroll = 0 end scrollWidth = floor(scrollWidth+.5) scrollHeight = floor(scrollHeight+.5) wrapperWidth = floor(wrapperWidth+.5) wrapperHeight = floor(wrapperHeight+.5) headerHeight = floor(headerHeight+.5) if wrapperBlocks >= 1 then for i, region in ipairs(Wrapper.headerComplex) do region:Show() end else for i, region in ipairs(Wrapper.headerComplex) do region:Hide() end return end --[[wrapperHeight = scrollHeight print('|cFFFFFF00params:|r scroller:', scrollWidth .. ',' .. scrollHeight, 'scroll:', scrollWidth .. ',' .. scrollHeight, 'wrapper:', wrapperWidth .. ',' .. wrapperHeight, 'header:', headerHeight)]] --Scroller:SetSize(wrapperWidth, wrapperHeight) Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, 0) Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT') Scroll:SetSize(scrollWidth, scrollHeight) Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, B.Conf.ObjectiveScroll or 0) Scroll:SetPoint('RIGHT', Scroller, 'RIGHT') --Scroller:UpdateScrollChildRect() Wrapper:SetSize(wrapperWidth, wrapperHeight) --[[ update action buttons print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(), '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(), '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(), '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5) ) --]] T.UpdateActionButtons() end --]=] Default.Update = function (self, reason, ...) local print = tprint local tracker = self.frame local blockIndex = 0 local trackerHeight = headerHeight tracker.title:SetFont(headerFont, headerSize, headerOutline) tracker.titlebg:SetHeight(headerHeight) tracker.title:SetTextColor(unpack(headerColor)) --tracker.titlebg:SetGradientAlpha(unpack(headerbg)) self.currentAnchor = tracker.titlebg local numWatched = self:GetNumWatched() local numBlocks = self.numBlocks local actualBlocks = 0 for watchIndex = 1, 25 do blockIndex = blockIndex + 1 if watchIndex <= numWatched then local info = self:GetInfo(watchIndex) if info then local currentBlock = self:UpdateBlock(blockIndex, info) currentBlock:SetPoint('TOPLEFT', self.currentAnchor, 'BOTTOMLEFT', 0, 0) currentBlock:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) self.currentAnchor = currentBlock print(' |cFFFFFF00'..watchIndex..'|r', '|cFF00FF00'..currentBlock:GetName()..'|r', currentBlock.height, trackerHeight) trackerHeight = trackerHeight + currentBlock.height numBlocks = max(numBlocks, watchIndex) actualBlocks = actualBlocks + 1 else print(' |cFFFF0000bad GetInfo data for #'..watchIndex) end elseif watchIndex <= numBlocks then local used = self.usedBlocks local free = self.freeBlocks print('clean up dead quest block') if used[blockIndex] then used[blockIndex]:Hide() used[blockIndex]:ClearAllPoints() free[#free+1]= used[blockIndex] used[blockIndex] = nil end else print(' |cFFFF9900END|r @', blockIndex) break -- done with quest stuff end end self.numWatched = numWatched self.numBlocks = numBlocks self.actualBlocks = actualBlocks tracker.previousHeight = tracker.height if numBlocks >= 1 then previousBlock = nil if tracker.isEmpty then tracker.headerFade:Play() tracker.isEmpty = nil end tracker.height = trackerHeight tracker:SetHeight(tracker.height) tracker:Show() else tracker.isEmpty = true tracker.height = 0 tracker:Hide() end return tracker.numWatched, tracker.numAll end --- Updates the selected block frame to display the given info batch -- If `previousBlock` is set, it will attempt to anchor to that -- @param blockNum the ordered block to be updated, not a watchIndex value -- @param info the reference returned by the GetXInfo functions -- REMEMBER: t.info and questData[questID] are the same table Default.UpdateBlock = function (handler, blockIndex, info) local print = bprint print(' Read list item |cFF00FFFF'..blockIndex..'|r') if not blockIndex or not info then return end local frame = handler.frame local block = T.GetBlock(handler, blockIndex) block.handler = handler block.info = info block.mainStyle = info.mainStyle or 'Normal' block.subStyle = info.subStyle info.blockIndex = blockIndex if info.questID then handler.QuestBlock[info.questID] = block end if info.questLogIndex then handler.LogBlock[info.questLogIndex] = block end if info.watchIndex then handler.WatchBlock[info.watchIndex] = block end handler.BlockInfo[blockIndex] = info block.endPoint = block.titlebg block.attachmentHeight = 0 handler:UpdateObjectives(block) block.title:SetText(info.title) local titleHeight = floor(block.title:GetHeight()+.5) local statusHeight = floor(block.status:GetHeight()+.5) local attachmentHeight =floor(block.attachmentHeight + .5) local titlebgHeight = titleHeight + titleSpacing*2 local statusbgHeight = statusHeight + textSpacing*2 block.titlebg:SetHeight(titlebgHeight) print(' |cFF0088FFanchor to', handler.currentAnchor:GetName()) print(' |cFF00FF00total sizes:') print(' attachment:', attachmentHeight) print(' title:', titlebgHeight, '('.. titleHeight..')') --block.titlebg:SetHeight(block.title:GetHeight() + T.Conf.Wrapper.TitleSpacing) block.height = titlebgHeight + attachmentHeight if statusHeight > 1 then block.height = block.height + statusbgHeight print(' status:', statusbgHeight, '('.. statusHeight..')') else print(' |cFFFF0088 skipped') end block:SetHeight(block.height) print(' |cFFFFFF00height|r:', block.height) print(' |cFF00FFFF)|r -> ', block, block:GetHeight()) block:Show() if info.specialItem and not info.itemButton then print(' - |cFF00FFFFgenerating item button for info set') info.itemButton = T.SetItemButton(block, info) else --info.itemButton = nil end local tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', block, 'TOPRIGHT' if info.rewardInfo then print('has immediate reward') if info.rewardInfo[1].type == 'currency' or info.rewardInfo[1].type == 'item' then block.icon:Show() block.iconLabel:SetText(info.rewardInfo[1].count) block.icon:SetPoint(tagPoint, tagAnchor, tagRelative, -2, -2) tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', block.icon, 'TOPLEFT' block.icon:SetTexture(info.rewardInfo[1].texture) end else block.icon:Hide() end if info.selected then block.SelectionOverlay:Show() else block.SelectionOverlay:Hide() end -- workaround for scrollchild issue where layers fall out of sync: in this case, it's by 1 vertical pixel --block.highlight:SetPoint('TOPLEFT', block, 'TOPLEFT', 0, 1) --block.lowlight:SetPoint('BOTTOMLEFT', block, 'BOTTOMLEFT', 0, 1) tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative) tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative) tagPoint, tagAnchor, tagRelative = T.AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative) return block end ---------- --- Top level methods local tick = 0 function T:Update (reason, ...) tick = tick + 1 local print = tprint reason = reason or OBJECTIVE_TRACKER_UPDATE_REASON local updateWrapper = 0 local hasStuff local insertingStuff print(format('%d |cFFFF%04X Update()', tick, lshift(reason, 4)), reason, ...) currentPosition = 0 anchorPoint = 'TOP' anchorFrame = Scroll local wrapperHeight = 0 for id, handler in pairs(T.orderedHandlers) do local frame = handler.frame print(format('|cFF00FFFF%s and(%04X vs %04x+%04x) = %04X|r', handler.name, reason, handler.updateReasonModule, handler.updateReasonEvents, band(reason, handler.updateReasonModule + handler.updateReasonEvents))) if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then handler:Update(reason, ...) print(' |cFF00FF00'..id..'|r', handler.displayName, 'count:', handler.numWatched) insertingStuff = true else print(' |cFFFF0088'..id..'|r', 'no reason to update') end if handler.numWatched >= 1 then hasStuff = true currentPosition = currentPosition + 1 frame:SetParent(Scroll) frame:SetPoint('TOP', anchorFrame, anchorPoint, 0, 0) print(' |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint) anchorFrame = handler.frame anchorPoint = 'BOTTOM' print('current frame height:', frame.height) wrapperHeight = wrapperHeight + frame.height print('|cFFFF0088total height:', wrapperHeight) else handler.frame:Hide() end end if hasStuff or insertingStuff then print('updating height to', wrapperHeight) Wrapper:SetHeight(wrapperHeight) Scroller:SetHeight(wrapperHeight) Scroll:SetHeight(wrapperHeight) Scroller:SetVerticalScroll(B.Conf.ObjectiveScroll or 0) print('|cFFFF8800Wrapper:', Wrapper:GetSize()) for i = 1, Wrapper:GetNumPoints() do print(' ', Wrapper:GetPoint(i)) end print(' |cFF00FFFFScroller:', Scroller:GetSize()) for i = 1, Scroller:GetNumPoints() do print(' ', Scroller:GetPoint(i)) end print(' |cFF00FFFFScroll:', Scroll:GetSize()) for i = 1, Scroll:GetNumPoints() do print(' ', Scroll:GetPoint(i)) end Wrapper:Show() Scroller:Show() Scroll:Show() end Quest.GetClosest() --T.UpdateActionButtons(reason) end --- Queue any active item buttons for update for that frame local iprint = B.print('ItemButton') T.UpdateActionButtons = function(updateReason) local print = iprint Scroller.snap_upper = 0 Scroller.snap_lower = 0 local print = B.print('ItemButton') if updateReason then print = B.print('IB_'..updateReason) end local previousItem for questID, itemButton in pairs(Quest.itemButtons) do local info= T.Quest.Info[questID] print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) local block = T.Quest.QuestBlock[questID] if block then -- Dispatch the probe if IsQuestWatched(info.questLogIndex) then itemButton.previousItem = previousItem print(' |cFFFFFF00probing', block:GetName()) block:SetScript('OnUpdate', function() if block:GetBottom() and not InCombatLockdown() then print(' '..block:GetName()..' |cFF00FF00probe hit!') T.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope block:SetScript('OnUpdate', nil) end end) previousItem = itemButton else print('hidden block or unwatched quest') itemButton.previousItem = nil itemButton:Hide() end elseif itemButton:IsVisible() then print(' |cFFFF0088hiding unwatched quest button', itemButton:GetName()) itemButton.previousItem = nil itemButton:Hide() else print(' |cFFBBBBBBignoring hidden log quest button', itemButton:GetName()) end end end T.UpdateBlockAction = function (block, itemButton) local print = iprint print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()') if itemButton.questID ~= block.info.questID then print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID) -- something happened between this and last frame, go back and set new probes return T.UpdateActionButtons() end local previousItem = itemButton.previousItem local upper_bound = Scroller:GetTop() + Scroller.snap_upper local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize local point, anchor, relative if block:GetBottom() < lower_bound then print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5)) if previousItem then print('adjusting', previousItem:GetName()) previousItem:ClearAllPoints() previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing) end itemButton:ClearAllPoints() itemButton.x = Wrapper:GetLeft() -4 itemButton.y = Wrapper:GetBottom() point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT' Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing elseif block:GetTop() > upper_bound then print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5)) itemButton:ClearAllPoints() if previousItem then print('latch onto another piece') point, anchor, relative ='TOP', previousItem, 'BOTTOM' itemButton.x = 0 itemButton.y = -itemButtonSpacing else print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop()) point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' itemButton.x = Scroller:GetLeft() -4 itemButton.y = Scroller:GetTop() end itemButton:Show() Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing) else print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5)) itemButton:ClearAllPoints() itemButton.x = block:GetLeft() - itemButtonSpacing itemButton.y = block:GetTop() point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' end itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y) itemButton:Show() end T.UpdateItemButtonCooldown = function(button) end local unitLevel = UnitLevel('player')