Mercurial > wow > buffalo2
view ObjectiveTracker/Frame.lua @ 30:7583684becf4
- implement procedural block contents generation
- redo anchor calculations to allow for transitional animation
- attempt to sort out event handling quirks related to autopopup quest completion and turn-in
- revise the data structures created by the different GetInfo's
- start on trimming out redundant variables
author | Nenue |
---|---|
date | Thu, 14 Apr 2016 17:11:13 -0400 |
parents | adcd7c328d07 |
children | 48b3e3959a0a |
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 = 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 = 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 unitLevel = 1 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON local debug = false --- Upvalues local Wrapper = _G.VeneerObjectiveWrapper local Scroller = Wrapper.scrollArea local Scroll = _G.VeneerObjectiveScroll local orderedHandlers = Module.orderedHandlers local orderedNames = Module.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,.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, .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 lineColors = { text = {.5,.75,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 = 32 local oprint = B.print('Objectives') local bprint = B.print('Block') local tprint = B.print('Tracker') local lprint = B.print('Line') Default.AddBlock = function(self, block, blockIndex) local blockIndex = blockIndex or (self.currentBlock + 1) local print = bprint local tracker = self.frame local info = block.info 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.numBlocks = max(self.numBlocks, blockIndex) 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) 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:Show() local r, g, b, a = 1, 1, 1, 1 if lineColors[template] then r, g, b = unpack(lineColors[template]) end line.status:SetText(text) line.height = floor(line.status:GetStringHeight()+.5) + textSpacing line:SetHeight(line.height) line.status:SetTextColor(r, g, b, a) -- For progressbar and timer lines, status text may be used as the title heading if attachment then local widgetPosition = 0 attachment:SetPoint('TOP', line, 'TOP', 0, -block.attachmentHeight) attachment:Show() if text and #text >= 1 then widgetPosition = line.status:GetHeight() + textSpacing line.status:SetText(text) line.height = floor(line.status:GetStringHeight()+.5) + textSpacing + attachment.height print(' - progressbar has text, adjust') end else print(' |cFFFF0088no attachments') end block.endIndex = line.index 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 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('fetching the "next" line:', lineIndex) else print('fetching explicit offset:', lineIndex) end block.numLines = max(block.numLines, lineIndex) print('|cFF00FFFFnumLines:|r', block.numLines, '|cFF00FFFFcurrentLine:|r', block.currentLine) 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 Default.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, handler.frame, 'VeneerTrackerBlock') local c = Module.Conf.Wrapper block.index = blockIndex block.lines = {} block.numLines = 0 block.currentLine = 0 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(Module.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(Module.colors.default.textbg)) block.SelectionOverlay:SetGradientAlpha(unpack(Module.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 local currentPosition, anchorFrame, anchorPoint --- Positioning and stuff local tick = 0 local maxReason = 0 function Module:Update (reason, ...) tick = tick + 1 -- is this the first time updating? if maxReason == 0 then reason = OBJECTIVE_TRACKER_UPDATE_ALL elseif not reason then reason = OBJECTIVE_TRACKER_UPDATE_REASON end local print = tprint 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(Module.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:UpdateTracker(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.destinationOffset = -wrapperHeight if 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 frame.SlideIn:SetScript('OnFinished', function() print(' |cFF00BBFFsliding finished:', delta, 'pixels covered') 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) frame:SetParent(Scroll) frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) end frame:Show() anchorFrame = handler.frame anchorPoint = 'BOTTOM' print('current frame height:', frame.height) wrapperHeight = wrapperHeight + frame.height print('|cFFFF0088total height:', wrapperHeight) else 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) 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() 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 for i = handler.currentBlock+1, handler.numBlocks do local used = handler.usedBlocks local free = handler.freeBlocks print('clean up dead quest block') if used[i] then used[i]:Hide() used[i]:ClearAllPoints() free[#free+1]= used[blockIndex] used[i] = nil 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 print(' Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..blockIndex..'|r') 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 local frame = handler.frame local block = handler:GetBlock(blockIndex) block.questID = info.questID if id == info.questID then --block.questFadeIn:Play() end 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 handler:UpdateObjectives(block) 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..')') --block.titlebg:SetHeight(block.title:GetHeight() + Module.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 = Module.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 = 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) 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) local print = lprint local info = block.info print(' |cFF00FF00default objectives routine', block:GetName()) block.endPoint = block.titlebg block.attachmentHeight = 0 block.currentLine = 0 -- 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. block.attachmentHeight = 0 local text, attachment 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 Module.AddLine(block, text, nil) 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 = handler:UpdateLine(block, line, data) print(' |cFF88FF00#', i, data.type, text) handler:AddLine(block, text, attachment) end end end for i = block.currentLine + 1, block.numLines do print(i, block.numLines) print(' - hide |cFFFF0088'..i..'|r', block.lines[i]) block.lines[i]:ClearAllPoints() block.lines[i]:Hide() end if block.currentLine > 0 then block.attachmentHeight = block.attachmentHeight + textSpacing * 2 print(' |cFF00FF00attachment:', block.attachmentHeight) 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 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.displayText, line.widget 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.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!') 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