annotate ObjectiveTracker/TrackerBlock.lua @ 41:7a65ed86e4dd r42-release

- prevent animation Play from firing more than once before block:Hide is called
author Nenue
date Sun, 24 Apr 2016 14:28:49 -0400
parents 03ed70f846de
children
rev   line source
Nenue@40 1 --- ${PACKAGE_NAME}
Nenue@40 2 -- @file-author@
Nenue@40 3 -- @project-revision@ @project-hash@
Nenue@40 4 -- @file-revision@ @file-hash@
Nenue@40 5 -- Created: 4/24/2016 11:30 AM
Nenue@40 6 --- These functions deal with propagating and managing block/line templates
Nenue@40 7 local B = select(2,...).frame
Nenue@40 8 local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
Nenue@40 9 local _G, ipairs, max, tostring = _G, ipairs, max, tostring
Nenue@40 10 local tinsert, tremove, tContains = table.insert, table.remove, tContains
Nenue@40 11 local Default = T.DefaultHandler
Nenue@40 12 local CreateFrame = CreateFrame
Nenue@40 13 local print = B.print('Layout')
Nenue@40 14 local bprint = B.print('Block')
Nenue@40 15 local lprint = B.print('Layout')
Nenue@40 16 local fprint = B.print('Frame')
Nenue@40 17 local used, free
Nenue@40 18
Nenue@40 19 local blockFadeOut_OnPlay = function(self)
Nenue@40 20 fprint(self:GetName(), '|cFF00FF00PLAY|r', debugstack(1,3,1))
Nenue@40 21 end
Nenue@40 22 local blockFadeOut_OnFinished = function(self)
Nenue@40 23 fprint(self:GetName(), '|cFF00FF00FINISHED|r', debugstack(1,3, 1))
Nenue@40 24 end
Nenue@40 25
Nenue@40 26 local tMove = function(source, dest, frame)
Nenue@40 27 -- if it's already in the stack, sanity check source stack
Nenue@40 28 local removed
Nenue@40 29 if tContains(dest, frame) then
Nenue@40 30 for i, entry in ipairs(source) do
Nenue@40 31 if entry == frame then
Nenue@40 32 removed = i
Nenue@40 33 tremove(source, i)
Nenue@40 34 break
Nenue@40 35 end
Nenue@40 36 end
Nenue@40 37 -- still need to resolve position
Nenue@40 38 for i, entry in ipairs(dest) do
Nenue@40 39 if entry == frame then
Nenue@40 40 bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. i..']')
Nenue@40 41 return i
Nenue@40 42 end
Nenue@40 43 end
Nenue@40 44 else
Nenue@40 45 -- if it's not, then pull from source stack
Nenue@40 46 for i, entry in ipairs(source) do
Nenue@40 47 if entry == frame then
Nenue@40 48 removed = i
Nenue@40 49 tremove(source, i)
Nenue@40 50 break
Nenue@40 51 end
Nenue@40 52 end
Nenue@40 53 tinsert(dest, frame)
Nenue@40 54 bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. #dest..']')
Nenue@40 55 return #dest
Nenue@40 56 end
Nenue@40 57 end
Nenue@40 58
Nenue@40 59
Nenue@40 60 --- Creates or retrieves a complete line data object
Nenue@40 61 Default.GetLine = function(handler, block, lineIndex)
Nenue@40 62 local print = lprint
Nenue@40 63 local blockIndex = block.index
Nenue@40 64 local lines = block.lines
Nenue@40 65 if not lineIndex then
Nenue@40 66 lineIndex = block.currentLine + 1
Nenue@40 67 print(' |cFFFFFF00generating a frame')
Nenue@40 68 end
Nenue@40 69
Nenue@40 70 block.numLines = max(block.numLines, lineIndex)
Nenue@40 71
Nenue@40 72 if not lines[lineIndex] then
Nenue@40 73 print(' |cFF00FF88created line #'..lineIndex..' from for '..handler.name..' block #'..blockIndex)
Nenue@40 74 lines[lineIndex] = CreateFrame('Frame', 'Vn'..handler.name .. blockIndex..'ObjectiveLine'..lineIndex, block, 'VeneerTrackerObjective')
Nenue@40 75 local line = lines[lineIndex]
Nenue@40 76 line.index = lineIndex
Nenue@40 77 line.height = 0
Nenue@40 78 line.schema = ''
Nenue@40 79 B.SetConfigLayers(line)
Nenue@40 80
Nenue@40 81 if debug then
Nenue@40 82 for _, region in ipairs(lines[lineIndex].debug) do
Nenue@40 83 region:Show()
Nenue@40 84 end
Nenue@40 85 end
Nenue@40 86
Nenue@40 87 end
Nenue@40 88 return lines[lineIndex]
Nenue@40 89 end
Nenue@40 90
Nenue@40 91
Nenue@40 92
Nenue@40 93 --- Creates or retrieves a complete block frame object
Nenue@40 94 --- todo: make it use data index to avoid re-coloring every block
Nenue@40 95 Default.GetBlock = function(handler, index)
Nenue@40 96 local print = bprint
Nenue@40 97 print('|cFF0088FF'..handler.name..':GetBlock', index)
Nenue@40 98 local block = handler.InfoBlock[index]
Nenue@40 99 local used = handler.usedBlocks
Nenue@40 100 local free = handler.freeBlocks
Nenue@40 101
Nenue@40 102 if block then
Nenue@40 103 print(block.info.id, index)
Nenue@40 104 end
Nenue@40 105
Nenue@40 106 -- if the frame entry is still good, sort heaps
Nenue@40 107 if block and block.info.id == index then
Nenue@40 108 block.posIndex = tMove(free, used, block)
Nenue@40 109 print(' |cFFFFFF00using '..handler.name..'|r.|cFF00FFBBusedBlocks['..tostring(block.posIndex)..'] ('.. block:GetName()..', "'..tostring(block.info.title)..'")')
Nenue@40 110 else
Nenue@40 111 local source = 'cache'
Nenue@40 112 if #handler.freeBlocks >= 1 then
Nenue@40 113 block = tremove(handler.freeBlocks)
Nenue@40 114 print(' |cFF00FF00 assigning from free heap', block:GetName())
Nenue@40 115 else
Nenue@40 116
Nenue@40 117 local blockIndex = (#handler.usedBlocks + #handler.freeBlocks) + 1
Nenue@40 118 block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock')
Nenue@40 119 --block:SetParent()
Nenue@40 120 block.schema = ''
Nenue@40 121 block.lines = {}
Nenue@40 122 block.numLines = 0
Nenue@40 123 block.currentLine = 0
Nenue@40 124 block.attachmentHeight = 0
Nenue@40 125 block.offset = 0
Nenue@40 126 B.SetConfigLayers(block)
Nenue@40 127 --- methods for event handlers
Nenue@40 128
Nenue@40 129 block.Select = handler.Select
Nenue@40 130 block.Open = handler.Open
Nenue@40 131 block.Remove = handler.Remove
Nenue@40 132 block.Link = handler.Link
Nenue@40 133 block.clickZone:SetScript('OnMouseUp', function(self, ...) handler.OnMouseUp(block, ...) end)
Nenue@40 134 block.clickZone:SetScript('OnMouseDown', function(self, ...) handler.OnMouseDown(block, ...) end)
Nenue@40 135 block:ClearAllPoints()
Nenue@40 136 block.index = blockIndex
Nenue@40 137
Nenue@40 138 block.blockFadeOut:SetScript('OnPlay', blockFadeOut_OnPlay)
Nenue@40 139
Nenue@40 140 source = 'new'
Nenue@40 141 end
Nenue@40 142 handler.InfoBlock[index] = block
Nenue@40 143 block.posIndex = tMove(free, used, block)
Nenue@40 144 print(' |cFF00FF00('..source..')|r |cFF0088FF'..handler.name..'|r.|cFF00FFBBusedBlocks['..block.posIndex..'] =|r', block:GetName())
Nenue@40 145 end
Nenue@40 146 block.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished)
Nenue@40 147 block:SetScript('OnHide', function(self)
Nenue@41 148 fprint(self:GetName(), '|cFF00FF00HIDE|r', debugstack(1,3,1))
Nenue@41 149 if(self.DebugTab:IsShown()) then
Nenue@41 150 self.DebugTab:Hide()
Nenue@41 151 end
Nenue@40 152 self.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished)
Nenue@41 153 self.isAnimating = nil
Nenue@40 154 end)
Nenue@40 155 print(' used/free: |cFFFFFF00' .. #handler.usedBlocks .. '|r/|cFF00FFFF'..#handler.freeBlocks ..'|r')
Nenue@40 156 return block
Nenue@40 157 end
Nenue@40 158
Nenue@40 159 --- begins a blockFadeOut animation and fires FreeBlock when that's done
Nenue@40 160 Default.ClearBlock = function(handler, block)
Nenue@40 161 if block.isAnimating then
Nenue@40 162 return
Nenue@40 163 end
Nenue@40 164
Nenue@40 165 block.isAnimating = true
Nenue@40 166 block.blockFadeOut:SetScript('OnFinished', nil)
Nenue@40 167 block.blockFadeOut:SetScript('OnFinished', function(self)
Nenue@40 168 fprint(self:GetName(), '|cFFFFFF00FINISHED|r', debugstack())
Nenue@40 169 handler:FreeBlock(block)
Nenue@40 170 self:SetScript('OnFinished', blockFadeOut_OnFinished)
Nenue@40 171 block.isAnimating = nil
Nenue@40 172 end)
Nenue@40 173 block.blockFadeOut:Play()
Nenue@40 174 end
Nenue@40 175
Nenue@40 176 --- remove a block from visible existence; not called directly
Nenue@40 177 Default.FreeBlock = function(handler, block)
Nenue@40 178 bprint('|cFFFF4400FreeBlock|r', block:GetName())
Nenue@40 179 local used = handler.usedBlocks
Nenue@40 180 local free = handler.freeBlocks
Nenue@40 181 tMove(used, free, block)
Nenue@40 182
Nenue@40 183 bprint(' |cFFFF4444used/free:|r |cFFFFFF00' .. #used .. '|r/|cFF00FFFF'..#free ..'|r')
Nenue@40 184
Nenue@40 185 block:Hide()
Nenue@40 186 local animations = {block:GetAnimationGroups() }
Nenue@40 187 for i, animGroup in ipairs(animations) do
Nenue@40 188 bprint(' animGroup', i, animGroup:GetName())
Nenue@40 189 animGroup:Stop()
Nenue@40 190 end
Nenue@40 191 end
Nenue@40 192
Nenue@40 193
Nenue@40 194
Nenue@40 195 --- Get a usable widget for the given achievement criteria set.
Nenue@40 196 -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block
Nenue@40 197 local wr = T.WidgetRegistry
Nenue@40 198 T.GetWidget = function(data, objectiveType, objectiveKey)
Nenue@40 199 local print = B.print('ObjectiveWidgets')
Nenue@40 200 local widgetType = objectiveType
Nenue@40 201 local widget
Nenue@40 202 local isNew
Nenue@40 203 if wr[widgetType] and wr[widgetType].used[objectiveKey] then
Nenue@40 204 widget = wr[widgetType].used[objectiveKey]
Nenue@40 205 print('|cFF00FF00Updating ('..objectiveKey..')', widget)
Nenue@40 206 elseif not wr[widgetType] or #wr[widgetType].free == 0 then
Nenue@40 207 -- creating a new frame
Nenue@40 208 isNew = true
Nenue@40 209 widget = CreateFrame(widgetType, 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType)
Nenue@40 210 print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn)
Nenue@40 211 T.UpdateSchema(widgetType, data.schema or 'default')
Nenue@40 212 else
Nenue@40 213 -- recycling for a different criteria set
Nenue@40 214 isNew = true
Nenue@40 215 widget = tremove(wr[widgetType].free)
Nenue@40 216 print('|cFFFFFF00Acquiring released widget', widget:GetName())
Nenue@40 217 end
Nenue@40 218
Nenue@40 219 for k,v in pairs(data) do
Nenue@40 220 if not widget[k] then
Nenue@40 221 widget[k] = v
Nenue@40 222 tprint('widget', widget:GetName(), k, v)
Nenue@40 223 end
Nenue@40 224 end
Nenue@40 225
Nenue@40 226 wr[widgetType].used[objectiveKey] = widget
Nenue@40 227 widget.objective = data
Nenue@40 228 widget.key = objectiveKey
Nenue@40 229 T.InitializeWidget(widget, isNew)
Nenue@40 230 return widget
Nenue@40 231 end