Files
2024-01-05 08:41:39 -07:00

361 lines
11 KiB
Lua

local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
--Lua functions
local _G = _G
local unpack, ipairs, pairs = unpack, ipairs, pairs
local gsub, match = string.gsub, string.match
--WoW API / Variables
local InCombatLockdown = InCombatLockdown
local RegisterStateDriver = RegisterStateDriver
local bar = CreateFrame("Frame", "ElvUI_BarTotem", E.UIParent, "SecureHandlerStateTemplate")
bar:SetFrameStrata("LOW")
local SLOT_BORDER_COLORS = {
["summon"] = {r = 0, g = 0, b = 0},
[EARTH_TOTEM_SLOT] = {r = 0.23, g = 0.45, b = 0.13},
[FIRE_TOTEM_SLOT] = {r = 0.58, g = 0.23, b = 0.10},
[WATER_TOTEM_SLOT] = {r = 0.19, g = 0.48, b = 0.60},
[AIR_TOTEM_SLOT] = {r = 0.42, g = 0.18, b = 0.74}
}
local SLOT_EMPTY_TCOORDS = {
[EARTH_TOTEM_SLOT] = {left = 66/128, right = 96/128, top = 3/256, bottom = 33/256},
[FIRE_TOTEM_SLOT] = {left = 67/128, right = 97/128, top = 100/256, bottom = 130/256},
[WATER_TOTEM_SLOT] = {left = 39/128, right = 69/128, top = 209/256, bottom = 239/256},
[AIR_TOTEM_SLOT] = {left = 66/128, right = 96/128, top = 36/256, bottom = 66/256}
}
function AB:MultiCastRecallSpellButton_Update()
if InCombatLockdown() then
AB.NeedsRecallButtonUpdate = true
AB:RegisterEvent('PLAYER_REGEN_ENABLED')
end
end
function AB:MultiCastFlyoutFrameOpenButton_Show(button, type, parent)
local color = type == "page" and SLOT_BORDER_COLORS.summon or SLOT_BORDER_COLORS[parent:GetID()]
button.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
button:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
button:Point("BOTTOM", parent, "TOP")
button.icon:SetRotation(0)
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
button:Point("TOP", parent, "BOTTOM")
button.icon:SetRotation(3.14)
end
end
function AB:MultiCastActionButton_Update(button, _, _, slot)
local color = SLOT_BORDER_COLORS[slot]
if color then
button:SetBackdropBorderColor(color.r, color.g, color.b)
end
if InCombatLockdown() then
AB.NeedsPositionAndSizeBarTotem = true
AB:RegisterEvent('PLAYER_REGEN_ENABLED')
elseif button.slotButton then
button:ClearAllPoints()
button:SetAllPoints(button.slotButton)
end
end
function AB:StyleTotemSlotButton(button, slot)
local color = SLOT_BORDER_COLORS[slot]
if color then
button:SetBackdropBorderColor(color.r, color.g, color.b)
button.ignoreBorderColors = true
end
end
function AB:SkinSummonButton(button)
local name = button:GetName()
local icon = _G[name.."Icon"]
local highlight = _G[name.."Highlight"]
local normal = _G[name.."NormalTexture"]
button:SetTemplate("Default")
button:StyleButton()
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetDrawLayer("ARTWORK")
icon:SetInside(button)
highlight:SetTexture(nil)
normal:SetTexture(nil)
end
function AB:MultiCastFlyoutFrame_ToggleFlyout(frame, type, parent)
frame.top:SetTexture(nil)
frame.middle:SetTexture(nil)
local color = type == "page" and SLOT_BORDER_COLORS.summon or SLOT_BORDER_COLORS[parent:GetID()]
local numButtons = 0
for i, button in ipairs(frame.buttons) do
if not button.isSkinned then
button:SetTemplate("Default")
button:StyleButton()
AB:HookScript(button, "OnEnter", "TotemOnEnter")
AB:HookScript(button, "OnLeave", "TotemOnLeave")
button.icon:SetDrawLayer("ARTWORK")
button.icon:SetInside(button)
bar.buttons[button] = true
button.isSkinned = true
end
if button:IsShown() then
numButtons = numButtons + 1
button:Size(AB.db.barTotem.buttonsize)
button:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
if i == 1 then
button:Point("BOTTOM", parent, "TOP", 0, AB.db.barTotem.flyoutSpacing)
else
button:Point("BOTTOM", frame.buttons[i - 1], "TOP", 0, AB.db.barTotem.flyoutSpacing)
end
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
if i == 1 then
button:Point("TOP", parent, "BOTTOM", 0, -AB.db.barTotem.flyoutSpacing)
else
button:Point("TOP", frame.buttons[i - 1], "BOTTOM", 0, -AB.db.barTotem.flyoutSpacing)
end
end
button:SetBackdropBorderColor(color.r, color.g, color.b)
button.icon:SetTexCoord(unpack(E.TexCoords))
end
end
if type == "slot" then
local tCoords = SLOT_EMPTY_TCOORDS[parent:GetID()]
frame.buttons[1].icon:SetTexCoord(tCoords.left, tCoords.right, tCoords.top, tCoords.bottom)
end
frame.buttons[1]:SetBackdropBorderColor(color.r, color.g, color.b)
MultiCastFlyoutFrameCloseButton.backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
frame:ClearAllPoints()
MultiCastFlyoutFrameCloseButton:ClearAllPoints()
if AB.db.barTotem.flyoutDirection == "UP" then
frame:Point("BOTTOM", parent, "TOP")
MultiCastFlyoutFrameCloseButton:Point("TOP", frame, "TOP")
MultiCastFlyoutFrameCloseButton.icon:SetRotation(3.14)
elseif AB.db.barTotem.flyoutDirection == "DOWN" then
frame:Point("TOP", parent, "BOTTOM")
MultiCastFlyoutFrameCloseButton:Point("BOTTOM", frame, "BOTTOM")
MultiCastFlyoutFrameCloseButton.icon:SetRotation(0)
end
frame:Height(((AB.db.barTotem.buttonsize + AB.db.barTotem.flyoutSpacing) * numButtons) + MultiCastFlyoutFrameCloseButton:GetHeight())
end
function AB:TotemOnEnter()
if bar.mouseover then
E:UIFrameFadeIn(bar, 0.2, bar:GetAlpha(), AB.db.barTotem.alpha)
end
end
function AB:TotemOnLeave()
if bar.mouseover then
E:UIFrameFadeOut(bar, 0.2, bar:GetAlpha(), 0)
end
end
function AB:ShowMultiCastActionBar()
self:PositionAndSizeBarTotem()
end
function AB:PositionAndSizeBarTotem()
if InCombatLockdown() then
AB.NeedsPositionAndSizeBarTotem = true
self:RegisterEvent("PLAYER_REGEN_ENABLED")
return
end
local buttonSpacing = E:Scale(self.db.barTotem.buttonspacing)
local size = E:Scale(self.db.barTotem.buttonsize)
local numActiveSlots = MultiCastActionBarFrame.numActiveSlots
bar:Width((size * (2 + numActiveSlots)) + (buttonSpacing * (2 + numActiveSlots - 1)))
MultiCastActionBarFrame:Width((size * (2 + numActiveSlots)) + (buttonSpacing * (2 + numActiveSlots - 1)))
bar:Height(size + 2)
MultiCastActionBarFrame:Height(size + 2)
bar.db = self.db.barTotem
local point, barAnchor, relativePoint = MultiCastActionBarFrame:GetPoint()
if barAnchor ~= bar or point ~= "BOTTOMLEFT" or relativePoint ~= "BOTTOMLEFT" then
MultiCastActionBarFrame:SetPoint('BOTTOMLEFT', bar, 'BOTTOMLEFT', 0, 0)
end
bar.mouseover = self.db.barTotem.mouseover
if bar.mouseover then
bar:SetAlpha(0)
else
bar:SetAlpha(self.db.barTotem.alpha)
end
local visibility = bar.db.visibility
if visibility and match(visibility, "[\n\r]") then
visibility = gsub(visibility, "[\n\r]","")
end
RegisterStateDriver(bar, "visibility", visibility)
local summonButton = _G.MultiCastSummonSpellButton
summonButton:ClearAllPoints()
summonButton:Size(size)
summonButton:Point("BOTTOMLEFT", E.Border*2, E.Border*2)
for i = 1, numActiveSlots do
local button = _G['MultiCastSlotButton'..i]
local actionButton = _G['MultiCastActionButton'..i]
local lastButton = _G['MultiCastSlotButton'..i - 1]
button:Size(size)
button:ClearAllPoints()
actionButton:SetSize(size, size) -- these need to match for icon trim setting
actionButton:ClearAllPoints()
actionButton:SetAllPoints(actionButton.slotButton)
if i == 1 then
button:Point('LEFT', summonButton, 'RIGHT', buttonSpacing, 0)
else
button:Point('LEFT', lastButton, 'RIGHT', buttonSpacing, 0)
end
end
MultiCastRecallSpellButton:Size(size)
MultiCastFlyoutFrameCloseButton:Width(size)
MultiCastFlyoutFrameOpenButton:Width(size)
end
function AB:CreateTotemBar()
bar:Point("BOTTOM", E.UIParent, "BOTTOM", 0, 250)
bar.buttons = {}
bar.eventFrame = CreateFrame("Frame")
bar.eventFrame:Hide()
bar.eventFrame:SetScript("OnEvent", function(self)
AB:PositionAndSizeBarTotem()
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
end)
local barFrame = _G.MultiCastActionBarFrame
barFrame:SetScript("OnUpdate", nil)
barFrame:SetScript("OnShow", nil)
barFrame:SetScript("OnHide", nil)
barFrame:SetParent(bar)
local closeButton = MultiCastFlyoutFrameCloseButton
closeButton:CreateBackdrop("Default", true, true)
closeButton.backdrop:SetPoint("TOPLEFT", 0, -(E.Border + E.Spacing))
closeButton.backdrop:SetPoint("BOTTOMRIGHT", 0, E.Border + E.Spacing)
closeButton.icon = closeButton:CreateTexture(nil, "ARTWORK")
closeButton.icon:Size(16)
closeButton.icon:SetPoint("CENTER")
closeButton.icon:SetTexture(E.Media.Textures.ArrowUp)
closeButton.normalTexture:SetTexture("")
closeButton:StyleButton()
closeButton.hover:SetInside(closeButton.backdrop)
closeButton.pushed:SetInside(closeButton.backdrop)
bar.buttons[closeButton] = true
local openButton = MultiCastFlyoutFrameOpenButton
openButton:CreateBackdrop("Default", true, true)
openButton.backdrop:SetPoint("TOPLEFT", 0, -(E.Border + E.Spacing))
openButton.backdrop:SetPoint("BOTTOMRIGHT", 0, E.Border + E.Spacing)
openButton.icon = openButton:CreateTexture(nil, "ARTWORK")
openButton.icon:Size(16)
openButton.icon:SetPoint("CENTER")
openButton.icon:SetTexture(E.Media.Textures.ArrowUp)
openButton.normalTexture:SetTexture("")
openButton:StyleButton()
openButton.hover:SetInside(openButton.backdrop)
openButton.pushed:SetInside(openButton.backdrop)
bar.buttons[openButton] = true
self:SkinSummonButton(MultiCastSummonSpellButton)
bar.buttons[MultiCastSummonSpellButton] = true
hooksecurefunc(MultiCastRecallSpellButton, "SetPoint", function(self, point, attachTo, anchorPoint, xOffset, yOffset)
if xOffset ~= AB.db.barTotem.buttonspacing then
if InCombatLockdown() then AB.NeedRecallButtonUpdate = true AB:RegisterEvent("PLAYER_REGEN_ENABLED") return end
self:SetPoint(point, attachTo, anchorPoint, AB.db.barTotem.buttonspacing, yOffset)
end
end)
self:SkinSummonButton(MultiCastRecallSpellButton)
bar.buttons[MultiCastRecallSpellButton] = true
for i = 1, 4 do
local button = _G["MultiCastSlotButton"..i]
button:StyleButton()
button:SetTemplate("Default")
button.background:SetTexCoord(unpack(E.TexCoords))
button.background:SetDrawLayer("ARTWORK")
button.background:SetInside(button)
button.overlay:SetTexture(nil)
bar.buttons[button] = true
end
for i = 1, 12 do
local button = _G["MultiCastActionButton"..i]
local icon = _G["MultiCastActionButton"..i.."Icon"]
local normal = _G["MultiCastActionButton"..i.."NormalTexture"]
local cooldown = _G["MultiCastActionButton"..i.."Cooldown"]
button:StyleButton()
icon:SetTexCoord(unpack(E.TexCoords))
icon:SetDrawLayer("ARTWORK")
icon:SetInside()
button.overlay:SetTexture(nil)
normal:SetTexture(nil)
normal:Hide()
normal:SetAlpha(0)
E:RegisterCooldown(cooldown)
bar.buttons[button] = true
end
for button in pairs(bar.buttons) do
button:HookScript("OnEnter", AB.TotemOnEnter)
button:HookScript("OnLeave", AB.TotemOnLeave)
end
self:SecureHook('MultiCastRecallSpellButton_Update')
self:SecureHook("MultiCastFlyoutFrameOpenButton_Show")
self:SecureHook("MultiCastActionButton_Update")
self:SecureHook("MultiCastSlotButton_Update", "StyleTotemSlotButton")
self:SecureHook("MultiCastFlyoutFrame_ToggleFlyout")
self:HookScript(_G.MultiCastActionBarFrame, "OnEnter", "TotemOnEnter")
self:HookScript(_G.MultiCastActionBarFrame, "OnLeave", "TotemOnLeave")
self:HookScript(MultiCastFlyoutFrame, "OnEnter", "TotemOnEnter")
self:HookScript(MultiCastFlyoutFrame, "OnLeave", "TotemOnLeave")
self:SecureHook("ShowMultiCastActionBar")
E:CreateMover(bar, "ElvBar_Totem", TUTORIAL_TITLE47, nil, nil, nil,"ALL,ACTIONBARS", nil, "actionbar,barTotem")
end