Mercurial > wow > buffalo2
view ObjectiveTracker/Frame.lua @ 36:a487841050be
- attempts to solve the mystery of disappearing objectives
author | Nenue |
---|---|
date | Sun, 17 Apr 2016 13:00:31 -0400 |
parents | 69d03f8e293e |
children | e84d645c8ab8 |
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, 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 = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow local print = B.print('Layout') local oprint = B.print('Objectives') local bprint = B.print('Block') local tprint = B.print('Tracker') local lprint = B.print('Layout') 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 = T.orderedHandlers local orderedNames = T.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 local blockPosition --- schema swapper T.UpdateSchema = function(layer, newSchema) if not (T.Conf.Schema[layer] and T.Conf.Schema[layer][newSchema]) then return elseif schemaName[layer] == newSchema then return end lastSchema[layer] = schemaName[layer] schemaName[layer] = newSchema local c = T.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 -- todo: figure out why objectives go invisible local anchorPoint, anchorFrame local abs, GetTime = math.abs, GetTime Default.AddTracker = function(handler, frame, index) if index == 1 then print('|cFF00FF00### beginning wrapper layout -----------------') anchorPoint, anchorFrame = 'TOP', Scroll wrapperHeight = 0 end frame.destinationOffset = -wrapperHeight print(frame.destinationOffset, frame.previousOffset) if handler.initialized and (abs(frame.previousOffset - frame.destinationOffset) > 0.9) and frame:IsVisible() then if frame.wasEmpty then frame.previousOffset = -Wrapper:GetHeight() end local postFrame, postPoint = anchorFrame, anchorPoint local delta = frame.destinationOffset - frame.previousOffset local _, _, _, _, offset = frame:GetPoint(1) print(' |cFF00FFBBpushing', frame:GetName(), 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(' |cFF00BBFF'..frame:GetName(), 'moved', delta, 'over duration of ', 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:ClearAllPoints() frame:SetParent(Scroll) frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) frame.previousOffset = frame.destinationOffset handler.initialized = true end frame.title:SetFont(headerFont, headerSize, headerOutline) frame.titlebg:SetHeight(headerHeight) frame.title:SetTextColor(unpack(headerColor)) if frame.height ~= frame.previousHeight then frame:SetHeight(frame.height) end frame:Show() if frame.wasEmpty then frame.headerFade:Play() frame.wasEmpty = nil end wrapperHeight = wrapperHeight + frame.height anchorFrame = handler.frame anchorPoint = 'BOTTOM' 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 block.index = blockIndex if blockSchema ~= block.schema then print('new schema detected, applicating...') block.schema = blockSchema block:SetWidth(T.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 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', self.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) 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 --- Handler vars if blockIndex == 1 then tracker.previousHeight = tracker.height tracker.height = headerHeight blockPosition = -headerHeight tprint(' |cFF88FF00AddBlock:|r new layout: headerHeight =', headerHeight, 'previousHeight =', tracker.previousHeight) else blockPosition = blockPosition tprint(' |cFF8888FFAddBlock:|r advancing: height =', tracker.height) end self.currentBlock = blockIndex self.currentAnchor = block block:SetPoint('TOPLEFT', self.frame, 'TOPLEFT', 0, blockPosition) block:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) self.numBlocks = self.numBlocks + 1 print(' |cFFFFFF00'..tracker.height..'|r', '|cFF00FF00'..block:GetName()..'|r', block.height, tracker.height) tracker.height = tracker.height + block.height blockPosition = blockPosition - block.height 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 template then if line.schema ~= template then print(' |cFF00FF00change schema', template) T.UpdateSchema('line', template) line.status:SetSpacing(textSpacing) line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) line.status:SetPoint('RIGHT', line, 'RIGHT',0, 0) line.status:SetTextColor(unpack(textColor)) line.schema = template else print(' |cFFFFFF00keep schema', line.schema) end end line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) line:Show() tprint(' |cFF0088FFAddLine|r (|cFF00FFFF'..tostring(line.schema)..'|r):', line:GetName()) -- 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 local debug_points = '' for i = 1, line:GetNumPoints() do local point, parent, anchor = line:GetPoint(i) debug_points = debug_points .. tostring(parent:GetName()) .. ', ' .. anchor .. ' ' end print(' |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, "|cFF0088FFpoint:|r", debug_points, "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) block.currentLine = lineIndex block.endPoint = line -- 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 line.schema = 'default' 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('|cFF0088FFgetting a block for logID', logIndex ..',', #handler.usedBlocks,'used', #handler.freeBlocks, 'free') local block = handler.LogBlock[logIndex] local used = handler.usedBlocks if not block then if #handler.freeBlocks >= 1 then block = tremove(handler.freeBlocks) tinsert(handler.usedBlocks, block) block.posIndex = #handler.usedBlocks print(' |cFF00FF00 assigning from free heap', block:GetName()) else local blockIndex = (#handler.usedBlocks + #handler.freeBlocks) + 1 block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock') --block:SetParent() block.lines = {} block.numLines = 0 block.currentLine = 0 block.attachmentHeight = 0 block.offset = 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 print(' |cFF00FFBBcreating new|r', block:GetName()) end handler.LogBlock[logIndex] = block tinsert(handler.usedBlocks, block) block.posIndex = #handler.usedBlocks else print(' |cFFFFFF00use existing block|r', block:GetName()) local found = false for i, entry in ipairs(used) do if entry == block then found = true break end end if not found then tinsert(used, block) block.posIndex = #used end end return block end ---------- --- Top level methods T.UpdateBlockAction = function (block, itemButton) local print = bprint 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 function T:FinishWrapper () if wrapperHeight > Wrapper.previousHeight then Wrapper:SetHeight(wrapperHeight) Scroller:SetHeight(wrapperHeight*3) Scroll:SetHeight(wrapperHeight) Wrapper.previousHeight = wrapperHeight Wrapper.destinationHeight = wrapperHeight end Scroller:SetVerticalScroll(B.Conf.ObjectiveScroll or 0) print('|cFF00FF00### end of wrapper layout', Wrapper:GetSize()) print(' |cFF00FF00Scroller:', Scroller:GetSize()) print(' |cFF00FF00Scroll:', Scroll:GetSize()) for i = 1, Wrapper:GetNumPoints() do print('|cFF00FF00 ', Wrapper:GetPoint(i)) end for i = 1, Scroller:GetNumPoints() do print('|cFF00FF00 ', Scroller:GetPoint(i)) end for i = 1, Scroll:GetNumPoints() do print('|cFF00FF00 ', Scroll:GetPoint(i)) end Wrapper:Show() Scroller:Show() Scroll:Show() end