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 |