Mercurial > wow > turok
view Turok/Layout/Layout.lua @ 9:9400a0ff8540
Ugh
Timer:
- container update directionality
- talent update iterates over a non-volatile table to carry out updates
- index management steps organized
- talentRow status implemented, returns the spell associated with the talent chosen from that row
CombatLog:
- sort out font controls and unbork arguments
author | Nenue |
---|---|
date | Sun, 21 Feb 2016 13:08:30 -0500 |
parents | a9b8b0866ece |
children |
line wrap: on
line source
--- LibFog-1.0 -- In-house solution to processing frame configuration data. --[[ -- Config Table fields: background .. _color, _texture, _blend properties of the texture referenced by frame.background foregound .. " " " properties of the texture referenced by frame.foreground backdrop arguments for SetBackdrop border_color sets the border color on an existing frame backdrop alpha, alpha_ooc uiobject alpha for in and out of combat combat_fade true to change alpha levels based on combat fade_time, fade_in, fade_out fade_time = fade_in or fade_out anchor, parent, anchorTo, x, y args for UIObject:SetPoint() height, width args for Region:SetSize() strata, layer, level override the strata, draw layer, and draw level where they apply padding space between frame and background edge foreground_inset space between background and foreground edge spacing space between segmented foreground elements (e.g. combo points) font, size, outline args for FontString:SetFont() respectively justifyV, justifyH LEFT/CENTER/RIGHT, TOP/MIDDLE/BOTTOM SetFrameLayout(): Applies: anchor, parent, anchorTo, x, y width, height, padding, spacing, foreground_inset backdrop, border_color, background_color alpha, alpha_ooc SetStatusTextures(): Applies: foreground_texture, foreground_color, foreground_blend background_texture, background_color, background_blend Defines: fill_direction, fill_width, fill_height, fill_inset :TranslateX(progress) :TranslateY(progress) :SetFillPoints() SetFontLayout(): Applies: anchor, parent, anchorTo, x, y width, height font, size, outline justifyH, justifyV - ]] local MAJOR, MINOR = "LibFog-1.0", 1 local F, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not F then return end local _G, UIParent, type, unpack, pairs, ipairs, min, abs, tostring, print = _G, UIParent, type, unpack, pairs, ipairs, math.min, math.abs, tostring, print local InCombatLockdown, GetTime, PlaySoundKitID, CreateFrame = InCombatLockdown, GetTime, PlaySoundKitID, CreateFrame local tinsert, wipe, concat = table.insert, table.wipe, table.concat local FADE_OUT_TIME, FADE_IN_TIME = 1, 0.4 --@debug@ local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool local ADDON, scriptargs = ... scriptargs.LibFog = F local print = function(...) if _G.Devian and _G.DevianDB.workspace ~= 1 then --_G.print('Layout', ...) end end --- debug highlighters local namef = function(s) return '|cFFFFFF00' ..tostring(s).. '|r' end -- uiobject targeted function local namet = function(s) return '|cFFFF4400 '..tostring(s).. '|r' end -- region targeted function local valuef = function(s) return '|cFF88FF88'..(s ~= nil and ('"'..tostring(s)..'"') or ('nil'))..'|r' end -- uiobject name local valuet = function(s) return '|cFFAACCAA'..(s ~= nil and ('"'..tostring(s)..'"') or ('nil'))..'|r' end -- string value local valuen = function(s) return '|cFFAADD77' ..(s ~= nil and ('"'..tostring(s)..'"') or ('nil')).. '|r' end -- string enumeration local valued = function(s) return '|cFFFFFFFF' ..(s ~= nil and ('"'..tostring(s)..'"') or ('nil')).. '|r' end -- number --@end-debug@ local GetPrint = function(trace) if trace then return print else return function() end end end --- Layout control metadata local lastdb -- fallback if a table isn't found mid-operation local ui_meta = { beepkit = 15263, -- something to play when debugging } local ui_embeds = { ['Frame'] = 'SetFrameLayout', ['Texture'] = 'SetTextureLayout', ['Font'] = 'SetFontLayout', } --- Resolve a parent object from varying depths -- @param self target object -- @parent string/number name of global frame or number of GetParent() hops to make -- @childKey index key to retrieve from the resolved parent object local function ParentValue(self, parent, childKey) local print = GetPrint(self.trace) local relativeTo = parent if type(parent) == 'number' then print(cWord('* Parent Trace:'), cNum(parent), cKey(self:GetName())) relativeTo = self:GetParent() for i = 2, parent do if relativeTo.GetParent and relativeTo:GetParent() ~= UIParent then --@debug@ print(' ', 'parent =', relativeTo:GetName()) --@end-debug local next = relativeTo:GetParent() relativeTo = next else --@debug@ print(' ',cWord(self:GetName()), 'parent =', cWord(parent)) --@debug-end@ end end end -- This allows us to call for an immediate sub-frame and still get a usable value if it's not there if childKey and relativeTo[childKey] then return relativeTo[childKey] end return relativeTo end --- Animations F.animate_regions = {} setmetatable(F.animate_regions, { __newindex = function (t,k,v) rawset(t,k,v) v.animationID = k F.SetAnimationGroup(v) end }) --- Constructs the generic status frame function F:SetFrameLayout(c) local print = GetPrint(c.trace) self.trace = c.trace or self.trace self.db = c self.labels = {} self.name = self:GetName() self.combat = InCombatLockdown() self:SetPoint(c.anchor, c.parent, c.anchorTo, c.x, c.y) self:SetSize(c.width, c.height) self:SetFrameStrata(c.strata) self.throttle_rate = 0.010 self.throttle_point = GetTime() if c.backdrop then c.backdrop.edgeSize = c.padding*4 self:SetBackdrop(c.backdrop) end if c.background_color and c.border_color then self:SetBackdropColor(unpack(c.background_color)) self:SetBackdropBorderColor(unpack(c.border_color)) end --@debug@ print(namef('SetFrameLayout'),'(', valuet(self:GetName()),')') print(cText(' dimensions:'), cNum(c.width), 'by', cNum(c.height), '::', c.x, c.y, c.anchor, c.anchorTo, c.parent) --@end-debug@ self.width = c.width self.height = c.height self.foreground_inset = c.foreground_inset self.padding = c.padding self.spacing = c.spacing self.alpha = c.alpha self.combatFade = c.combatFade self.alpha_fade_in = c.alpha_fade_in or c.alpha_fade self.alpha_fade_out = c.alpha_fade_out or c.alpha_fade print(' fade on combat =', self.combatFade) for _, type in ipairs({'alpha', 'alpha_ooc'}) do self[type] = c[type] --_G.print('DB', self:GetName(), type, self[type]) for _, subtype in ipairs({'_passive', '_active'}) do self[type..subtype] = c[type..subtype] or self[type] --_G.print('DB', self:GetName(), type..subtype, self[type..subtype]) for _, subsubtype in ipairs({'_empty', '_half', '_full'}) do self[type..subtype..subsubtype] = c[type..subtype..subsubtype] or self[type..subtype] --_G.print('DB', self:GetName(), type..subtype..subsubtype, self[type..subtype..subsubtype]) self[type..subsubtype] = c[type..subsubtype] or self[type..subtype] --_G.print('DB', self:GetName(), type..subsubtype, self[type..subsubtype]) end end end self.UpdateAlpha = F.UpdateAlpha --if c.combatFade then self.faderID = #F.animate_regions+1 F.animate_regions[#F.animate_regions+1] = self print(cText(' animation target ID #'), cNum(self.faderID)) --end self:UpdateAlpha(InCombatLockdown()) if self.lefttext then print(' auto-lefttext') F.SetFontLayout(self.lefttext, c.lefttext or c) end if self.righttext then print(' auto-righttext') F.SetFontLayout(self.righttext, c.righttext or c) end end --- Seeds basic animations, else a template can be specified by the frame data function F:SetAnimationGroup(group) local print = GetPrint(self.trace) group = group or self.animationClass or nil --@debug@ if not group then print(' |cFFFF44AAseeding debug animations', self:GetName()) self.__flash = self:CreateAnimationGroup(self:GetName()..'Flasher') self.__flash:SetToFinalAlpha(true) local fade1 = self.__flash:CreateAnimation('Alpha') fade1:SetChange(-1) fade1:SetDuration(.6) fade1:SetOrder(1) local fade2 = self.__flash:CreateAnimation('Alpha') fade2:SetChange(1) fade2:SetDuration(.6) fade2:SetOrder(2) fade2:SetEndDelay(.6) --@debug@ self.__flash.fade1 = fade1 self.__flash.fade2 = fade2 self.__flash:SetLooping('NONE') self.__flash:SetScript('OnFinished', function() print(self:GetName(), '[>>>] Done animating flash.') self.flashing = nil end)--@end-debug@ self.Flash = F.Flash self.__fade = self:CreateAnimationGroup(self:GetName()..'Fader') self.__fade:SetToFinalAlpha(true) self.__fade:SetScript('OnFinished', function() print(self:GetName(), '[>>>] Done animating fade.') self.fading = nil local a = self.__flash.fade1:GetToAlpha() --self:SetAlpha(a) if a == 0 and not self.__fade.noHide then self:Hide() end if self.__fade.queuedFade then print('[>>>] ', cWord(self:GetName())..'.'..cKey('__fade:'), 'starting queued fade') local fadeTo, fadeDuration, noHide = unpack(self.__fade.queuedFade) self.__fade.queuedFade = nil self:Fade(fadeTo, fadeDuration, noHide) end end) self.Fade = F.Fade end --@end-debug@ if not self.animationID then tinsert(F.animate_regions, self) -- uses rawset, so won't death loop self.animationID = #F.animate_regions end end function F:Flash(duration, peak, valley, holdUp, holdDown) local print = GetPrint(self.trace) local fl = self.__flash print('[>>>]', self:GetName(), duration, peak, valley, holdUp, holdDown) fl.fade1:SetFromAlpha(valley) fl.fade1:SetToAlpha(peak) fl.fade1:SetDuration(duration) fl.fade1:SetEndDelay(holdUp) fl.fade2:SetFromAlpha(peak) fl.fade2:SetToAlpha(valley) fl.fade2:SetDuration(duration) fl.fade2:SetEndDelay(2) self.flashing = true fl:Play() end --- Fade to a value; fading to 0 will hide the frame function F:Fade(duration, fadeTo, noHide) print('|cFFFF6600[>>>]', cText('Fade('), self:GetName(), cText(')')) local fader = self.__fade local fade1 = self.__flash.fade1 if fader:IsPlaying() then self.__fade.queuedFade = {duration, fadeTo, noHide } print(' ', cText('playing:'), cNum(fader:GetDuration())..'s', cNum(fade1:GetToAlpha())) print(' ', cPink('queued {'), cNum(duration)..'s', cNum(self:GetAlpha()), 'to', cNum(fadeTo), '}') return else print(' ', cNum('starting {'), cNum(duration), cNum(self:GetAlpha()), 'to', cNum(fadeTo), '}') end fade1:SetParent(fader) fade1:SetFromAlpha(self:GetAlpha()) fade1:SetToAlpha(fadeTo) fade1:SetDuration(duration) fade1:SetOrder(1) self.__fade.noHide = noHide self.fading = true fader:Play() end function F:Beep() if self.quiet then return end PlaySoundKitID(F.beepkit) -- random anub'rhekan sounds end --- Defines the corners used in filling operations local directionBase = { ['LEFT'] = 'TOPRIGHT', ['RIGHT'] = 'TOPLEFT', ['UP'] = 'BOTTOMLEFT', ['DOWN'] = 'TOPLEFT' } local directionPeak ={ ['LEFT'] = 'BOTTOMLEFT', ['RIGHT'] = 'BOTTOMRIGHT', ['UP'] = 'TOPRIGHT', ['DOWN'] = 'BOTTOMRIGHT', } local directionPeakTo = { ['LEFT'] = 'BOTTOMRIGHT', ['RIGHT'] = 'BOTTOMLEFT', ['UP'] = 'BOTTOMRIGHT', ['DOWN'] = 'TOPRIGHT' } local anchorInverse = {['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['TOP'] = 'BOTTOM', ['BOTTOM'] = 'TOP' } --- Directional coefficients for corner positions -- [1] = end X, [2] = end Y, [3] = base X, [4] = base Y local directionCoord = { ['LEFT'] = {-1, 0, -1, -1}, ['RIGHT'] = { 1, 0, 1, -1}, ['UP'] = { 0, 1, 1, 1}, ['DOWN'] = { 0, -1, 1, -1}, ['CENTER'] = {.5, .5, 1, 1} } local paddingScale = { ['UP'] = 1, ['DOWN'] = -1, ['LEFT'] = -1, ['RIGHT'] = 1, } local embedScale = { ['LEFT'] = {1, false}, ['RIGHT'] = {-1, false}, ['TOP'] = {false, -1}, ['BOTTOM'] = {false, 1} } --- Determines the correct relative X offset for a given progress ratio --- x = 0 + padding + spacing + i, where i = {embedded | icon_size +spacing} -- Factors padding and spacing parameters, including icon embedding dimensions. -- @param self frame on which the foreground/background textures and config data exist -- @param ratio progess from 0 to 1; 0 returns the starting corner coordinate, 1 returns end corner -- @param scale overrides the pixel fill length, with starting corner used as scaling origin local TranslateX = function(self, ratio, scale) if not scale then scale = self.fill_width end if self.fill_inverse then ratio = 1 - ratio end ----_G.print('Update', 'dx', self.fill_x) local x = scale * ratio * directionCoord[self.fill_direction][1] return min(x, scale) + self.fill_x end --- Determines the correct relative Y offset for a given progress ratio -- Factors padding and spacing parameters, including icon embedding dimensions. -- @param self frame on which the foreground/background textures and config data exist -- @param ratio progess from 0 to 1; 0 returns the starting corner coordinate, 1 returns end corner -- @param scale overrides the pixel fill length, with starting corner used as scaling origin local TranslateY = function(self, ratio, scale) if not scale then scale = self.fill_height end if self.fill_inverse then ratio = 1 - ratio end --_G.print('Update', 'dy', self.fill_y) -- (height of bar offset by the size of any overlapping element) * progress ratio, offset by the size of any overlapping embed + inset local y = scale * ratio * directionCoord[self.fill_direction][2] - self.foreground_inset return min(y, scale) + self.fill_y end local SetProgress = function(self, progress, scaleX, scaleY) --[[_G.print('Update', cText(self:GetName()), "\n d:", progress, 'dX:', directionCoord[self.fill_direction][1], 'dY:', directionCoord[self.fill_direction][2], 'dI:', self.fill_inverse, "\n peak:", self.fill_anchor, self.fill_anchorTo, TranslateX(self, progress), TranslateY(self,progress)) --]] self.foreground:SetPoint(self.fill_anchor, self.background, self.fill_anchorTo, TranslateX(self, progress, scaleX), TranslateY(self, progress, scaleY)) end --- Assigns textures to the generic foreground background bar regions -- Called as F.SetStatusTextures(MyFrame, config pointer) -- foreground_inset - number of pixels by which the foreground edges occlude the background (basically always negative) -- padding - number of pixels between the background edge and frame edge (basically always positive) function F:SetStatusTextures(c) local print = GetPrint(self.trace) if c == nil then c = self.db or lastdb if not c then error('No config table found') end end local relativeTo = ParentValue(self, c.parent, c.parentKey) self.fill_direction = c.fill_direction or 'RIGHT' self.fill_inset = c.padding - c.foreground_inset -- foreground edge / frame edge self.fill_width = self.width - self.fill_inset*2 -- foreground left / right edges self.fill_height = self.height - self.fill_inset*2 -- " top / bottom " self.fill_inverse = c.fill_inverse self.fill_x, self.fill_y = 0, 0 self.fill_insets = { LEFT = self.fill_inset, TOP = self.fill_inset, BOTTOM = self.fill_inset, RIGHT = self.fill_inset } -- create filling points self.fill_base = directionBase[self.fill_direction] self.fill_anchor = directionPeak[self.fill_direction] self.fill_anchorTo = directionPeakTo[self.fill_direction] print(" foreground:", self.fill_base, self.fill_base, TranslateX(self, 0), TranslateY(self, 0)) print(" foreground fill:", self.fill_anchor, self.fill_anchorTo) -- calculate icon embed if self.icon and self.icon.embedded then print(cText('#### EMBED ####')) -- change anchor point so the icon is inside self.icon.anchor = self.icon.anchorTo print(' * Icon anchor:' , cText(self.icon.anchor), 'to', cText(self.icon.anchorTo)) print(' * Fill start:', cText(self.fill_base)) local coordSet = {nil, nil} local baseSet = {nil, nil } local endSet = {nil, nil} for dir, coords in pairs(embedScale) do if self.icon.anchor:match(dir) then print(' xtrans { matches', dir, 'include {', coords[1], coords[2], '}') if not coordSet[1] then coordSet[1] = coords[1] end if not coordSet[2] then coordSet[2] = coords[2] end -- the embedding position can overlap either corner if self.fill_base:match(dir) then print(' base corner also matches') if not baseSet[1] then baseSet[1] = coords[1] end if not baseSet[2] then baseSet[2] = coords[2] end else if not endSet[1] then endSet[1] = coords[1] end if not endSet[2] then endSet[2] = coords[2] end end end end -- make sure there are values if none of them matched at all for some reason coordSet = {coordSet[1] or 0, coordSet[2] or 0} baseSet = {baseSet[1] or 0, baseSet[2] or 0 } -- needs to produce a negative number endSet = {endSet[1] or 0, endSet[2] or 0 } print(' == xtrans push =', unpack(coordSet)) print(' == fbase delta =', unpack(baseSet)) print(' == ftail delta =', unpack(endSet)) -- determine the foreground displacement self.icon_dx = (min(self.fill_width, self.fill_height) + self.spacing) self.icon_dy = (min(self.fill_width, self.fill_height) + self.spacing) print(' * Foreground compression:', cNum(self.icon_dx)) self.icon_size = self.icon.size self.icon_x = self.padding * baseSet[1] - (self.icon.size - self.icon_dx) self.icon_y = self.padding * baseSet[2] - (self.icon.size - self.icon_dy) print(' * Icon dims:' , cNum(self.icon_size), ' offset:', cNum(self.icon_dx)) local ofi = self.fill_insets[self.fill_direction] print(' * Fill inset('..cWord(self.fill_direction)..') from', cNum(ofi), 'to', cNum(self.fill_insets[self.fill_direction])) -- used to place the starting corner self.fill_x = (self.icon_dx) * baseSet[1] self.fill_y = (self.icon_dy) * baseSet[2] print(' * fill offset dX:', self.fill_x) print(' * fill offset dY:', self.fill_y) -- amount taken off of fill scale, subtract spacing self.icon_dx_cut = abs(self.icon_dx * -baseSet[1]) self.icon_dy_cut = abs(self.icon_dy * -baseSet[2]) local ofw, ofh = self.fill_width, self.fill_height self.fill_width = self.fill_width - self.icon_dx_cut self.fill_height = self.fill_height - self.icon_dy_cut print(' * Scale dX:', self.icon_dx_cut, cNum(ofw), 'to', cNum(self.fill_width)) print(' * Scale dY:', self.icon_dy_cut, cNum(ofh), 'to', cNum(self.fill_height)) self.icon:ClearAllPoints() self.icon:SetPoint(self.icon.anchor, self, self.icon.anchorTo, self.icon_x, self.padding * coordSet[2]) self.icon:SetSize(self.icon_size, self.icon_size) end --@debug@ print(namet('SetStatusTextures'),'(', valuef(self:GetName()), ')') 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, '+') print(' ', valuen(concat(c.background_color,', ')),valuet(c.background_texture), valuen(concat(c.foreground_color,', ')), valuet(c.foreground_texture)) print(' background:', self.padding, self.padding, 'BOTTOMLEFT', 'BOTTOMLEFT' , '::', -self.padding, -self.padding, 'TOPRIGHT', 'TOPRIGHT') --@end-debug@ self.background:ClearAllPoints() self.background:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', self.padding, self.padding) self.background:SetPoint('TOPRIGHT', self, 'TOPRIGHT', -self.padding, -self.padding) if c.background_texture ~= '' and c.background_texture ~= nil then self.background:SetTexture(c.background_texture) self.background:SetVertexColor(unpack(c.background_color)) else self.background:SetTexture(unpack(c.background_color)) end self.background:SetBlendMode(c.background_blend) if c.foreground_texture ~= '' and c.foreground_texture ~= nil then self.foreground:SetTexture(c.foreground_texture) self.foreground:SetVertexColor(unpack(c.foreground_color)) else self.foreground:SetTexture(unpack(c.foreground_color)) end self.foreground:SetBlendMode(c.foreground_blend) self.foreground:ClearAllPoints() local dx = (directionCoord[self.fill_direction][3] * -self.foreground_inset) + self.fill_x local dy = (directionCoord[self.fill_direction][4] * -self.foreground_inset) + self.fill_y print(' foreground base:', cNum(dx), cNum(dy)) self.foreground:SetPoint(self.fill_base, self.background, self.fill_base, dx, dy) SetProgress(self, 1) self.TranslateX = TranslateX self.TranslateY = TranslateY self.SetFillPoints = SetFillPoints self.SetProgress = SetProgress end --- Sets properties for a generated FontString -- Takes the FontString object as a self, and applies config values. -- In particalur, the anchor parent is derived from either a fixed number of GetParent() or global name -- @usage Region:SetFontLayout([table]) function F:SetFontLayout (c) local print = GetPrint(self.trace) if c == nil then c = lastdb if not c then error('No config table found') end end local relativeTo = ParentValue(self, c.parent, c.parentKey) --@debug@ print(namet('FontLayout'),'(', valuet(self:GetName()), ')', valuet(c.font), valuet(c.size), valuet(c.outline)) print(' ', valuen(c.anchor or 'CENTER'), relativeTo:GetName(), valuen(c.anchorTo or 'CENTER'), valued(c.x or 0), valued(c.y or 0)) --@end-debug@ self:SetPoint( c.anchor or 'CENTER', relativeTo, c.anchorTo or 'CENTER', c.x or 0, c.y or 0) self:SetSize( c.width or relativeTo:GetWidth(), c.height or relativeTo:GetHeight()) self:SetFont( c.font, c.size, c.outline) self:SetJustifyH(c.justifyH or 'CENTER') self:SetJustifyV(c.justifyV or 'MIDDLE') self:SetTextColor(unpack(c.text_color or {1,1,1,1})) end --- For setting up widget pieces function F:SetTextureLayout(c) local print = GetPrint(self.trace) if c == nil then c = lastdb if not c then error('No config table found') end end local relativeTo = ParentValue(self, c.parent, c.parentKey) self.size = c.size self.width = c.width self.height = c.height self.x = c.x self.y = c.y self.embedded = c.embedded self.anchor = c.anchor self.anchorTo = c.anchorTo self:SetPoint(c.anchor, relativeTo, c.anchorTo, c.x, c.y) self:SetSize(c.size or c.width, c.size or c.height) self:SetAlpha(c.alpha) self:SetDesaturated(c.desaturated or false) print('|cFF00FFFFSetTextureLayout(|r', self:GetName(), '|cFF00FFFF)|r') print(' ', c.anchor, relativeTo, c.anchorT, c.x, c.v) if c.combatFade and not (relativeTo.faderID and F.animate_regions[relativeTo.faderID]) then tinsert(F.animate_regions, self) self.faderID = #F.animate_regions --@debug@ print('register fadeable texture #'..self.faderID) --@end-debug@ end end local alphaSubType = { [1] = '_passive', [2] = '_active' } local alphaFillType = { [1] = '_empty', [2] = '_half', [3] = '_full', } function F:UpdateAlpha(inCombat, displayState, fillState) local print = function() end print(cWord('UpdateAlpha(')..self:GetName()..cWord(')')) local alphaType = inCombat and 'alpha' or 'alpha_ooc' local alphaDuration = inCombat and 'alpha_fade_in' or 'alpha_fade_out' local displayState = displayState or self.displayState or nil local fillState = fillState or self.fillState or nil local alphaSubType = '' if displayState then alphaSubType = (displayState == 1) and '_passive' or ((displayState == 2) and '_active' or '' ) end local alphaFillType = '' if fillState then alphaFillType = (fillState == 1) and '_half' or ((fillState == 2) and '_full' or '_empty') end local fadeTo = self[alphaType..alphaSubType..alphaFillType] local fadeDuration = self[alphaDuration] or 0 print(' alphaKey:', cWord(alphaType..alphaSubType..alphaFillType)) print(' alphaTo:', cNum(fadeTo), 'duration:', cNum(fadeDuration)) if self:IsVisible() and fadeDuration ~= 0 then self:Fade(fadeDuration, fadeTo or (inCombat and 1 or 0.5), true) print(' |cFFFFFF00 :Fade()|r', 'dur='..cNum(fadeDuration), cNum(fadeTo), cWord(self:GetName())) else self:SetAlpha(fadeTo) print(' |cFF00FF00 :SetAlpha('..fadeTo..')|r', cText(self:GetName())) end end --- Sets an OnUpdate within a time-throttled wrapper -- throttle rate should be slightly smaller than 1/average frame rate function F:SetFrameScript(updateFunc, showFunc, hideFunc, ...) local print = GetPrint(self.trace) if not self.__oldscripts then self.__oldscripts = {} end self:SetScript('OnUpdate', nil) -- clear any scripts self:SetSCript('OnUpdate', function(self) if GetTime() < self.throttle_time then return end self.throttle_time = self.throttle_time + self.throttle_rate updateFunc(self) end) -- put the new function in its place local changeSet = { { self.__oldscripts,onUpdate = self:GetScript('OnUpdate') }, } if showFunc then tinsert(changeSet, {onShow = self:GetScript('OnShow')}) self:SetScript('OnShow', showFunc) end if hideFunc then tinsert(changeSet, {onHide = self:GetScript('OnShow')}) self:SetScript('OnHide', hideFunc) end end --- Embed function F:Embed(object) print('Doing embed') for k, v in pairs(ui_embeds) do print('embedding Set'..k..'Layout') object['Set'..k..'Layout'] = self[v] end object.SetStatusTextures = self.SetStatusTextures --- map a generic layout method if embedded into a frame object if object.GetObjectType and ui_embeds[object.GetObjectType()] then if ui_embeds[object.GetObjectType()] then object.SetLayout = ui_embeds[object.GetObjectType()] end end end