comparison Veneer.lua @ 90:6e2cb847c3c6

Implement a mixin template for the basic visual config widgets.
author Nenue
date Mon, 24 Oct 2016 18:28:40 -0400
parents 74e714637d6a
children caded2668701
comparison
equal deleted inserted replaced
89:74e714637d6a 90:6e2cb847c3c6
5 -- 4. Update() 5 -- 4. Update()
6 -- 5. Reanchor() 6 -- 5. Reanchor()
7 7
8 SLASH_VENEER1 = "/veneer" 8 SLASH_VENEER1 = "/veneer"
9 SLASH_VENEER2 = "/vn" 9 SLASH_VENEER2 = "/vn"
10 local VENEER_VERSION = 703
10 11
11 SlashCmdList.VENEER = function(cmd) 12 SlashCmdList.VENEER = function(cmd)
13
14 if Veneer.ConfigMode then
15 Veneer.ConfigMode = false
16 else
17 Veneer.ConfigMode = true
18 end
19 Veneer:UpdateConfigLayers()
12 end 20 end
13 21
14 VeneerCore = { 22 VeneerCore = {
15 Frames = {}, 23 Frames = {},
16 ConfigLayers = {}, 24 ConfigLayers = {},
17 FrameClusters = {}, 25 FrameClusters = {},
18 parserDepth = 0, 26 parserDepth = 0,
19 pendingCalls = {}, 27 pendingCalls = {},
28 AddOnCheck = {}
20 } 29 }
21 VeneerHandlerMixin = {
22
23 anchorPoint = 'CENTER', -- indicates the initial cluster group point
24 --anchorPath = 'BOTTOM', -- indicates the point from which the frame is anchored in a cluster arrangement
25 OnHide = function()
26 Veneer:DynamicReanchor()
27 end,
28 OnShow = function(self)
29 self:Reanchor()
30 Veneer:StaticReanchor(self)
31 end
32 }
33 VeneerAnimationMixin = {}
34 local print = DEVIAN_WORKSPACE and function(...) print('Veneer', ...) end or nop 30 local print = DEVIAN_WORKSPACE and function(...) print('Veneer', ...) end or nop
35 local wipe = table.wipe 31 local wipe = table.wipe
36 32
37 local defaults = { 33 local defaults = {
38 enableAll = true, 34 enableAll = true,
40 BuffFrame = true, 36 BuffFrame = true,
41 }, 37 },
42 BuffFrame = { 38 BuffFrame = {
43 width = 48, 39 width = 48,
44 height = 48, 40 height = 48,
45 } 41 },
42 ConfigMode = true
46 } 43 }
47 44
48 local configMode 45 local configMode
49 local anonID = 0 46 local anonID = 0
50 local tostring = tostring 47 local tostring = tostring
107 self:RegisterForDrag('LeftButton') 104 self:RegisterForDrag('LeftButton')
108 105
109 106
110 end 107 end
111 108
109 local select, IsAddOnLoaded, IsLoggedIn = select, IsAddOnLoaded, IsLoggedIn
110
112 function VeneerCore:OnEvent(event, ...) 111 function VeneerCore:OnEvent(event, ...)
112 print(event, ...)
113 if event == 'ADDON_LOADED' or event == 'PLAYER_LOGIN' then 113 if event == 'ADDON_LOADED' or event == 'PLAYER_LOGIN' then
114 print(IsLoggedIn(), self.initialized)
114 if IsLoggedIn() and not self.intialized then 115 if IsLoggedIn() and not self.intialized then
115 self:Setup() 116 self:Setup()
116 self:UnregisterEvent('ADDON_LOADED') 117 self.intialized = true
117 self:UnregisterEvent('PLAYER_LOGIN') 118 print('popping init sequence', self.intialized)
118 self:Reanchor() 119 end
119 self:Update() 120
121
122 if self.intialized then
123 local addon = ...
124 if self.AddOnCheck[addon] then
125 print(' - setting up '..addon..' dependent modules:')
126 local keepChecking = false
127 for index, handler in ipairs(self.AddOnCheck[addon]) do
128 print(' -', handler:GetName(), (not handler.initialized) and (handler.addonFrame and not _G[handler.addonFrame]))
129 if not handler.initialized then
130 print(' '..handler:GetName()..':Setup()')
131 handler:Setup()
132 handler.initialized = true
133 end
134 end
135 if not keepChecking then
136 self.AddOnCheck[addon] = nil
137 end
138 end
120 end 139 end
121 end 140 end
122 end 141 end
123 142
124 function VeneerCore:OnDragStart() 143 function VeneerCore:OnDragStart()
128 function VeneerCore:OnDragStop() 147 function VeneerCore:OnDragStop()
129 self:StopMovingOrSizing() 148 self:StopMovingOrSizing()
130 end 149 end
131 150
132 function VeneerCore:Setup () 151 function VeneerCore:Setup ()
133 self.initialized = true 152 local resetConfig = (not VeneerData)
134 if (not VeneerData) or (not VeneerData.version) then 153 if (not VeneerData) then
135 VeneerData = defaults 154 VeneerData = defaults
155 VeneerData.version = VENEER_VERSION
156 self:print('Fresh install.')
157 elseif (VeneerData.version and VeneerData.version < VENEER_VERSION) then
158 local oldVars = VeneerData
159 VeneerData = defaults
160 VeneerData.version = VENEER_VERSION
161 VeneerData.oldSettings = oldVars
162 self:print('Resetting to temp defaults. Use /vn retro to use old settings.')
136 end 163 end
137 self.data = VeneerData 164 self.data = VeneerData
138 self:ExecuteOnClusters(nil, 'Setup') 165 self:ExecuteOnClusters(nil, function(frame)
139 end 166 if (not frame.addonTrigger) or select(2,IsAddOnLoaded(frame.addonTrigger)) then
140 167 if not frame.initialized then
168 frame:Setup()
169 frame.initialized = true
170 end
171 end
172 end)
173
174 self.ConfigMode = VeneerData.ConfigMode
175 self:UpdateConfigLayers()
176 self:Reanchor()
177 self:Update()
178 end
179
180 function VeneerCore:UpdateConfigLayers()
181 if VeneerData then
182
183 VeneerData.ConfigMode = self.ConfigMode
184 end
185
186 self:print('Config mode '..(self.ConfigMode and '|cFF00FF00ON|r' or '|cFFFF0000OFF|r')..'.')
187 self:ExecuteOnClusters(nil, function(frame)
188 if frame.UpdateConfigLayers then
189 frame:UpdateConfigLayers(self.ConfigMode)
190 end
191
192
193 if type(frame.ConfigLayer) == 'table' then
194 for index, region in ipairs(frame.ConfigLayer) do
195 print('setting', frame:GetName() .. '['.. index..']', 'to', self.ConfigMode)
196
197 region:SetShown(self.ConfigMode)
198 end
199 end
200
201 self.ConfigLayers[frame] = frame:IsShown()
202 if self.ConfigMode then
203 print(frame:GetName(), self.ConfigLayers[frame])
204 frame:SetShown(self.ConfigMode)
205 else
206 frame:SetShown(self.ConfigLayers[frame])
207 end
208 end)
209 end
141 210
142 function VeneerCore:GetClusterFromArgs (...) 211 function VeneerCore:GetClusterFromArgs (...)
143 local primaryAnchor 212 local primaryAnchor
144 local insertPosition 213 local insertPosition
214
215
216
145 local clusterTable = self.FrameClusters 217 local clusterTable = self.FrameClusters
146 for i = 1, select('#', ...) do 218 for i = 1, select('#', ...) do
147 local arg = select(i, ...) 219 local arg = select(i, ...)
148 local argType = type(arg) 220 local argType = type(arg)
149 if argType == 'string' then 221 if argType == 'string' then
167 end 239 end
168 240
169 function VeneerCore:AddHandler(handler, ...) 241 function VeneerCore:AddHandler(handler, ...)
170 print('*** Adding handler:', handler.moduleName or handler:GetName()) 242 print('*** Adding handler:', handler.moduleName or handler:GetName())
171 243
172 local anchorGroup, clusterTable, clusterIndex = self:GetClusterFromArgs(...) 244
173 if clusterIndex == 1 then 245 local anchorGroup, clusterTable, clusterIndex = self:GetClusterFromArgs(...)
174 for i, frame in ipairs(clusterTable) do 246 if clusterIndex == 1 then
175 frame.clusterIndex = i + 1 247 for i, frame in ipairs(clusterTable) do
176 end 248 frame.clusterIndex = i + 1
177 end 249 end
178 tinsert(clusterTable, clusterIndex, handler) 250 end
251 tinsert(clusterTable, clusterIndex, handler)
252
179 print('cluster', anchorGroup, 'table', clusterTable, 'position', clusterIndex) 253 print('cluster', anchorGroup, 'table', clusterTable, 'position', clusterIndex)
180 254
181 handler.anchorCluster = clusterTable 255 handler.anchorCluster = clusterTable
182 handler.anchorIndex = clusterIndex 256 handler.anchorIndex = clusterIndex
183 for k,v in pairs(VeneerHandlerMixin) do 257 for k,v in pairs(VeneerHandlerMixin) do
184 if not handler[k] then 258 if not handler[k] then
185 print(' * from mixin:', k) 259 print(' * from mixin:', k)
186 handler[k] = v 260 handler[k] = v
187 end 261 end
188 end 262 end
263
264 if handler.addonTrigger and not IsAddOnLoaded(handler.addonTrigger) then
265 print('|cFFFF4400 -- dependency:', handler.addonTrigger)
266 self.AddOnCheck[handler.addonTrigger] = self.AddOnCheck[handler.addonTrigger] or {}
267 tinsert(self.AddOnCheck[handler.addonTrigger], handler)
268 end
269
189 if self.initialized then 270 if self.initialized then
190 print(' -- doing initialization') 271 print(' -- initialization check')
191 if handler.Setup and not handler.initialized then 272 if handler.Setup then
192 handler:Setup() 273 local doInit = (not handler.initialized)
193 handler.initialized = true 274 if handler.addonTrigger and not IsAddOnLoaded(handler.addonTrigger) then
194 end 275 doInit = false
195 self:InternalReanchor(handler) 276 end
277 -- room to add other checks
278
279 if doInit then
280 handler:Setup()
281 handler.initialized = true
282 self:InternalReanchor(handler)
283 end
284 end
196 end 285 end
197 end 286 end
198 287
199 function VeneerCore:Reanchor() 288 function VeneerCore:Reanchor()
200 self:ExecuteOnClusters(nil, 'Reanchor') 289 self:ExecuteOnClusters(nil, 'Reanchor')
201 self:DynamicReanchor(self) 290 self:DynamicReanchor(self)
202 end 291 end
203 292
204 function VeneerCore:Update() 293 function VeneerCore:Update()
205 self:ExecuteOnClusters(nil, 'Update') 294 self:ExecuteOnClusters(nil, function(frame)
295 if frame.initialized and frame.Update then
296 frame:Update()
297 end
298 end)
206 self:Reanchor() 299 self:Reanchor()
207 end 300 end
208 301
209 -- updates anchor relations to and from the target handler 302 -- updates anchor relations to and from the target handler
210 function VeneerCore:GetAnchor(...) 303 function VeneerCore:GetAnchor(...)
217 parent = parent or self 310 parent = parent or self
218 print('|cFF88FF00DynamicReanchor()') 311 print('|cFF88FF00DynamicReanchor()')
219 for anchorPoint, cluster in pairs(parent.FrameClusters) do 312 for anchorPoint, cluster in pairs(parent.FrameClusters) do
220 local lastFrame 313 local lastFrame
221 for index, frame in ipairs(cluster) do 314 for index, frame in ipairs(cluster) do
222 print(' |cFF00FF00'..index, frame:GetName(), frame:IsVisible()) 315 print(' |cFF00FF00'..index, frame:GetName(), frame:IsVisible(), (lastFrame and ('|cFFFFFF00'..lastFrame:GetName()..'|r') or '|cFF00FFFFUIParent'))
223 if frame:IsVisible() then 316 if frame:IsVisible() then
224 anchorPoint = frame.anchorPoint 317
225 frame:ClearAllPoints() 318 if frame.anchorFrame then
226 if lastFrame then 319 frame:SetPoint(frame.anchorPoint, frame.anchorFrame, frame.anchorFrom, frame.anchorX, frame.anchorY)
227 frame:SetPoint(anchorPoint, lastFrame, ANCHOR_OFFSET_POINT[anchorPoint], 0, 0) 320 print(frame:GetTop(), frame:GetRight())
228 else 321 else
229 frame:SetPoint(anchorPoint, UIParent, anchorPoint, 0, 0) 322 anchorPoint = frame.anchorPoint
323 frame:ClearAllPoints()
324 if lastFrame then
325 frame:SetPoint(anchorPoint, lastFrame, ANCHOR_OFFSET_POINT[anchorPoint], 0, 0)
326 else
327 frame:SetPoint(anchorPoint, UIParent, anchorPoint, frame.anchorX, frame.anchorY)
328 end
329 print(frame:GetTop(), frame:GetRight())
330 lastFrame = frame
230 end 331 end
231 lastFrame = frame 332
232 end 333 end
233 334
234 end 335 end
235 end 336 end
236 end 337 end
237 338
238 -- Evaluates the current visibility state and re-anchors adjacent blocks accordingly 339 -- Evaluates the current visibility state and re-anchors adjacent blocks accordingly
239 function VeneerCore:InternalReanchor(handler, printFunc) 340 function VeneerCore:InternalReanchor(handler, printFunc)
240 print('|cFF00FFFFVeneer:InternalReanchor('..handler:GetName()..')') 341 print('|cFF00FFFFVeneer:InternalReanchor('..handler:GetName()..')')
342 if handler.anchorFrame then
343 handler:SetPoint(handler.anchorPoint, handler.anchorFrame, handler.anchorFrom, handler.anchorX, handler.anchorY)
344 return
345 end
346
347
241 local anchorPoint = handler.anchorPath or handler.anchorPoint 348 local anchorPoint = handler.anchorPath or handler.anchorPoint
242 local anchorParent, anchorTo = UIParent, anchorPoint 349 local anchorParent, anchorTo = UIParent, anchorPoint
243 local subPoint, subTo 350 local subPoint, subTo
244 local nextFrame 351 local nextFrame
245 for index, frame in ipairs(handler.anchorCluster) do 352 for index, frame in ipairs(handler.anchorCluster) do
302 if self.parserDepth > 1 then 409 if self.parserDepth > 1 then
303 tinsert(self.pendingCalls, method) 410 tinsert(self.pendingCalls, method)
304 print('delaying walk for', method) 411 print('delaying walk for', method)
305 return 412 return
306 end 413 end
307 print('|cFF00FF00Veneer:ExecuteOnClusters|r('..tostring(layer)..', '..method..')') 414 print('|cFF00FF00Veneer:ExecuteOnClusters|r('..tostring(layer)..', '..tostring(method)..')')
308 else 415 else
309 print(' Level '..self.parserDepth) 416 print(' Level '..self.parserDepth)
310 end 417 end
311 418
312 layer = layer or self.FrameClusters 419 layer = layer or self.FrameClusters
313 for anchor, cluster in pairs(layer) do 420 for anchor, cluster in pairs(layer) do
314 for index, frame in ipairs(cluster) do 421 for index, frame in ipairs(cluster) do
315 print(' '..anchor..'.'..index..' = '..frame:GetName()) 422 print(' '..anchor..'.'..index..' = '..frame:GetName())
316 if frame[method] then 423 if type(method) == 'function' then
424 method(frame, true)
425 elseif frame[method] then
317 print(' |cFF00FF00'..frame:GetName()) 426 print(' |cFF00FF00'..frame:GetName())
318 frame[method](frame, true) 427 frame[method](frame, true)
319 end 428 end
320 end 429 end
321 if cluster.FrameClusters then 430 if cluster.FrameClusters then
329 print('starting delayed walk for', delayedMethod) 438 print('starting delayed walk for', delayedMethod)
330 self:ExecuteOnClusters(nil, delayedMethod) 439 self:ExecuteOnClusters(nil, delayedMethod)
331 end 440 end
332 end 441 end
333 442
334 local VeneerButton_OnDragStart = function(self) 443
335 self.startingLeft = self:GetLeft()
336 self.startingBottom = self:GetBottom()
337 self.anchors = self.anchors or {}
338 table.wipe(self.anchors)
339
340 local frame = self:GetParent()
341 local n = frame:GetNumPoints()
342 for i = 1, n do
343 local anchor, parent, relative, x, y = frame:GetPoint(i)
344 self.anchors[i] = {
345 anchor = anchor,
346 parent = parent,
347 relative = relative,
348 x = x,
349 y = y
350 }
351 end
352
353 print(self:GetName(), 'start moving', self.startingLeft, self.startingBottom)
354 self:StartMoving()
355 end
356
357 local VeneerButton_OnDragStop = function(self)
358 self:StopMovingOrSizing()
359 if self.OnDragStop then
360 self.OnDragStop(self)
361 else
362 local frame = self:GetParent()
363 local dx = self:GetLeft() - self.startingLeft
364 local dy = self:GetBottom() - self.startingBottom
365
366 frame:ClearAllPoints()
367 for i, point in ipairs(self.anchors) do
368 frame:SetPoint(point.anchor, point.parent, point.relative, point.x + dx, point.y + dy)
369 print('adjusting anchor', point.anchor, point.parent, point.relative, point.x + dx, point.y + dy)
370 end
371 end
372 end
373
374 local Veneer_FixMovers = function()
375 for frame, veneer in pairs(veneers) do
376 if veneer:IsMoving() then
377 VeneerButton_OnDragStop(veneer)
378 end
379 end
380 end
381
382 local VeneerButton_Update = function(self)
383 if configMode then
384 self:SetScript('OnDragStart', VeneerButton_OnDragStart)
385 self:SetScript('OnDragStop', VeneerButton_OnDragStop)
386 self:SetMovable(true)
387 self:EnableMouse(true)
388 self:RegisterForDrag('LeftButton')
389
390 self.bg:SetColorTexture(0,1,0,0.5)
391 for i, region in ipairs(self.configLayers) do
392 region:Show()
393 end
394 self:Show()
395 else
396
397 self:SetScript('OnDragStart', self.StartMoving)
398 self:SetScript('OnDragStop', self.StopMovingOrSizing)
399 self:SetMovable(false)
400 self:EnableMouse(false)
401
402 self.bg:SetColorTexture(0,1,0,0)
403 for i, region in ipairs(self.configLayers) do
404 region:Hide()
405 end
406 if self.isHidden then
407 self:Hide()
408 end
409
410 end
411 end
412
413 local ToggleVeneerConfig = function()
414 if configMode then
415 configMode = false
416 Veneer:print('Config mode off.')
417 else
418 configMode = true
419 Veneer:print('Config mode on.')
420 end
421
422 for frame, veneer in pairs(veneers) do
423 VeneerButton_Update(veneer)
424 end
425 end
426
427 local VeneerButton_OnShow = function(self)
428 VeneerButton_Update(self)
429 end
430 444
431 -- Takes frame handle and assigns a block to it 445 -- Takes frame handle and assigns a block to it
432 function VeneerCore:Acquire (frame, template) 446 function VeneerCore:Acquire (frame, template)
433 if not frame then 447 if not frame then
434 print('|cFFFF4400Unable to acquire frame...|r') 448 print('|cFFFF4400Unable to acquire frame...|r')
435 return 449 return
436 end 450 end
437 local veneer = self.Frames[frame] 451 local veneer = self.Frames[frame]
438 if not veneer then 452 if not veneer then
439 local name = type(frame) == 'table' and GetTableName(frame) or GetAnonymousName() 453 local name = type(frame) == 'table' and GetTableName(frame) or GetAnonymousName()
440 veneer = CreateFrame('Frame', name, frame, template or 'VeneerTemplate') 454 veneer = CreateFrame('Frame', name, frame, template or 'VeneerStatusButtonTemplate')
441 print('+veneer', name) 455 print(self:GetName()..':Acquire()', frame:GetName(), template)
442 456
443 veneer:SetAllPoints(frame) 457 veneer:SetAllPoints(frame)
444 veneer:SetParent(frame) 458 veneer:SetParent(frame)
445 veneer.label:SetText(name) 459 veneer.label:SetText(name)
446 veneer.bg:SetColorTexture(0,0,0,0) 460 veneer.bg:SetColorTexture(0,0,0,0)
447 veneer:Hide() 461 veneer:Hide()
448 veneer:EnableMouse(false) 462 veneer:EnableMouse(false)
449
450 veneer:SetScript('OnShow', VeneerButton_OnShow)
451
452 -- find current X/Y 463 -- find current X/Y
453 veneer.currentLeft = frame:GetLeft() 464 veneer.currentLeft = frame:GetLeft()
454 veneer.currentTop = frame:GetTop() 465 veneer.currentTop = frame:GetTop()
455 self.Frames[frame] = veneer 466 self.Frames[frame] = veneer
456 end 467 end
457
458 return veneer 468 return veneer
459 end 469 end
460
461 function VeneerHandlerMixin:Reanchor (anchorAll)
462 if not anchorAll then
463 Veneer:InternalReanchor(self)
464 end
465
466 end
467
468 function VeneerAnimationMixin:OnPlay()
469 PlaySoundKitID(229)
470 self.animating = true
471 print('|cFF00FF00Anim:OnPlay|r @', unpack(self.sourcePoint))
472 end
473 function VeneerAnimationMixin:OnStop()
474 PlaySoundKitID(229)
475 self.animating = nil
476 print('|cFF00FF00Anim:OnFinish|r @', unpack(self.destPoint))
477 end
478 function VeneerAnimationMixin:OnFinished()
479 PlaySoundKitID(229)
480 self.animating = nil
481 print('|cFF00FF00Anim:OnFinish|r @', unpack(self.destPoint))
482 end