diff BuffFrame/BuffButton.lua @ 47:1a322b92dbfa

file cleanup
author Nenue
date Thu, 28 Apr 2016 05:54:21 -0400
parents BuffButton.lua@5301c68f28d8
children 9837069e366a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BuffFrame/BuffButton.lua	Thu Apr 28 05:54:21 2016 -0400
@@ -0,0 +1,441 @@
+--- Actual BlizzUI modifications are applied here
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 3/12/2016 12:47 AM
+local MODULE = 'BuffFrame'
+local _, A = ...
+local B, _G = A.frame, _G
+local type, unpack, select, pairs, ipairs = _G.type, _G.unpack, _G.select, _G.pairs, _G.ipairs
+local min, ceil, mod, tonumber, tostring = _G.min, _G.ceil, _G.mod, _G.tonumber, _G.tostring
+local floor, wipe, max = _G.math.floor, _G.table.wipe, _G.math.max
+local CreateFrame, IsInGroup, GetCVarBool = _G.CreateFrame, _G.IsInGroup, _G.GetCVarBool
+local BuffFrame, ConsolidatedBuffs = _G.BuffFrame, _G.ConsolidatedBuffs
+local print, gprint, aprint, fprint = B.print('Buff'), B.print('SetGuides'), B.print('SetAnchors'), B.fprint
+local displays, anchors, guides, decors, positioned, drawn, zoom = B.displays, {}, {}, {}, {}, {}, {}
+local UnitAura, UnitName, RegisterStateDriver = _G.UnitAura, _G.UnitName, _G.RegisterStateDriver
+
+local M = B:RegisterModule(MODULE)
+
+M.GetBuffZoom = function(buffName)
+  local zoom = tonumber(B.displays[buffName].conf['Zoom']) / 100 / 2
+  local zoomL, zoomU, zoomR, zoomD = zoom, zoom, 1-zoom, 1-zoom
+  print(buffName, zoom)
+  return function(self, ...)
+    if select('#',...) == 4 then
+      zoomL, zoomR, zoomU, zoomD = ...
+    end
+    self:SetTexCoord(zoomL, zoomR, zoomU, zoomD)
+    return zoomL, zoomR, zoomU, zoomD
+  end
+end
+
+
+
+M.UpdateButtonAlpha = function(self)
+  if not self.parent.timeLeft or not self:IsVisible() then
+    self:SetScript('OnUpdate', nil)
+    return
+  end
+
+  if self.parent.timeLeft < _G.BUFF_WARNING_TIME then
+    self:SetAlpha(BuffFrame.BuffAlphaValue)
+  else
+    self:SetAlpha(1)
+  end
+end
+
+--- Called infrequently to align stencil frames
+local refreshCount = 0
+M.UpdateGuideFrames = function(buffName)
+  refreshCount = refreshCount + 1
+  local print = fprint()
+
+
+  local anchor = anchors[buffName]
+  local c, g, d = displays[buffName].conf, guides[buffName], decors[buffName]
+  local perRow = c['PerRow']
+  local buffSpacing, buffSize, buffBorder, buffDurationSize, buffCountSize, relativeX, relativeY = c['Spacing'], c['Size'], c['Border'], c['DurationSize'], c['CountSize'], c['RelativeX'], c['RelativeY']
+  local consolidated = (anchors[buffName].contains and IsInGroup())
+  local consolidatedPosition = (consolidated and anchors[buffName].containPosition or 0)
+
+
+  print('|cFF00FF00Setting Guides ('..refreshCount..'):|r', buffName, 'user max:',c['Max'], 'hard max:', displays[buffName].maxIcons)
+
+  local buffMax = min(c['Max'], displays[buffName].maxIcons)
+  local anchorFrom, anchorTo = c.Point[1], c.Point[2]
+  anchor.Zoom = M.GetBuffZoom(buffName)
+
+
+
+  if consolidated then
+    buffMax = buffMax + 1
+  end
+
+  local legend = {}
+  legend.r, legend.g, legend.b, legend.a = unpack(displays[buffName].legendColor)
+  local horizFrom = (relativeX < 0) and 'RIGHT' or 'LEFT'
+  local horizTo = (relativeX < 0) and 'LEFT' or 'RIGHT'
+  local vertFrom = (relativeY < 0) and 'TOP' or 'BOTTOM'
+  local vertTo = (relativeY < 0) and 'BOTTOM' or 'TOP'
+  local previous, up
+  local bottom_extent = 0
+  for i = 1, buffMax do
+    print('update idx', i)
+    if not g[i] then
+      g[i] = CreateFrame('Frame', buffName..'Guide'..i, anchor, displays[buffName].template or 'VeneerGuideTemplate')
+      RegisterStateDriver(g[i], "visibility", "[petbattle] [vehicleui] hide; show")
+    end
+
+    local guide = g[i]
+
+    local row = ceil(i / perRow)
+    local  col = mod(i, perRow)
+    if col == 0 then
+      col = perRow
+    end
+
+    guide.previous = previous
+    guide.up = up
+    local x, y, parent = 0, 0, anchor
+    if i == 1 then
+      parent = anchor
+      up = guide
+    elseif col == 1 then
+      parent = g[i-perRow]
+      y = (buffSpacing + bottom_extent)  * relativeY
+      up = guide
+      anchorFrom = vertFrom .. horizFrom
+      anchorTo = vertFrom .. horizFrom
+      bottom_extent = 0
+    else
+      parent = g[i-1]
+      x = buffSpacing * relativeX
+      anchorFrom = vertFrom .. horizFrom
+      anchorTo = vertFrom .. horizTo
+    end
+    previous = guide
+    guide.parent = parent
+
+    ---------------------------------
+    -- Positioning layer
+    if i ~= consolidatedPosition or not consolidated then
+      guide:SetSize(buffSize, buffSize + buffDurationSize)
+      -- RaidBuffTray will fix the sizing
+    end
+    bottom_extent = max(bottom_extent, guide:GetHeight())
+
+    guide.info = {} -- UnitAura cache
+
+    if i == consolidatedPosition then
+      guide.legend:SetTexture(1,1,0,0.5)
+    else
+      guide.legend:SetTexture(legend.r, legend.g, legend.b, legend.a)
+    end
+
+    guide.idText:SetText(i) -- needs to reflect the current position
+
+    guide:ClearAllPoints()
+    guide:SetPoint(anchorFrom, parent, anchorTo, x, y)
+    print(anchorFrom, parent, anchorTo, x, y)
+
+    guide.icon:SetSize(buffSize - buffBorder * 2, buffSize - buffBorder * 2)
+    guide.icon:ClearAllPoints()
+    guide.icon:SetPoint('TOPLEFT', guide, 'TOPLEFT', buffBorder, -buffBorder )
+
+    local anchorTo, anchorFrom, x, y = unpack(c.DurationPoint)
+    guide.duration:ClearAllPoints()
+    guide.duration:SetPoint(anchorTo, guide, anchorFrom, x, y)
+    --guide.duration:SetSize(buffSize, buffDurationSize)
+    print('  duration ->', anchorFrom, anchorTo, x, y)
+
+    local anchorTo, anchorFrom, x, y = unpack(c.CountPoint)
+    guide.count:ClearAllPoints()
+    guide.count:SetPoint(anchorTo, guide.icon, anchorFrom, x, y)
+    --guide.count:SetSize(buffSize, c.CountSize)
+    print('  count    ->', anchorFrom, anchorTo, x, y)
+
+    -----------------------------------
+    -- Background decorations layer
+    if not d[i] then
+      d[i] = CreateFrame('Frame', buffName..i..'Decor', _G.UIParent, 'VeneerDecorTemplate')
+      -- todo: sort out a way to fix this without creating taint issues
+      RegisterStateDriver(d[i], "visibility", "[petbattle] [vehicleui] hide")
+    end
+
+    d[i]:SetPoint('BOTTOMLEFT', guide.icon, 'BOTTOMLEFT', -buffBorder, -buffBorder)
+    d[i]:SetPoint('TOPRIGHT', guide.icon, 'TOPRIGHT', buffBorder, buffBorder)
+
+
+    guide:Show()
+    B.SetConfigLayers(guide)
+  end
+
+
+  if #guides[buffName] > buffMax then
+    local lim = #guides[buffName]
+    for i = buffMax+1, lim do
+
+      local g = guides[buffName][i]
+      if g:IsVisible() then
+        print('cleaning up #', i, buffName)
+        g:Hide()
+        B.RemoveConfigLayers(g)
+      end
+
+    end
+  end
+
+  anchor.last = previous
+  anchor.up = up
+
+  print(anchor:GetName(), anchor:GetSize())
+end
+
+M.UpdateButtonPositions = function(buffName, auraType)
+  local print = fprint()
+  local c = auraType.conf
+  local numBuffs = 0
+  local actualIcons = auraType.actualIcons()
+  local maxIcons = auraType.maxIcons
+  local anchor = anchors[buffName]
+  local buffMax = c['Max']
+  local consolidated = (anchor.contains and IsInGroup())
+  local consolidatedPosition = (consolidated and anchor.containPosition or 0)
+
+  for k,v in pairs(decors[buffName]) do
+    print(v)
+  end
+
+  if consolidated then
+    decors[buffName][1]:Hide()
+    numBuffs = numBuffs + 1
+    buffMax = buffMax + 1
+  end
+
+  print(' ', 'frame count:', auraType.actualIcons(), 'hardmax:', maxIcons)
+  if auraType.actualIcons() > 0 then
+    for i = 1, actualIcons do
+
+
+      local buff = _G[buffName .. i]
+      local buffIcon = _G[buffName .. i .. 'Icon']
+      local buffBorder = c['Border']
+      local buffDuration = _G[buffName .. i .. 'Duration']
+      local buffCount = _G[buffName .. i .. 'Count']
+      local buffDurationSize = c['DurationSize']
+      local debuffBorder = _G[buffName .. i .. 'Border']
+
+
+      if buff and not buff.consolidated then
+        numBuffs = numBuffs + 1
+        local guide = guides[buffName][numBuffs]
+        local deco = decors[buffName][numBuffs]
+        if numBuffs > buffMax then
+          -- if a limit is reached, start hiding
+          if guide then
+            guide.info = nil
+          end
+          if deco then
+            deco:Hide()
+          end
+          buff:Hide()
+        else
+          local buffData = guide.info
+          buffData.name,  buffData.rank,  buffData.icon,  buffData.count,  buffData.dispelType,  buffData.duration,  buffData.expires,  buffData.caster,  buffData.isStealable,  buffData.shouldConsolidate,  buffData.spellID,  buffData.canApplyAura,  buffData.isBossDebuff,  buffData.value1,  buffData.value2,  buffData.value3
+          = UnitAura(buff.unit, buff:GetID(), nil, buff.filters)
+
+          if guide.caster and buffData.caster then
+            if (buffData.caster ~= 'player' or c.ShowSelfCast) then
+              guide.caster:SetText(UnitName(buffData.caster))
+            else
+              guide.caster:SetText(nil)
+            end
+          end
+
+
+          print(numBuffs, i, buff:GetName(), buff:GetID(), decors[buffName][numBuffs]:GetName())
+
+          buff:SetAllPoints(guide)
+          buffIcon:ClearAllPoints()
+          buffIcon:SetPoint('TOPLEFT', guide.icon, 'TOPLEFT', 0, 0)
+          buffIcon:SetPoint('BOTTOMRIGHT', guide.icon, 'BOTTOMRIGHT', 0, 0)
+
+          deco.parent = buff
+          -- make sure so they aren't re-shown in pet battle
+          if not C_PetBattles.IsInBattle() then
+            deco:Show()
+            deco:SetAlpha(1)
+          end
+
+          if debuffBorder then
+            deco.background:SetTexture(debuffBorder:GetVertexColor())
+            debuffBorder:Hide()
+          else
+            if guide.info.caster == 'player' then
+              print(guide.info.caster)
+              deco.background:SetTexture(unpack(c.PlayerColor))
+            elseif buffData.isBossDebuff then
+              print(guide.info.isBossDebuff)
+              deco.background:SetTexture(unpack(c.BossColor))
+            else
+              print(guide.info.caster)
+              deco.background:SetTexture(unpack(c.Color))
+            end
+          end
+
+
+          buffDuration:ClearAllPoints()
+          local from, to = unpack(c.DurationPoint)
+          buffDuration:SetPoint(from, guide.duration, to)
+          buffDuration:SetText('WHAT')
+
+          if buff.timeLeft and c.WarningFade then
+            deco:SetScript('OnUpdate', M.UpdateButtonAlpha)
+          else
+            deco:SetScript('OnUpdate', nil)
+            deco:SetAlpha(1.0)
+          end
+
+          buffCount:ClearAllPoints()
+          local from, to = unpack(c.CountPoint)
+          buffCount:SetPoint(from, guide.count, to)
+
+          if not drawn[buffName][numBuffs] then
+            anchors[buffName].Zoom(buffIcon)
+
+            if buffDuration then
+              local font = buffDuration:GetFont()
+              buffDuration:SetFont(font, c.DurationSize, 'OUTLINE')
+
+            end
+
+            if buffCount then
+              local font = buffCount:GetFont()
+              buffCount:SetFont(font, c.CountSize, 'OUTLINE')
+            end
+            drawn[buffName][numBuffs] = true
+          end
+        end
+      end
+
+    end
+  end
+  -- clear any outliers
+  for i = numBuffs+1, buffMax do
+    if guides[buffName][i].caster then
+    guides[buffName][i].caster:SetText(nil)
+    end
+    --if not decors[buffName][i].parent or
+
+    decors[buffName][i].parent = nil
+    decors[buffName][i]:SetAlpha(1.0)
+    decors[buffName][i]:SetScript('OnUpdate', nil)
+    decors[buffName][i]:Hide()
+  end
+
+  -- parametric occlusion data for compacted anchor points
+  if numBuffs == 0 then
+    anchor.cutout_X = 0
+    anchor.cutout_Y = 0
+    anchor.outer_X = 0
+    anchor.outer_Y = 0
+  elseif numBuffs <= buffMax then
+    local sX, sY = guides[buffName][numBuffs]:GetWidth(), guides[buffName][numBuffs]:GetHeight()
+    local p = c.PerRow
+    local lX = mod(numBuffs, p)
+    local lY = floor(numBuffs / p)
+    local oX = min(numBuffs, c.PerRow)
+    local oY = ceil(numBuffs / p)
+    anchor.cutout_X = lX * sX + lX * c.Spacing -- max clearance to fit alongside the row
+    anchor.cutout_Y = lY * sY + lY * c.Spacing
+    anchor.outer_Y  = oY * sY + oY * c.Spacing -- distance of farthest row
+    anchor.outer_X  = oX * sX + oX * c.Spacing
+
+
+    print('|cFF0088FF', 'inner corner', lX, lY, 'outer corners', oX, oY)
+    print('cutout delta =', anchor.cutout_X, anchor.cutout_Y, 'out of', floor(anchor:GetWidth()), floor(anchor:GetHeight()))
+    print('extent delta =', anchor.outer_X, anchor.outer_Y)
+  else
+    anchor.cutout_X = 0
+    anchor.cutout_Y = 0
+    anchor.outer_X = 0
+    anchor.outer_Y = 0
+  end
+
+  if anchor.attached then
+    M.UpdateAnchorChild(anchor, anchor.attached, anchor.attachmentConf)
+  end
+
+end
+
+M.PostBuffAnchors  = function()
+  local print = fprint()
+  if M.ShowConsolidatedBuffs then
+    M.UpdateRaidBuffs()
+  end
+  for buttonName, auraType in pairs(displays) do
+    print('sending', buttonName, auraType)
+    -- if waiting for anchors
+    if not anchors[buttonName] then
+      return
+    end
+
+    --if positioned[buttonName] == 0 then
+      print('possibly reloaded UI, check positions')
+      M.UpdateGuideFrames(buttonName)
+    --end
+
+    M.UpdateButtonPositions(buttonName, auraType)
+  end
+end
+
+M.UpdateBuffs = function(buttonName, forced)
+  local print = B.fprint(buttonName)
+  local c = displays[buttonName].conf
+  if drawn[buttonName] then
+    wipe(drawn[buttonName])
+  else
+    drawn[buttonName] = {}
+  end
+
+  M.UpdateAnchorFrames(buttonName)
+  M.UpdateGuideFrames(buttonName)
+  M.UpdateButtonPositions(buttonName, displays[buttonName])
+end
+
+--- should only be called from user input
+print('init def')
+function M:OnInitialize ()
+  drawn = B.Abstract(B.displays, 'drawn')
+  -- Lesser extent of guide frames that have been positioned
+  positioned = B.Abstract(B.displays, 'positioned', positioned)
+  -- Backdrop style frame
+  decors = B.Abstract(B.displays, 'decorator', decors)
+  -- Static positioning frames
+  guides = B.Abstract(B.displays, 'guides', guides)
+  -- Anchor points for guides
+  anchors = B.Abstract(B.displays, 'anchor')
+  -- Stored functions for doing icon texture adjustments
+  zoom = B.Abstract(B.displays, 'zoom', zoom)
+
+  B:RegisterUnitEvent("UNIT_AURA", "player", "vehicle")
+  B:RegisterEvent("GROUP_ROSTER_UPDATE")
+  B:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
+  hooksecurefunc("BuffFrame_UpdateAllBuffAnchors", M.PostBuffAnchors)
+  hooksecurefunc("RaidBuffTray_Update", M.UpdateRaidBuffs)
+end
+print('update def')
+function M:OnUpdate ()
+  M.ShowConsolidated = (IsInGroup() and GetCVarBool("consolidateBuffs"))
+  M.ShowMissingBuffs = (IsInGroup() and B.Conf.RaidShowMissing)
+
+  for name, auraType in pairs(displays) do
+    print(name, auraType)
+    M.UpdateBuffs(auraType.buffName, true)
+  end
+
+  M.UpdateAnchorAnchors()
+  M.UpdateRaidBuffs()
+  M.UpdateBuffsTodo()
+end
\ No newline at end of file