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 |
