diff 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 diff
--- a/ObjectiveTracker/Frame.lua	Wed Apr 13 21:53:24 2016 -0400
+++ b/ObjectiveTracker/Frame.lua	Thu Apr 14 17:11:13 2016 -0400
@@ -4,29 +4,26 @@
 -- @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 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 = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs
+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
---------------------------------------------------------------------
---- Global frame layout
---------------------------------------------------------------------
 
 --- Upvalues
 local Wrapper = _G.VeneerObjectiveWrapper
 local Scroller = Wrapper.scrollArea
 local Scroll = _G.VeneerObjectiveScroll
-local orderedHandlers = T.orderedHandlers
-local orderedNames = T.orderedNames
+local orderedHandlers = Module.orderedHandlers
+local orderedNames = Module.orderedNames
 
 --- Temp values set during updates
 local wrapperWidth, wrapperHeight
@@ -36,7 +33,7 @@
 --- todo: source these from config
 local itemButtonSize, itemButtonSpacing =  36, 1
 
-local headerHeight, headerColor, headerSpacing = 16, {1,1,1,1}, 2
+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'
 
@@ -55,6 +52,10 @@
 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 }
@@ -64,135 +65,101 @@
 local tprint = B.print('Tracker')
 local lprint = B.print('Line')
 
-local currentPosition, anchorFrame, anchorPoint
-
---- Positioning and stuff
-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
-
-T.AddBlock = function(self, block)
+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:SetPoint('TOPLEFT', self.currentAnchor, 'BOTTOMLEFT', 0, 0)
+
+  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, info.blockIndex)
+  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)
-T.AddTag = function (block, tagName, tagPoint, tagAnchor, tagRelative)
+Default.AddTag = function (handler, block, tagInfo, 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()
+
+  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.
-T.AddLine = function(block, line)
+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:SetHeight(line.height)
   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.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,
+  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
-T.GetLine = function(handler, block, lineIndex)
+Default.GetLine = function(handler, block, lineIndex)
   local print = lprint
   local blockIndex = block.index
-  if not block.lines then
-    block.lines = {}
+  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
-  local lines = block.lines
+
+  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')
@@ -220,7 +187,7 @@
 
 
 --- Creates or retrieves a complete block frame object
-T.GetBlock = function(handler, blockIndex)
+Default.GetBlock = function(handler, blockIndex)
   local print = bprint
   local block = handler.usedBlocks[blockIndex]
 
@@ -229,19 +196,20 @@
       block = handler.freeBlocks[#handler.freeBlocks]
       handler.freeBlocks[#handler.freeBlocks] = nil
     else
-      block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock')
+      block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock')
 
-
-
-      local c = T.Conf.Wrapper
+      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(T.colors.default.titlebg))
+      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)
 
@@ -252,9 +220,9 @@
       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.statusbg:SetGradientAlpha(unpack(Module.colors.default.textbg))
 
-      block.SelectionOverlay:SetGradientAlpha(unpack(T.colors.default.selectionbg))
+      block.SelectionOverlay:SetGradientAlpha(unpack(Module.colors.default.selectionbg))
       block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0)
       block.SelectionOverlay:SetPoint('BOTTOMRIGHT')
 
@@ -286,10 +254,131 @@
   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.Update = function (self, reason, ...)
+Default.UpdateTracker = function (handler, reason, id, isNew)
   local print = tprint
-  local tracker = self.frame
+  local tracker = handler.frame
   local blockIndex = 0
   tracker.previousHeight = tracker.height
   tracker.height = 0
@@ -298,37 +387,37 @@
   tracker.titlebg:SetHeight(headerHeight)
   tracker.title:SetTextColor(unpack(headerColor))
 
-  self.currentAnchor = tracker.titlebg
-  self.numWatched = self:GetNumWatched()
-  self.actualBlocks = 0
-  for watchIndex = 1, 25 do
-    blockIndex = blockIndex + 1
-    if watchIndex <= self.numWatched then
-      local info = self:GetInfo(watchIndex)
-      if info then
-        local currentBlock = self:UpdateBlock(blockIndex, info)
-        T.AddBlock(self, currentBlock)
-      else
-        print('    |cFFFF0000bad GetInfo data for #'..watchIndex)
-      end
-    elseif watchIndex <= self.actualBlocks 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
+  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 self.actualBlocks >= 1 then
+
+  if handler.currentBlock >= 1 then
     tracker.height = tracker.height + headerHeight
     tracker:Show()
 
