view ObjectiveTracker/TrackerBlock.lua @ 42:c73051785f19

Added tag r42-release for changeset 7a65ed86e4dd
author Nenue
date Mon, 25 Apr 2016 03:32:34 -0400
parents 7a65ed86e4dd
children
line wrap: on
line source
--- ${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)
    fprint(self:GetName(), '|cFF00FF00HIDE|r', debugstack(1,3,1))
    if(self.DebugTab:IsShown()) then
      self.DebugTab:Hide()
    end
    self.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished)
    self.isAnimating = nil
  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