diff ObjectiveTracker/TrackerBlock.lua @ 40:03ed70f846de

- move block accessors into a new file - define a tMove function for reconciling the free/used tables as needed - when retrieving an old block frame, confirm ID still matches; resolves multiple watch items on one block - stop any animations when a block is freed; resolves stuck flare graphics
author Nenue
date Sun, 24 Apr 2016 14:15:25 -0400
parents
children 7a65ed86e4dd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ObjectiveTracker/TrackerBlock.lua	Sun Apr 24 14:15:25 2016 -0400
@@ -0,0 +1,226 @@
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 4/24/2016 11:30 AM
+--- These functions deal with propagating and managing block/line templates
+local B = select(2,...).frame
+local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
+local _G, ipairs, max, tostring = _G, ipairs, max, tostring
+local tinsert, tremove, tContains = table.insert, table.remove, tContains
+local Default = T.DefaultHandler
+local CreateFrame = CreateFrame
+local print = B.print('Layout')
+local bprint = B.print('Block')
+local lprint = B.print('Layout')
+local fprint = B.print('Frame')
+local used, free
+
+local blockFadeOut_OnPlay = function(self)
+  fprint(self:GetName(), '|cFF00FF00PLAY|r', debugstack(1,3,1))
+end
+local blockFadeOut_OnFinished = function(self)
+  fprint(self:GetName(), '|cFF00FF00FINISHED|r', debugstack(1,3, 1))
+end
+
+local tMove = function(source, dest, frame)
+  -- if it's already in the stack, sanity check source stack
+  local removed
+  if tContains(dest, frame) then
+    for i, entry in ipairs(source) do
+      if entry == frame then
+        removed = i
+        tremove(source, i)
+        break
+      end
+    end
+    -- still need to resolve position
+    for i, entry in ipairs(dest) do
+      if entry == frame then
+          bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. i..']')
+          return i
+      end
+    end
+  else
+  -- if it's not, then pull from source stack
+    for i, entry in ipairs(source) do
+      if entry == frame then
+        removed = i
+        tremove(source, i)
+        break
+      end
+    end
+    tinsert(dest, frame)
+    bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. #dest..']')
+    return #dest
+  end
+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 = ''
+    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, index)
+  local print = bprint
+  print('|cFF0088FF'..handler.name..':GetBlock', index)
+  local block = handler.InfoBlock[index]
+  local used = handler.usedBlocks
+  local free = handler.freeBlocks
+
+  if block then
+    print(block.info.id, index)
+  end
+
+  -- if the frame entry is still good, sort heaps
+  if block and block.info.id == index then
+    block.posIndex = tMove(free, used, block)
+    print('  |cFFFFFF00using '..handler.name..'|r.|cFF00FFBBusedBlocks['..tostring(block.posIndex)..'] ('.. block:GetName()..', "'..tostring(block.info.title)..'")')
+  else
+    local source = 'cache'
+    if #handler.freeBlocks >= 1 then
+      block = tremove(handler.freeBlocks)
+      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.schema = ''
+      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
+
+      block.blockFadeOut:SetScript('OnPlay', blockFadeOut_OnPlay)
+
+      source = 'new'
+    end
+    handler.InfoBlock[index] = block
+    block.posIndex = tMove(free, used, block)
+    print('  |cFF00FF00('..source..')|r |cFF0088FF'..handler.name..'|r.|cFF00FFBBusedBlocks['..block.posIndex..'] =|r', block:GetName())
+  end
+  block.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished)
+  block:SetScript('OnHide', function(self)
+    self.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished)
+  end)
+  print('  used/free: |cFFFFFF00' .. #handler.usedBlocks .. '|r/|cFF00FFFF'..#handler.freeBlocks ..'|r')
+  return block
+end
+
+--- begins a blockFadeOut animation and fires FreeBlock when that's done
+Default.ClearBlock = function(handler, block)
+  if block.isAnimating then
+    return
+  end
+
+  block.isAnimating = true
+  block.blockFadeOut:SetScript('OnFinished', nil)
+  block.blockFadeOut:SetScript('OnFinished', function(self)
+    fprint(self:GetName(), '|cFFFFFF00FINISHED|r', debugstack())
+    handler:FreeBlock(block)
+    self:SetScript('OnFinished', blockFadeOut_OnFinished)
+    block.isAnimating = nil
+  end)
+  block.blockFadeOut:Play()
+end
+
+--- remove a block from visible existence; not called directly
+Default.FreeBlock = function(handler, block)
+  bprint('|cFFFF4400FreeBlock|r', block:GetName())
+  local used = handler.usedBlocks
+  local free = handler.freeBlocks
+  tMove(used, free, block)
+
+  bprint('  |cFFFF4444used/free:|r |cFFFFFF00' .. #used .. '|r/|cFF00FFFF'..#free ..'|r')
+
+  block:Hide()
+  local animations = {block:GetAnimationGroups() }
+  for i, animGroup in ipairs(animations) do
+    bprint('  animGroup', i,  animGroup:GetName())
+    animGroup:Stop()
+  end
+end
+
+
+
+--- Get a usable widget for the given achievement criteria set.
+-- Returns a frame object with dimensioning parameters needed to size the receiving tracker block
+local wr = T.WidgetRegistry
+T.GetWidget = function(data, objectiveType, objectiveKey)
+  local print = B.print('ObjectiveWidgets')
+  local widgetType = objectiveType
+  local widget
+  local isNew
+  if wr[widgetType] and wr[widgetType].used[objectiveKey] then
+    widget = wr[widgetType].used[objectiveKey]
+    print('|cFF00FF00Updating ('..objectiveKey..')', widget)
+  elseif not wr[widgetType] or #wr[widgetType].free == 0 then
+    -- creating a new frame
+    isNew = true
+    widget = CreateFrame(widgetType, 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType)
+    print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn)
+    T.UpdateSchema(widgetType, data.schema or 'default')
+  else
+    -- recycling for a different criteria set
+    isNew = true
+    widget = tremove(wr[widgetType].free)
+    print('|cFFFFFF00Acquiring released widget', widget:GetName())
+  end
+
+  for k,v in pairs(data) do
+    if not widget[k] then
+      widget[k] = v
+      tprint('widget', widget:GetName(), k, v)
+    end
+  end
+
+  wr[widgetType].used[objectiveKey] = widget
+  widget.objective = data
+  widget.key = objectiveKey
+  T.InitializeWidget(widget, isNew)
+  return widget
+end
\ No newline at end of file