@@ -353,14 +442,24 @@
 -- @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)
+Default.UpdateBlock = function (handler, blockIndex, id, added)
   local print = bprint
-  print('  Read list item |cFF00FFFF'..blockIndex..'|r')
-  if not blockIndex or not info then
+  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 = T.GetBlock(handler, blockIndex)
+  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'
@@ -371,28 +470,22 @@
   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)
 
+  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
 
-  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..')')
@@ -408,7 +501,7 @@
 
   if info.specialItem and not info.itemButton then
     print('    - |cFF00FFFFgenerating item button for info set')
-    info.itemButton = T.SetItemButton(block, info)
+    info.itemButton = Module.SetItemButton(block, info)
   else
     --info.itemButton = nil
   end
@@ -437,9 +530,9 @@
   --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)
+  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
@@ -453,6 +546,9 @@
   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
@@ -463,97 +559,47 @@
 
   --- 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
 
+  local text, attachment
   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)
+    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)
-    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)
+    text = info.completionText
+    Module.AddLine(block, text, nil)
   else
     if info.objectives then
       for i, data in ipairs(info.objectives) do
-        print('     |cFF88FF00#', i, data.type, data.text)
+        local line = handler:GetLine(block)
         displayObjectiveHeader = true
         line.height = 0
-        handler:UpdateLine(block, line, data)
+        text, attachment = handler:UpdateLine(block, line, data)
+        print('     |cFF88FF00#', i, data.type, text)
+        handler:AddLine(block, text, attachment)
 
-        -- 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
+  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 lineIndex > 0 then
+  if block.currentLine > 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
@@ -585,14 +631,14 @@
   else
     line.progress = 0
   end
-  return line
+  return line.displayText, line.widget
 end
 ----------
 --- Top level methods
 
 --- Queue any active item buttons for update for that frame
 local iprint = B.print('ItemButton')
-T.UpdateActionButtons = function(updateReason)
+Module.UpdateActionButtons = function(updateReason)
   local print = iprint
   Scroller.snap_upper = 0
   Scroller.snap_lower = 0
@@ -603,10 +649,10 @@
 
   local previousItem
   for questID, itemButton in pairs(Quest.itemButtons) do
-    local info= T.Quest.Info[questID]
+    local info= Module.Quest.Info[questID]
 
     print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName())
-    local block = T.Quest.QuestBlock[questID]
+    local block = Module.Quest.QuestBlock[questID]
     if block then
         -- Dispatch the probe
       if IsQuestWatched(info.questLogIndex) then
@@ -615,7 +661,7 @@
         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
+            Module.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope
             block:SetScript('OnUpdate', nil)
 
           end
@@ -636,13 +682,13 @@
   end
 end
 
-T.UpdateBlockAction = function (block, itemButton)
+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 T.UpdateActionButtons()
+    return Module.UpdateActionButtons()
   end
 
   local previousItem = itemButton.previousItem
@@ -691,18 +737,18 @@
   itemButton:Show()
 end
 
-T.UpdateItemButtonCooldown = function(button)
+Module.UpdateItemButtonCooldown = function(button)
 
 end
 
 Default.Select = function(handler, block)
-  T:Update(handler.watchReasonModule)
+  Module:Update(handler.watchReasonModule)
 end
 Default.Open = function(handler, block)
-  T:Update(handler.watchReasonModule)
+  Module:Update(handler.watchReasonModule)
 end
 Default.Remove = function(handler, block)
-  T:Update(handler.watchReasonModule)
+  Module:Update(handler.watchReasonModule)
 end
 Default.Report = function(handler, block)
   print('Stats:', handler.numWatched,'items tracked,', handler.numBlocks,'blocks assigned.')
@@ -724,7 +770,7 @@
   self.initialButton = nil
   self.modChatLink = nil
   self.modQuestWatch = nil
-  T:Update(self.handler.updateReasonModule)
+  Module:Update(self.handler.updateReasonModule)
   print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r')
 end
 Default.OnMouseDown = function(self, button)