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