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