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