comparison Turok/Layout/Layout.lua @ 6:a9b8b0866ece

clear out log jam
author Nenue
date Sun, 21 Feb 2016 08:32:53 -0500
parents
children 9400a0ff8540
comparison
equal deleted inserted replaced
5:8a9a6637f082 6:a9b8b0866ece
1 --- LibFog-1.0
2 -- In-house solution to processing frame configuration data.
3 --[[
4 --
5 Config Table fields:
6
7 background .. _color, _texture, _blend properties of the texture referenced by frame.background
8 foregound .. " " " properties of the texture referenced by frame.foreground
9 backdrop arguments for SetBackdrop
10 border_color sets the border color on an existing frame backdrop
11 alpha, alpha_ooc uiobject alpha for in and out of combat
12 combat_fade true to change alpha levels based on combat
13 fade_time, fade_in, fade_out fade_time = fade_in or fade_out
14
15 anchor, parent, anchorTo, x, y args for UIObject:SetPoint()
16 height, width args for Region:SetSize()
17 strata, layer, level override the strata, draw layer, and draw level where they apply
18
19 padding space between frame and background edge
20 foreground_inset space between background and foreground edge
21 spacing space between segmented foreground elements (e.g. combo points)
22
23 font, size, outline args for FontString:SetFont() respectively
24 justifyV, justifyH LEFT/CENTER/RIGHT, TOP/MIDDLE/BOTTOM
25
26 SetFrameLayout():
27 Applies:
28 anchor, parent, anchorTo, x, y
29 width, height,
30 padding, spacing, foreground_inset
31 backdrop, border_color, background_color
32 alpha, alpha_ooc
33
34 SetStatusTextures():
35 Applies:
36 foreground_texture, foreground_color, foreground_blend
37 background_texture, background_color, background_blend
38
39 Defines:
40 fill_direction, fill_width, fill_height, fill_inset
41 :TranslateX(progress)
42 :TranslateY(progress)
43 :SetFillPoints()
44
45 SetFontLayout():
46 Applies:
47 anchor, parent, anchorTo, x, y
48 width, height
49 font, size, outline
50 justifyH, justifyV
51
52 -
53 ]]
54 local MAJOR, MINOR = "LibFog-1.0", 1
55 local F, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
56 if not F then return end
57
58 local _G, UIParent, type, unpack, pairs, ipairs, min, abs, tostring, print = _G, UIParent, type, unpack, pairs, ipairs, math.min, math.abs, tostring, print
59 local InCombatLockdown, GetTime, PlaySoundKitID, CreateFrame = InCombatLockdown, GetTime, PlaySoundKitID, CreateFrame
60 local tinsert, wipe, concat = table.insert, table.wipe, table.concat
61 local FADE_OUT_TIME, FADE_IN_TIME = 1, 0.4
62
63 --@debug@
64 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool
65 local ADDON, scriptargs = ...
66 scriptargs.LibFog = F
67 local print = function(...)
68 if _G.Devian and _G.DevianDB.workspace ~= 1 then
69 _G.print('Layout', ...)
70 end
71 end
72 --- debug highlighters
73 local namef = function(s) return '|cFFFFFF00' ..tostring(s).. '|r' end -- uiobject targeted function
74 local namet = function(s) return '|cFFFF4400 '..tostring(s).. '|r' end -- region targeted function
75 local valuef = function(s) return '|cFF88FF88'..(s ~= nil and ('"'..tostring(s)..'"') or ('nil'))..'|r' end -- uiobject name
76 local valuet = function(s) return '|cFFAACCAA'..(s ~= nil and ('"'..tostring(s)..'"') or ('nil'))..'|r' end -- string value
77 local valuen = function(s) return '|cFFAADD77' ..(s ~= nil and ('"'..tostring(s)..'"') or ('nil')).. '|r' end -- string enumeration
78 local valued = function(s) return '|cFFFFFFFF' ..(s ~= nil and ('"'..tostring(s)..'"') or ('nil')).. '|r' end -- number
79 --@end-debug@
80 local GetPrint = function(trace)
81 if trace then
82 return print
83 else
84 return function() end
85 end
86 end
87
88 --- Layout control metadata
89 local lastdb -- fallback if a table isn't found mid-operation
90 local ui_meta = {
91 beepkit = 15263, -- something to play when debugging
92 }
93 local ui_embeds = {
94 ['Frame'] = 'SetFrameLayout',
95 ['Texture'] = 'SetTextureLayout',
96 ['Font'] = 'SetFontLayout',
97 }
98
99 --- Resolve a parent object from varying depths
100 -- @param self target object
101 -- @parent string/number name of global frame or number of GetParent() hops to make
102 -- @childKey index key to retrieve from the resolved parent object
103 local function ParentValue(self, parent, childKey)
104 local print = GetPrint(self.trace)
105
106 local relativeTo = parent
107 if type(parent) == 'number' then
108 print(cWord('* Parent Trace:'), cNum(parent), cKey(self:GetName()))
109 relativeTo = self:GetParent()
110 for i = 2, parent do
111 if relativeTo.GetParent and relativeTo:GetParent() ~= UIParent then
112 --@debug@
113 print(' ', 'parent =', relativeTo:GetName())
114 --@end-debug
115 local next = relativeTo:GetParent()
116 relativeTo = next
117 else
118 --@debug@
119 print(' ',cWord(self:GetName()), 'parent =', cWord(parent))
120 --@debug-end@
121 end
122 end
123 end
124
125 -- This allows us to call for an immediate sub-frame and still get a usable value if it's not there
126 if childKey and relativeTo[childKey] then
127 return relativeTo[childKey]
128 end
129 return relativeTo
130 end
131
132 --- Animations
133 F.animate_regions = {}
134 setmetatable(F.animate_regions, {
135 __newindex = function (t,k,v)
136 rawset(t,k,v)
137 v.animationID = k
138 F.SetAnimationGroup(v)
139 end
140 })
141
142 --- Constructs the generic status frame
143 function F:SetFrameLayout(c)
144 local print = GetPrint(c.trace)
145 self.trace = c.trace or self.trace
146
147 self.db = c
148 self.labels = {}
149
150 self.name = self:GetName()
151 self.combat = InCombatLockdown()
152 self:SetPoint(c.anchor, c.parent, c.anchorTo, c.x, c.y)
153 self:SetSize(c.width, c.height)
154 self:SetFrameStrata(c.strata)
155 self.throttle_rate = 0.010
156 self.throttle_point = GetTime()
157
158 if c.backdrop then
159 c.backdrop.edgeSize = c.padding*4
160 self:SetBackdrop(c.backdrop)
161 end
162 if c.background_color and c.border_color then
163 self:SetBackdropColor(unpack(c.background_color))
164 self:SetBackdropBorderColor(unpack(c.border_color))
165 end
166
167 --@debug@
168 print(namef('SetFrameLayout'),'(', valuet(self:GetName()),')')
169 print(cText(' dimensions:'), cNum(c.width), 'by', cNum(c.height), '::', c.x, c.y, c.anchor, c.anchorTo, c.parent)
170 --@end-debug@
171
172 self.width = c.width
173 self.height = c.height
174 self.foreground_inset = c.foreground_inset
175 self.padding = c.padding
176 self.spacing = c.spacing
177 self.alpha = c.alpha
178
179 self.combatFade = c.combatFade
180 self.alpha_fade_in = c.alpha_fade_in or c.alpha_fade
181 self.alpha_fade_out = c.alpha_fade_out or c.alpha_fade
182 print(' fade on combat =', self.combatFade)
183 for _, type in ipairs({'alpha', 'alpha_ooc'}) do
184 self[type] = c[type]
185 _G.print('DB', self:GetName(), type, self[type])
186 for _, subtype in ipairs({'_passive', '_active'}) do
187 self[type..subtype] = c[type..subtype] or self[type]
188 _G.print('DB', self:GetName(), type..subtype, self[type..subtype])
189 for _, subsubtype in ipairs({'_empty', '_half', '_full'}) do
190 self[type..subtype..subsubtype] = c[type..subtype..subsubtype] or self[type..subtype]
191 _G.print('DB', self:GetName(), type..subtype..subsubtype, self[type..subtype..subsubtype])
192 self[type..subsubtype] = c[type..subsubtype] or self[type..subtype]
193 _G.print('DB', self:GetName(), type..subsubtype, self[type..subsubtype])
194 end
195 end
196 end
197 self.UpdateAlpha = F.UpdateAlpha
198 --if c.combatFade then
199 self.faderID = #F.animate_regions+1
200 F.animate_regions[#F.animate_regions+1] = self
201 print(cText(' animation target ID #'), cNum(self.faderID))
202 --end
203
204 self:UpdateAlpha(InCombatLockdown())
205
206 if self.lefttext then
207 print(' auto-lefttext')
208 F.SetFontLayout(self.lefttext, c.lefttext or c)
209 end
210 if self.righttext then
211 print(' auto-righttext')
212 F.SetFontLayout(self.righttext, c.righttext or c)
213 end
214 end
215
216 --- Seeds basic animations, else a template can be specified by the frame data
217 function F:SetAnimationGroup(group)
218 local print = GetPrint(self.trace)
219
220 group = group or self.animationClass or nil
221 --@debug@
222 if not group then
223 print(' |cFFFF44AAseeding debug animations', self:GetName())
224 self.__flash = self:CreateAnimationGroup(self:GetName()..'Flasher')
225 self.__flash:SetToFinalAlpha(true)
226 local fade1 = self.__flash:CreateAnimation('Alpha')
227 fade1:SetChange(-1)
228 fade1:SetDuration(.6)
229 fade1:SetOrder(1)
230 local fade2 = self.__flash:CreateAnimation('Alpha')
231 fade2:SetChange(1)
232 fade2:SetDuration(.6)
233 fade2:SetOrder(2)
234 fade2:SetEndDelay(.6)
235 --@debug@
236 self.__flash.fade1 = fade1
237 self.__flash.fade2 = fade2
238 self.__flash:SetLooping('NONE')
239 self.__flash:SetScript('OnFinished', function()
240 print(self:GetName(), '[>>>] Done animating flash.')
241 self.flashing = nil
242 end)--@end-debug@
243 self.Flash = F.Flash
244
245 self.__fade = self:CreateAnimationGroup(self:GetName()..'Fader')
246 self.__fade:SetToFinalAlpha(true)
247 self.__fade:SetScript('OnFinished', function()
248 print(self:GetName(), '[>>>] Done animating fade.')
249 self.fading = nil
250 local a = self.__flash.fade1:GetToAlpha()
251 --self:SetAlpha(a)
252 if a == 0 and not self.__fade.noHide then
253 self:Hide()
254 end
255 if self.__fade.queuedFade then
256 print('[>>>] ', cWord(self:GetName())..'.'..cKey('__fade:'), 'starting queued fade')
257 local fadeTo, fadeDuration, noHide = unpack(self.__fade.queuedFade)
258 self.__fade.queuedFade = nil
259 self:Fade(fadeTo, fadeDuration, noHide)
260 end
261 end)
262 self.Fade = F.Fade
263 end
264 --@end-debug@
265 if not self.animationID then
266 tinsert(F.animate_regions, self) -- uses rawset, so won't death loop
267 self.animationID = #F.animate_regions
268 end
269 end
270
271 function F:Flash(duration, peak, valley, holdUp, holdDown)
272 local print = GetPrint(self.trace)
273
274 local fl = self.__flash
275 print('[>>>]', self:GetName(), duration, peak, valley, holdUp, holdDown)
276 fl.fade1:SetFromAlpha(valley)
277 fl.fade1:SetToAlpha(peak)
278 fl.fade1:SetDuration(duration)
279 fl.fade1:SetEndDelay(holdUp)
280 fl.fade2:SetFromAlpha(peak)
281 fl.fade2:SetToAlpha(valley)
282 fl.fade2:SetDuration(duration)
283 fl.fade2:SetEndDelay(2)
284 self.flashing = true
285 fl:Play()
286 end
287
288 --- Fade to a value; fading to 0 will hide the frame
289 function F:Fade(duration, fadeTo, noHide)
290
291 print('|cFFFF6600[>>>]', cText('Fade('), self:GetName(), cText(')'))
292 local fader = self.__fade
293 local fade1 = self.__flash.fade1
294 if fader:IsPlaying() then
295 self.__fade.queuedFade = {duration, fadeTo, noHide }
296 print(' ', cText('playing:'), cNum(fader:GetDuration())..'s', cNum(fade1:GetToAlpha()))
297 print(' ', cPink('queued {'), cNum(duration)..'s', cNum(self:GetAlpha()), 'to', cNum(fadeTo), '}')
298 return
299 else
300 print(' ', cNum('starting {'), cNum(duration), cNum(self:GetAlpha()), 'to', cNum(fadeTo), '}')
301 end
302 fade1:SetParent(fader)
303 fade1:SetFromAlpha(self:GetAlpha())
304 fade1:SetToAlpha(fadeTo)
305 fade1:SetDuration(duration)
306 fade1:SetOrder(1)
307 self.__fade.noHide = noHide
308 self.fading = true
309 fader:Play()
310 end
311
312 function F:Beep()
313 if self.quiet then
314 return
315 end
316 PlaySoundKitID(F.beepkit) -- random anub'rhekan sounds
317 end
318
319
320 --- Defines the corners used in filling operations
321 local directionBase = {
322 ['LEFT'] = 'TOPRIGHT',
323 ['RIGHT'] = 'TOPLEFT',
324 ['UP'] = 'BOTTOMLEFT',
325 ['DOWN'] = 'TOPLEFT'
326 }
327 local directionPeak ={
328 ['LEFT'] = 'BOTTOMLEFT',
329 ['RIGHT'] = 'BOTTOMRIGHT',
330 ['UP'] = 'TOPRIGHT',
331 ['DOWN'] = 'BOTTOMRIGHT',
332 }
333 local directionPeakTo = {
334 ['LEFT'] = 'BOTTOMRIGHT',
335 ['RIGHT'] = 'BOTTOMLEFT',
336 ['UP'] = 'BOTTOMRIGHT',
337 ['DOWN'] = 'TOPRIGHT'
338 }
339 local anchorInverse = {['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['TOP'] = 'BOTTOM', ['BOTTOM'] = 'TOP' }
340 --- Directional coefficients for corner positions
341 -- [1] = end X, [2] = end Y, [3] = base X, [4] = base Y
342 local directionCoord = {
343 ['LEFT'] = {-1, 0, -1, -1},
344 ['RIGHT'] = { 1, 0, 1, -1},
345 ['UP'] = { 0, 1, 1, 1},
346 ['DOWN'] = { 0, -1, 1, -1},
347 ['CENTER'] = {.5, .5, 1, 1}
348 }
349 local paddingScale = {
350 ['UP'] = 1,
351 ['DOWN'] = -1,
352 ['LEFT'] = -1,
353 ['RIGHT'] = 1,
354 }
355 local embedScale = {
356 ['LEFT'] = {1, false},
357 ['RIGHT'] = {-1, false},
358 ['TOP'] = {false, -1},
359 ['BOTTOM'] = {false, 1}
360 }
361
362 --- Determines the correct relative X offset for a given progress ratio
363 --- x = 0 + padding + spacing + i, where i = {embedded | icon_size +spacing}
364 -- Factors padding and spacing parameters, including icon embedding dimensions.
365 -- @param self frame on which the foreground/background textures and config data exist
366 -- @param ratio progess from 0 to 1; 0 returns the starting corner coordinate, 1 returns end corner
367 -- @param scale overrides the pixel fill length, with starting corner used as scaling origin
368 local TranslateX = function(self, ratio, scale)
369 if not scale then
370 scale = self.fill_width
371 end
372 if self.fill_inverse then
373 ratio = 1 - ratio
374 end
375 _G.print('Update', 'dx', self.fill_x)
376 local x =
377 scale * ratio * directionCoord[self.fill_direction][1]
378 return min(x, scale) + self.fill_x
379 end
380
381 --- Determines the correct relative Y offset for a given progress ratio
382 -- Factors padding and spacing parameters, including icon embedding dimensions.
383 -- @param self frame on which the foreground/background textures and config data exist
384 -- @param ratio progess from 0 to 1; 0 returns the starting corner coordinate, 1 returns end corner
385 -- @param scale overrides the pixel fill length, with starting corner used as scaling origin
386 local TranslateY = function(self, ratio, scale)
387 if not scale then
388 scale = self.fill_height
389 end
390 if self.fill_inverse then
391 ratio = 1 - ratio
392 end
393
394 _G.print('Update', 'dy', self.fill_y)
395 -- (height of bar offset by the size of any overlapping element) * progress ratio, offset by the size of any overlapping embed + inset
396 local y =
397 scale * ratio * directionCoord[self.fill_direction][2] - self.foreground_inset
398 return min(y, scale) + self.fill_y
399 end
400 local SetProgress = function(self, progress, scaleX, scaleY)
401 _G.print('Update', cText(self:GetName()),
402 "\n d:", progress, 'dX:', directionCoord[self.fill_direction][1], 'dY:', directionCoord[self.fill_direction][2], 'dI:', self.fill_inverse,
403 "\n peak:", self.fill_anchor, self.fill_anchorTo, TranslateX(self, progress), TranslateY(self,progress))
404
405 self.foreground:SetPoint(self.fill_anchor, self.background, self.fill_anchorTo, TranslateX(self, progress, scaleX), TranslateY(self, progress, scaleY))
406 end
407
408 --- Assigns textures to the generic foreground background bar regions
409 -- Called as F.SetStatusTextures(MyFrame, config pointer)
410 -- foreground_inset - number of pixels by which the foreground edges occlude the background (basically always negative)
411 -- padding - number of pixels between the background edge and frame edge (basically always positive)
412 function F:SetStatusTextures(c)
413 local print = GetPrint(self.trace)
414
415 if c == nil then
416 c = self.db or lastdb
417 if not c then
418 error('No config table found')
419 end
420 end
421 local relativeTo = ParentValue(self, c.parent, c.parentKey)
422
423
424 self.fill_direction = c.fill_direction or 'RIGHT'
425 self.fill_inset = c.padding - c.foreground_inset -- foreground edge / frame edge
426 self.fill_width = self.width - self.fill_inset*2 -- foreground left / right edges
427 self.fill_height = self.height - self.fill_inset*2 -- " top / bottom "
428 self.fill_inverse = c.fill_inverse
429 self.fill_x, self.fill_y = 0, 0
430 self.fill_insets = {
431 LEFT = self.fill_inset,
432 TOP = self.fill_inset,
433 BOTTOM = self.fill_inset,
434 RIGHT = self.fill_inset
435 }
436
437
438 -- create filling points
439 self.fill_base = directionBase[self.fill_direction]
440 self.fill_anchor = directionPeak[self.fill_direction]
441 self.fill_anchorTo = directionPeakTo[self.fill_direction]
442 print(" foreground:", self.fill_base, self.fill_base, TranslateX(self, 0), TranslateY(self, 0))
443 print(" foreground fill:", self.fill_anchor, self.fill_anchorTo)
444
445 -- calculate icon embed
446 if self.icon and self.icon.embedded then
447 print(cText('#### EMBED ####'))
448 -- change anchor point so the icon is inside
449 self.icon.anchor = self.icon.anchorTo
450 print(' * Icon anchor:' , cText(self.icon.anchor), 'to', cText(self.icon.anchorTo))
451 print(' * Fill start:', cText(self.fill_base))
452
453
454 local coordSet = {nil, nil}
455 local baseSet = {nil, nil }
456 local endSet = {nil, nil}
457 for dir, coords in pairs(embedScale) do
458 if self.icon.anchor:match(dir) then
459 print(' xtrans { matches', dir, 'include {', coords[1], coords[2], '}')
460 if not coordSet[1] then coordSet[1] = coords[1] end
461 if not coordSet[2] then coordSet[2] = coords[2] end
462
463 -- the embedding position can overlap either corner
464 if self.fill_base:match(dir) then
465 print(' base corner also matches')
466 if not baseSet[1] then baseSet[1] = coords[1] end
467 if not baseSet[2] then baseSet[2] = coords[2] end
468 else
469
470 if not endSet[1] then endSet[1] = coords[1] end
471 if not endSet[2] then endSet[2] = coords[2] end
472 end
473 end
474 end
475
476 -- make sure there are values if none of them matched at all for some reason
477 coordSet = {coordSet[1] or 0, coordSet[2] or 0}
478 baseSet = {baseSet[1] or 0, baseSet[2] or 0 }
479 -- needs to produce a negative number
480 endSet = {endSet[1] or 0, endSet[2] or 0 }
481
482
483 print(' == xtrans push =', unpack(coordSet))
484 print(' == fbase delta =', unpack(baseSet))
485 print(' == ftail delta =', unpack(endSet))
486
487 -- determine the foreground displacement
488
489 self.icon_dx = (min(self.fill_width, self.fill_height) + self.spacing)
490 self.icon_dy = (min(self.fill_width, self.fill_height) + self.spacing)
491 print(' * Foreground compression:', cNum(self.icon_dx))
492
493 self.icon_size = self.icon.size
494 self.icon_x = self.padding * baseSet[1] - (self.icon.size - self.icon_dx)
495 self.icon_y = self.padding * baseSet[2] - (self.icon.size - self.icon_dy)
496 print(' * Icon dims:' , cNum(self.icon_size), ' offset:', cNum(self.icon_dx))
497
498
499 local ofi = self.fill_insets[self.fill_direction]
500 print(' * Fill inset('..cWord(self.fill_direction)..') from', cNum(ofi), 'to', cNum(self.fill_insets[self.fill_direction]))
501
502 -- used to place the starting corner
503 self.fill_x = (self.icon_dx) * baseSet[1]
504 self.fill_y = (self.icon_dy) * baseSet[2]
505 print(' * fill offset dX:', self.fill_x)
506 print(' * fill offset dY:', self.fill_y)
507
508 -- amount taken off of fill scale, subtract spacing
509 self.icon_dx_cut = abs(self.icon_dx * -baseSet[1])
510 self.icon_dy_cut = abs(self.icon_dy * -baseSet[2])
511
512 local ofw, ofh = self.fill_width, self.fill_height
513 self.fill_width = self.fill_width - self.icon_dx_cut
514 self.fill_height = self.fill_height - self.icon_dy_cut
515 print(' * Scale dX:', self.icon_dx_cut, cNum(ofw), 'to', cNum(self.fill_width))
516 print(' * Scale dY:', self.icon_dy_cut, cNum(ofh), 'to', cNum(self.fill_height))
517
518 self.icon:ClearAllPoints()
519 self.icon:SetPoint(self.icon.anchor, self, self.icon.anchorTo, self.icon_x, self.padding * coordSet[2])
520 self.icon:SetSize(self.icon_size, self.icon_size)
521 end
522
523 --@debug@
524 print(namet('SetStatusTextures'),'(', valuef(self:GetName()), ')')
525 print(' form:', self.padding,'-', self.foreground_inset, '+', self.fill_width, self.padding,'-', self.foreground_inset, '+','x', self.padding,'-', self.foreground_inset, '+', self.fill_height, self.padding,'-', self.foreground_inset, '+')
526 print(' ', valuen(concat(c.background_color,', ')),valuet(c.background_texture), valuen(concat(c.foreground_color,', ')), valuet(c.foreground_texture))
527 print(' background:', self.padding, self.padding, 'BOTTOMLEFT', 'BOTTOMLEFT' , '::', -self.padding, -self.padding, 'TOPRIGHT', 'TOPRIGHT')
528 --@end-debug@
529
530 self.background:ClearAllPoints()
531 self.background:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', self.padding, self.padding)
532 self.background:SetPoint('TOPRIGHT', self, 'TOPRIGHT', -self.padding, -self.padding)
533 if c.background_texture ~= '' and c.background_texture ~= nil then
534 self.background:SetTexture(c.background_texture)
535 self.background:SetVertexColor(unpack(c.background_color))
536 else
537 self.background:SetTexture(unpack(c.background_color))
538 end
539 self.background:SetBlendMode(c.background_blend)
540
541 if c.foreground_texture ~= '' and c.foreground_texture ~= nil then
542 self.foreground:SetTexture(c.foreground_texture)
543 self.foreground:SetVertexColor(unpack(c.foreground_color))
544 else
545 self.foreground:SetTexture(unpack(c.foreground_color))
546 end
547 self.foreground:SetBlendMode(c.foreground_blend)
548
549 self.foreground:ClearAllPoints()
550 local dx = (directionCoord[self.fill_direction][3] * -self.foreground_inset) + self.fill_x
551 local dy = (directionCoord[self.fill_direction][4] * -self.foreground_inset) + self.fill_y
552 print(' foreground base:', cNum(dx), cNum(dy))
553 self.foreground:SetPoint(self.fill_base, self.background, self.fill_base, dx, dy)
554
555 SetProgress(self, 1)
556
557 self.TranslateX = TranslateX
558 self.TranslateY = TranslateY
559 self.SetFillPoints = SetFillPoints
560 self.SetProgress = SetProgress
561 end
562 --- Sets properties for a generated FontString
563 -- Takes the FontString object as a self, and applies config values.
564 -- In particalur, the anchor parent is derived from either a fixed number of GetParent() or global name
565 -- @usage Region:SetFontLayout([table])
566 function F:SetFontLayout (c)
567 local print = GetPrint(self.trace)
568
569 if c == nil then
570 c = lastdb
571 if not c then
572 error('No config table found')
573 end
574 end
575 local relativeTo = ParentValue(self, c.parent, c.parentKey)
576
577 --@debug@
578 print(namet('FontLayout'),'(', valuet(self:GetName()), ')', valuet(c.font), valuet(c.size), valuet(c.outline))
579 print(' ', valuen(c.anchor or 'CENTER'), relativeTo:GetName(), valuen(c.anchorTo or 'CENTER'), valued(c.x or 0),
580 valued(c.y or 0))
581 --@end-debug@
582 self:SetPoint(
583 c.anchor or 'CENTER',
584 relativeTo,
585 c.anchorTo or 'CENTER',
586 c.x or 0,
587 c.y or 0)
588 self:SetSize(
589 c.width or relativeTo:GetWidth(),
590 c.height or relativeTo:GetHeight())
591 self:SetFont(
592 c.font,
593 c.size,
594 c.outline)
595 self:SetJustifyH(c.justifyH or 'CENTER')
596 self:SetJustifyV(c.justifyV or 'MIDDLE')
597 self:SetTextColor(unpack(c.text_color or {1,1,1,1}))
598 end
599
600 --- For setting up widget pieces
601 function F:SetTextureLayout(c)
602 local print = GetPrint(self.trace)
603
604 if c == nil then
605 c = lastdb
606 if not c then
607 error('No config table found')
608 end
609 end
610 local relativeTo = ParentValue(self, c.parent, c.parentKey)
611
612 self.size = c.size
613 self.width = c.width
614 self.height = c.height
615 self.x = c.x
616 self.y = c.y
617 self.embedded = c.embedded
618 self.anchor = c.anchor
619 self.anchorTo = c.anchorTo
620
621 self:SetPoint(c.anchor, relativeTo, c.anchorTo, c.x, c.y)
622 self:SetSize(c.size or c.width, c.size or c.height)
623 self:SetAlpha(c.alpha)
624 self:SetDesaturated(c.desaturated or false)
625 print('|cFF00FFFFSetTextureLayout(|r', self:GetName(), '|cFF00FFFF)|r')
626 print(' ', c.anchor, relativeTo, c.anchorT, c.x, c.v)
627 if c.combatFade and not (relativeTo.faderID and F.animate_regions[relativeTo.faderID]) then
628 tinsert(F.animate_regions, self)
629 self.faderID = #F.animate_regions
630 --@debug@
631 print('register fadeable texture #'..self.faderID)
632 --@end-debug@
633 end
634 end
635
636 local alphaSubType = {
637 [1] = '_passive',
638 [2] = '_active'
639 }
640 local alphaFillType = {
641 [1] = '_empty',
642 [2] = '_half',
643 [3] = '_full',
644 }
645 function F:UpdateAlpha(inCombat, displayState, fillState)
646 local print = function() end
647 print(cWord('UpdateAlpha(')..self:GetName()..cWord(')'))
648 local alphaType = inCombat and 'alpha' or 'alpha_ooc'
649 local alphaDuration = inCombat and 'alpha_fade_in' or 'alpha_fade_out'
650 local displayState = displayState or self.displayState or nil
651 local fillState = fillState or self.fillState or nil
652
653 local alphaSubType = ''
654 if displayState then
655 alphaSubType = (displayState == 1) and '_passive' or ((displayState == 2) and '_active' or '' )
656 end
657
658 local alphaFillType = ''
659 if fillState then
660 alphaFillType = (fillState == 1) and '_half' or ((fillState == 2) and '_full' or '_empty')
661 end
662
663 local fadeTo = self[alphaType..alphaSubType..alphaFillType]
664 local fadeDuration = self[alphaDuration] or 0
665 print(' alphaKey:', cWord(alphaType..alphaSubType..alphaFillType))
666 print(' alphaTo:', cNum(fadeTo), 'duration:', cNum(fadeDuration))
667 if self:IsVisible() and fadeDuration ~= 0 then
668 self:Fade(fadeDuration, fadeTo or (inCombat and 1 or 0.5), true)
669 print(' |cFFFFFF00 :Fade()|r', 'dur='..cNum(fadeDuration), cNum(fadeTo), cWord(self:GetName()))
670 else
671 self:SetAlpha(fadeTo)
672 print(' |cFF00FF00 :SetAlpha('..fadeTo..')|r', cText(self:GetName()))
673 end
674 end
675
676 --- Sets an OnUpdate within a time-throttled wrapper
677 -- throttle rate should be slightly smaller than 1/average frame rate
678 function F:SetFrameScript(updateFunc, showFunc, hideFunc, ...)
679 local print = GetPrint(self.trace)
680
681 if not self.__oldscripts then
682 self.__oldscripts = {}
683 end
684
685 self:SetScript('OnUpdate', nil) -- clear any scripts
686 self:SetSCript('OnUpdate', function(self)
687 if GetTime() < self.throttle_time then
688 return
689 end
690 self.throttle_time = self.throttle_time + self.throttle_rate
691 updateFunc(self)
692 end) -- put the new function in its place
693 local changeSet = {
694 { self.__oldscripts,onUpdate = self:GetScript('OnUpdate') },
695 }
696
697 if showFunc then
698 tinsert(changeSet,
699 {onShow = self:GetScript('OnShow')})
700 self:SetScript('OnShow', showFunc)
701 end
702
703 if hideFunc then
704 tinsert(changeSet,
705 {onHide = self:GetScript('OnShow')})
706 self:SetScript('OnHide', hideFunc)
707 end
708 end
709
710 --- Embed
711 function F:Embed(object)
712 print('Doing embed')
713 for k, v in pairs(ui_embeds) do
714 print('embedding Set'..k..'Layout')
715 object['Set'..k..'Layout'] = self[v]
716 end
717 object.SetStatusTextures = self.SetStatusTextures
718
719 --- map a generic layout method if embedded into a frame object
720 if object.GetObjectType and ui_embeds[object.GetObjectType()] then
721 if ui_embeds[object.GetObjectType()] then
722 object.SetLayout = ui_embeds[object.GetObjectType()]
723 end
724 end
725 end