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