Mercurial > wow > buffalo2
diff BuffButton.lua @ 0:3dbcad2b387d
initial push
author | Nenue |
---|---|
date | Wed, 30 Mar 2016 02:24:56 -0400 |
parents | |
children | b0447b382f36 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BuffButton.lua Wed Mar 30 02:24:56 2016 -0400 @@ -0,0 +1,440 @@ +--- 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') + 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