Mercurial > wow > buffalo2
view ObjectiveTracker/Frame.lua @ 34:9856ebc63fa4
- half solution to Update being fired multiple times during load
- change securefunc handlers to dispense a reason code; catch that reason code in the enclosure passed to hooksecurefunc, and decide whether to update or not from there.
author | Nenue |
---|---|
date | Sun, 17 Apr 2016 00:21:45 -0400 |
parents | 64f2a9bbea79 |
children | 69d03f8e293e |
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 Module = 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, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove 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 = Module.DefaultHandler, Module.AutoQuest, Module.Quest, Module.Bonus, Module.Cheevs local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow local print = B.print('Tracker') local oprint = B.print('Objectives') local bprint = B.print('Block') local tprint = B.print('Tracker') local lprint = B.print('Line') local unitLevel = 1 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON local debug = false --- FRAMES local Wrapper = _G.VeneerObjectiveWrapper local Scroller = Wrapper.scrollArea local Scroll = _G.VeneerObjectiveScroll local orderedHandlers = Module.orderedHandlers local orderedNames = Module.orderedNames --- FRAME TEMP VARIABLES local wrapperWidth, wrapperHeight local scrollWidth, scrollHeight --- SCHEMA VARIABLES local schemaName, lastSchema = { tracker = '', block = '', line = '' }, {} local trackerSchema, blockSchema, lineSchema local itemButtonSize, itemButtonSpacing = 36, 1 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 = 24 local headerHeight, headerColor, headerSpacing = 16, {1,.75,0,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, 0, 1, 0, .7, .2} local titleFont, titleSize, titleOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE' local titleColor = {0,.7,1,1} local textbg = {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 } local textFont, textSize, textOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE' local textColor = {1,1,1,1} 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 --- END SCHEMA --- schema swapper Module.UpdateSchema = function(layer, newSchema) if not (Module.Conf.Schema[layer] and Module.Conf.Schema[layer][newSchema]) then return elseif schemaName[layer] == newSchema then return end lastSchema[layer] = schemaName[layer] schemaName[layer] = newSchema local c = Module.Conf.Schema[layer][newSchema] if layer == 'tracker' then headerHeight, headerSpacing = c.headerHeight, c.headerSpacing headerColor = c.headerColor headerbg = c.headerbg headerFont, headerSize, headerOutline = c.headerFont, c.headerSize, c.headerOutline trackerSchema = newSchema elseif layer == 'block' then titlebg = c.titlebg titleFont, titleSize, titleOutline = c.titleFont, c.titleSize, c.titleOutline selectionbg = c.selectionbg titleSpacing, textSpacing, blockSpacing = c.titleSpacing, c.textSpacing, c.blockSpacing titleIndent, textIndent,selectionIndent = 2, 5, 50 titleColor = c.titleColor rewardSize = 24 blockSchema = newSchema textFont, textSize, textOutline = c.textFont, c.textSize, c.textOutline textbg = c.textbg textIndent = c.textIndent rewardSize = c.rewardSize elseif layer == 'line' then textColor = c.textColor lineSchema = newSchema end print('|cFFFF0088UpdateSchema:|r', layer, lastSchema[layer], '->', newSchema) end Default.AddBlock = function(self, block, blockIndex) local blockIndex = blockIndex or (self.currentBlock + 1) local print = bprint local tracker = self.frame local info = block.info if blockSchema ~= block.schema then print('new schema detected, applicating...') block.schema = blockSchema block:SetWidth(Module.Conf.Wrapper.Width) block.title:SetSpacing(titleSpacing) block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing) block.title:SetPoint('LEFT', block, 'LEFT', titleIndent, 0) block.titlebg:SetTexture(1,1,1,1) block.titlebg:SetGradientAlpha(unpack(titlebg)) block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0) block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing) block.status:SetSpacing(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(textbg)) block.SelectionOverlay:SetGradientAlpha(unpack(selectionbg)) block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0) block.SelectionOverlay:SetPoint('BOTTOMRIGHT') local anchor, target, point, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 for i, tile in ipairs(block.rewardTile) do print(rewardSize) tile:SetSize(rewardSize, rewardSize) tile:ClearAllPoints() tile:SetPoint(anchor, target, point, x, y) block.rewardLabel[i]:SetPoint('TOP', tile, 'TOP', 0, 0) anchor, target, point, x, y = 'TOPRIGHT', tile, 'TOPLEFT', -2, 0 end end if block.debug then local func = (B.Conf.GuidesMode == true) and 'Show' or 'Hide' for _, region in ipairs(block.debug) do region[func]() end end -- positioned by offset since they tend to swap contents block.index = blockIndex block:SetPoint('TOPLEFT', self.frame, 'TOPLEFT', 0, block.offset) block:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) self.currentBlock = blockIndex self.currentAnchor = block print(' |cFFFFFF00'..tracker.height..'|r', '|cFF00FF00'..block:GetName()..'|r', block.height, tracker.height) tracker.height = tracker.height + block.height self.actualBlocks = self.actualBlocks + 1 end --- Used as an iterator of sorts for cascaded tag icon placements (the daily/faction/account icons) Default.AddTag = function (handler, block, tagInfo, tagPoint, tagAnchor, tagRelative) local print = bprint for order, tagName in ipairs(block.info.tagInfo) do local tag = block[tagName] if block.tagCoords[tagName] and tag then tag:SetTexCoord(unpack(block.tagCoords[tagName])) tag:Show() tag:SetPoint(tagPoint, tagAnchor, tagRelative, 0, 0) tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', tag, 'TOPLEFT' else block[tagName]:Hide() end 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. Default.AddLine = function(handler, block, text, attachment, template) local print = lprint local lineIndex = block.currentLine + 1 local line = handler:GetLine(block, lineIndex) line.index = lineIndex if line.schema ~= template then print(' |cFF00FF00change schema', template) Module.UpdateSchema('line', template) line.status:SetSpacing(textSpacing) line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) line.status:SetPoint('RIGHT', line, 'RIGHT', -textIndent, 0) line.status:SetTextColor(unpack(textColor)) line.schema = template else print(' |cFFFFFF00keep schema', template) end line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) line:Show() print(' |cFF0088FFAddLine >>|r', block, '::', block.endPoint:GetName(),'"'.. text .. '"', attachment, template) -- fill in the text, then derive pixel-rounded height line.status:SetText(text) line.height = floor(line.status:GetStringHeight()+.5) -- For progressbar and timer lines, status text may be used as the title heading if attachment then print(' |cFFFF0088doing things with a widget', attachment:GetSize()) line.height = attachment:GetHeight() if text then line.height = max(line.height, line.status:GetStringHeight()) end if attachment.status:GetText() then line.height = max(line.height, attachment.status:GetStringHeight()) end attachment:Show() end line:SetHeight(line.height) block.attachmentHeight = block.attachmentHeight + line.height + textSpacing print(' |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, "|cFF0088FFpoint:|r", line:GetPoint(1), "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) block.currentLine = lineIndex block.endPoint = line.statusbg -- edge used for the next block return lineIndex end --- Creates or retrieves a complete line data object Default.GetLine = function(handler, block, lineIndex) local print = lprint local blockIndex = block.index local lines = block.lines if not lineIndex then lineIndex = block.currentLine + 1 print(' |cFFFFFF00generating a frame') end block.numLines = max(block.numLines, lineIndex) 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 B.SetConfigLayers(line) 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 --- todo: make it use data index to avoid re-coloring every block Default.GetBlock = function(handler, logIndex) local print = bprint print('|cFFFFFF00getting a block for logID', logIndex ..',', #handler.usedBlocks,'used', #handler.freeBlocks, 'free') local block = handler.LogBlock[logIndex] if not block then if #handler.freeBlocks >= 1 then block = tremove(handler.freeBlocks) print(' assigning from free heap|cFF00FFFF', block:GetName()) else local blockIndex = handler.numBlocks + 1 block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock') block.lines = {} block.numLines = 0 block.currentLine = 0 block.attachmentHeight = 0 B.SetConfigLayers(block) --- 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:ClearAllPoints() block.index = blockIndex handler.numBlocks = max(handler.numBlocks, blockIndex) print(' |cFFFFFF00creating new|r', block:GetName()) end handler.LogBlock[logIndex] = block tinsert(handler.usedBlocks, block) else print(' |cFFFFFF00use existing block|r', block:GetName()) end return block end local currentPosition, anchorFrame, anchorPoint --- Positioning and stuff local tick = 0 local firstUpdate = true function Module:Update (reason, ...) if not B.Conf.VeneerObjectiveWrapper.enabled then return end tick = tick + 1 if firstUpdate or not reason then reason = _G.OBJECTIVE_TRACKER_UPDATE_ALL end local print = tprint local updateWrapper = 0 local hasStuff local insertingStuff print(format('|cFFBB0066Update:|r |cFFFF%04X%d|r ', tick, lshift(reason, 4)), reason, ...) currentPosition = 0 anchorPoint = 'TOP' anchorFrame = Scroll local wrapperHeight = 0 for id, handler in pairs(Module.orderedHandlers) do local frame = handler.frame if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then handler:UpdateTracker(reason, ...) insertingStuff = true else print(' |cFFFF0088'..id..'|r', 'no reason to update') end if handler.numWatched >= 1 then print(format('|cFF88FFBB%s and(%04X, %04x+%04x) = %04X|r', handler.name, reason, handler.updateReasonModule, handler.updateReasonEvents, band(reason, handler.updateReasonModule + handler.updateReasonEvents))) hasStuff = true currentPosition = currentPosition + 1 frame.destinationOffset = -wrapperHeight if (not firstUpdate) and frame.previousOffset ~= wrapperHeight and frame:IsVisible() then print(frame.SlideIn.translation) local postFrame, postPoint = anchorFrame, anchorPoint local delta = frame.destinationOffset - frame.previousOffset local _, _, _, _, offset = frame:GetPoint(1) print(' |cFF00BBFFstart slide for', delta, 'pixels, from', frame.previousOffset, '(', offset, ')') frame.SlideIn.translation:SetTarget(frame) frame.SlideIn.translation:SetOffset(0, delta) frame.SlideIn:Play() for i, b in ipairs(handler.usedBlocks) do b.SlideIn.translation:SetOffset(0, delta) b.SlideIn:Play() end local start = GetTime() frame.SlideIn:SetScript('OnFinished', function() print(' |cFF00BBFFsliding finished:', delta, 'pixels covered; duration:', GetTime()-start) frame:SetParent(Scroll) frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) frame.previousOffset = frame.destinationOffset frame.SlideIn:SetScript('OnFinished', nil) if Wrapper.destinationHeight then Wrapper:SetHeight(Wrapper.destinationHeight) Scroller:SetHeight(Wrapper.destinationHeight) Scroll:SetHeight(Wrapper.destinationHeight) Wrapper.previousHeight = Wrapper.destinationHeight Wrapper.destinationHeight = nil end end) else print(' |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint, '|rcurrent frame height:', frame.height) print(' |cFFFF0088total height:', wrapperHeight) frame:SetParent(Scroll) frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) end frame:Show() anchorFrame = handler.frame anchorPoint = 'BOTTOM' wrapperHeight = wrapperHeight + frame.height else print(' |cFFFF4400GetNumWatched:|r',handler.name, '0') frame:SetPoint('TOP', Scroll, 'TOP', 0, 0) frame.destinationOffset = 0 frame.previousOffset = 0 handler.frame:Hide() end end if hasStuff or insertingStuff then print('updating height to', wrapperHeight) if wrapperHeight > Wrapper.previousHeight then Wrapper:SetHeight(wrapperHeight) Scroller:SetHeight(wrapperHeight) Scroll:SetHeight(wrapperHeight) Wrapper.previousHeight = wrapperHeight Wrapper.destinationHeight = wrapperHeight end 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() --Module.UpdateActionButtons(reason) if firstUpdate then firstUpdate = nil end end --- Content generator base Default.UpdateTracker = function (handler, reason, id, isNew) local print = tprint local tracker = handler.frame local blockIndex = 0 tracker.previousHeight = tracker.height tracker.height = 0 tracker.title:SetFont(headerFont, headerSize, headerOutline) tracker.titlebg:SetHeight(headerHeight) tracker.title:SetTextColor(unpack(headerColor)) handler.updateReason = reason handler.numWatched = handler:GetNumWatched() if handler.numWatched >= 1 then print(' |cFF00FF88GetNumWatched:|r',handler.name, handler.numWatched, 'of', handler.numAll) end handler.currentBlock = 0 handler.currentAnchor = tracker.titlebg local blockPosition = -headerHeight for blockIndex = 1, handler.numWatched do local currentBlock = handler:UpdateBlock(blockIndex, id, isNew) if currentBlock then currentBlock.offset = blockPosition handler:AddBlock(currentBlock) blockPosition = blockPosition - currentBlock.height else print(' |cFFFF9900END|r @', blockIndex) break -- done with quest stuff end end local numBlocks = handler.numBlocks local used = handler.usedBlocks if numBlocks < #used then print(' |cFF0088FFcull the dead: showing|r', numBlocks, '|cFF0088FF out of|r', #used) local free = handler.freeBlocks local remaining = #used for i = #used, 1, -1 do print(' -', 'i='.. i, 'watchIndex='..used[i].info.watchIndex) if used[i].info.watchIndex > numBlocks then print(' clean up dead quest block') local released = tremove(used, i) released:Hide() released:ClearAllPoints() tinsert(free, used[blockIndex]) end end end if handler.currentBlock >= 1 then tracker.height = tracker.height + headerHeight tracker:Show() if tracker.wasEmpty then tracker.headerFade:Play() tracker.wasEmpty = nil end if tracker.height ~= tracker.previousHeight then tracker:SetHeight(tracker.height) end print(' |cFFFFFF00', tracker.height, tracker:GetWidth()) else tracker:Hide() tracker.wasEmpty = true 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, id, added) local print = bprint if not blockIndex then return end local info = handler:GetInfo(blockIndex) -- should match up with whatever the internal watch list has if not info then return end print(' Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..blockIndex..'|r|cFF0099FF', info.id ,'|r') local frame = handler.frame local block = handler:GetBlock(info.id) if added then -- do something if the block is being assigned a new thing end block.handler = handler block.info = info info.blockIndex = blockIndex if info.questID then handler.QuestBlock[info.questID] = block end if info.logIndex then handler.LogBlock[info.logIndex] = block end if info.watchIndex then handler.WatchBlock[info.watchIndex] = block end handler.BlockInfo[blockIndex] = info local newSchema = handler:UpdateObjectives(block) if newSchema and newSchema ~= blockSchema then Module.UpdateSchema('block', newSchema) end block.title:SetText(info.title) local titleHeight = floor(block.title:GetHeight()+.5) local titlebgHeight = titleHeight + titleSpacing*2 block.titlebg:SetHeight(titlebgHeight) local statusHeight = floor(block.status:GetHeight()+.5) local statusbgHeight = statusHeight + textSpacing*2 local attachmentHeight =floor(block.attachmentHeight + .5) print(' |cFF0088FFanchor to', handler.currentAnchor:GetName()) print(' |cFF00FF00attachment:|r', attachmentHeight, '|cFF00FF00title:|r', titlebgHeight, '('.. titleHeight..')') if attachmentHeight > 0 then attachmentHeight = attachmentHeight + textSpacing end block.height = titlebgHeight + attachmentHeight 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 = Module.SetItemButton(block, info) else --info.itemButton = nil end local tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 local numCurrency = 0 for i, rewardTile in ipairs(block.rewardTile) do if info.rewardInfo and info.rewardInfo[i] then local reward = info.rewardInfo[i] --rewardTile:SetPoint(tagPoint, tagAnchor, tagRelative, -2, -2) rewardTile:SetTexture(reward.texture) rewardTile:Show() print('updating reward tile #'.. i, reward.type, reward.count, reward.text, reward.texture) if reward.count and reward.count > 1 then block.rewardLabel[i]:SetText(reward.count) block.rewardLabel[i]:Show() end rewardTile:ClearAllPoints() rewardTile:SetPoint(tagPoint, tagAnchor, tagRelative, x, y) tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', rewardTile, 'TOPLEFT', -2, 0 else rewardTile:Hide() block.rewardLabel[i]:Hide() end 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) if info.tagInfo then tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative) tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative) tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative) end if info.statusKey and (Devian and Devian.InWorkspace()) then block.debugText:SetText(info.statusKey) block.debugText:Show() end return block 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, block_schema) local print = lprint local info = block.info print('|cFF00FF00default.objectives', block:GetName()) -- reset the starting positions block.endPoint = block.titlebg block.attachmentHeight = 0 block.currentLine = 0 local displayObjectiveHeader = false block.attachmentHeight = 0 local text, attachment, template if info.description and #info.description >= 1 then print(' |cFF00FFFF header line:|r', info.description) text = info.description handler:AddLine(block, text, nil) end if (info.isComplete or info.numObjectives == 0) and info.completionText then print(' overriding line #1 for completion text:', info.completionText) text = info.completionText handler:AddLine(block, text, nil, 'completed') else if info.objectives then for i, data in ipairs(info.objectives) do local line = handler:GetLine(block) displayObjectiveHeader = true line.height = 0 text, attachment, template = handler:UpdateLine(block, line, data) print(' |cFF88FF00#', i, data.type, text, attachment) handler:AddLine(block, text, attachment, template) end end end if block.currentLine < block.numLines then print(' - cull', block.currentLine, block.numLines) for i = block.currentLine + 1, block.numLines do print(' - hide |cFFFF0088'..i..'|r', block.lines[i]) block.lines[i]:ClearAllPoints() block.lines[i]:Hide() end end if block.currentLine > 0 then block.attachmentHeight = block.attachmentHeight + textSpacing print(' |cFF00FF00attachment:', block.attachmentHeight) end return block_schema 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 Default.UpdateLine = function(handler, block, line, data) if line.finished then line.progress = 2 elseif line.quantity > 0 then line.progress = 1 else line.progress = 0 end return data.text, line.widget, 'normal' end ---------- --- Top level methods --- Queue any active item buttons for update for that frame local iprint = B.print('ItemButton') Module.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= Module.Quest.Info[questID] print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) local block = Module.Quest.QuestBlock[questID] if block then -- Dispatch the probe if IsQuestWatched(info.logIndex) then itemButton.previousItem = previousItem print(' |cFFFFFF00probing', block:GetName()) block:SetScript('OnUpdate', function() if block:GetBottom() and not InCombatLockdown() then print(' '..block:GetName()..' |cFF00FF00probe hit!') Module.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 Module.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 Module.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 Module.UpdateItemButtonCooldown = function(button) end Default.Select = function(handler, block) Module:Update(handler.watchReasonModule) end Default.Open = function(handler, block) Module:Update(handler.watchReasonModule) end Default.Remove = function(handler, block) Module:Update(handler.watchReasonModule) end Default.Report = function(handler, block) print('Stats:', handler.numWatched,'items tracked,', handler.numBlocks,'blocks assigned.') end Default.OnMouseUp = function(self, button) print(self.handler.name, self.mainStyle, self.subStyle) if button == 'LeftButton' then if IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow() then self.Link(self.handler, self) elseif IsModifiedClick("QUESTWATCHTOGGLE") then self.Remove(self.handler, self) else self.Select(self.handler, self) end elseif button == 'RightButton' then self.Open(self.handler, self) end self.initialButton = nil self.modChatLink = nil self.modQuestWatch = nil Module:Update(self.handler.updateReasonModule) print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r') end Default.OnMouseDown = function(self, button) print(self.info.title) end