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