Mercurial > wow > buffalo2
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