From 8beb36e57eaab821e103d95d448a936e6c13a44b Mon Sep 17 00:00:00 2001 From: Narcasung Date: Mon, 13 Jul 2026 15:03:05 +0200 Subject: [PATCH] Initial commit: ElvUI_CoA plugin Skins/hides custom CoA-server frames not covered by stock ElvUI, starting with the ExtraActionBar. --- ElvUI_CoA.toc | 10 +++ Modules/ExtraActionBar.lua | 150 +++++++++++++++++++++++++++++++++++++ README.md | 7 ++ core.lua | 61 +++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 ElvUI_CoA.toc create mode 100644 Modules/ExtraActionBar.lua create mode 100644 README.md create mode 100644 core.lua diff --git a/ElvUI_CoA.toc b/ElvUI_CoA.toc new file mode 100644 index 0000000..010c84b --- /dev/null +++ b/ElvUI_CoA.toc @@ -0,0 +1,10 @@ +## Interface: 30300 +## Author: Narcasung +## Version: 1.0 +## Title: |cff1784d1E|r|cffe5e3e3lvUI|r |cff1784d1C|r|cffe5e3e3oA|r +## Notes: Hides and skins custom CoA-server frames for ElvUI. +## RequiredDeps: ElvUI +## X-IconTexture: Interface\AddOns\ElvUI\Media\ElvUILogo + +core.lua +Modules\ExtraActionBar.lua diff --git a/Modules/ExtraActionBar.lua b/Modules/ExtraActionBar.lua new file mode 100644 index 0000000..e2498dc --- /dev/null +++ b/Modules/ExtraActionBar.lua @@ -0,0 +1,150 @@ +local E, L, V, P, G = unpack(ElvUI) +local CoA = E:GetModule("CoA") + +local CONTAINER_NAME = "ExtraActionBar" +local BUTTON_NAME = "ExtraActionBarPoolFrameExtraActionButtonTemplate1" + +local function SkinGlow(button, name) + local glow = _G[name.."SpellActivationAlert"] + if not glow or not glow.GetNumRegions then return end + + for i = 1, glow:GetNumRegions() do + local region = select(i, glow:GetRegions()) + if region and region.IsObjectType and region:IsObjectType("Texture") then + region:SetVertexColor(unpack(E.media.rgbvaluecolor)) + end + end +end + +local function SkinButton(button) + if button.CoASkinned then return end + button.CoASkinned = true + + local name = button:GetName() + local icon = _G[name.."Icon"] + local hotkey = _G[name.."HotKey"] + local macroText = _G[name.."Name"] + local count = _G[name.."Count"] + local flash = _G[name.."Flash"] + local border = _G[name.."Border"] + local normal = _G[name.."NormalTexture"] + local normal2 = button:GetNormalTexture() + local cooldown = _G[name.."Cooldown"] + + if flash then flash:SetTexture(nil) end + if border then border:Kill() end + if normal then normal:SetTexture(nil) normal:Hide() end + if normal2 then normal2:SetTexture(nil) normal2:Hide() end + + for i = 1, button:GetNumRegions() do + local region = select(i, button:GetRegions()) + if region and region.IsObjectType and region:IsObjectType("Texture") and region:GetTexture() == [[Interface\ExtraButton\Default]] then + region:SetTexture(nil) + region:Hide() + end + end + + button:CreateBackdrop("Default") + button.backdrop:SetBackdropColor(0, 0, 0, 0) + button.backdrop:SetBackdropBorderColor(0, 0, 0, 0) + button:StyleButton() + + if icon then + icon:SetTexCoord(0.08, 0.92, 0.08, 0.92) + icon:SetParent(button.backdrop) + button.backdrop:SetOutside(icon, 1, 1) + + local rim = CreateFrame("Frame", nil, button.backdrop) + rim:SetAllPoints(icon) + rim:SetFrameLevel(button.backdrop:GetFrameLevel() + 10) + rim:SetBackdrop({edgeFile = E.media.blankTex, edgeSize = 6}) + rim:SetBackdropBorderColor(unpack(E.media.bordercolor)) + end + + if hotkey then + hotkey:ClearAllPoints() + hotkey:Point("TOPRIGHT", 0, 0) + hotkey:FontTemplate() + end + + if macroText then + macroText:ClearAllPoints() + macroText:Point("BOTTOM", 0, 1) + macroText:FontTemplate() + end + + if count then + count:ClearAllPoints() + count:Point("BOTTOMRIGHT", 0, 2) + count:FontTemplate() + end + + if cooldown then + cooldown.CooldownOverride = "actionbar" + E:RegisterCooldown(cooldown) + end + + SkinGlow(button, name) +end + +local function SetupMover(container, button) + if CoA.extraActionBarMoverCreated then return end + + local width, height = button:GetSize() + if width == 0 or height == 0 then return end + + local left, bottom = button:GetLeft(), button:GetBottom() + if not left or not bottom then return end + + CoA.extraActionBarMoverCreated = true + + container:StripTextures(true) + container:EnableMouse(false) + + local holder = CreateFrame("Frame", "CoA_ExtraActionBarHolder", E.UIParent) + holder:Size(width, height) + holder:Point("BOTTOMLEFT", E.UIParent, "BOTTOMLEFT", left, bottom) + + E:CreateMover(holder, "CoA_ExtraActionBarMover", "Extra Action Bar", nil, nil, nil, "ALL,ACTIONBARS", nil, "CoA,skin,extraActionBar") + holder:SetAllPoints(_G["CoA_ExtraActionBarMover"]) + + local function Anchor() + container:ClearAllPoints() + container:SetPoint("CENTER", holder, "CENTER") + end + + if InCombatLockdown() then + CoA:RegisterEvent("PLAYER_REGEN_ENABLED", function() + Anchor() + CoA:UnregisterEvent("PLAYER_REGEN_ENABLED") + end) + else + Anchor() + end +end + +local function TryHook() + local container = _G[CONTAINER_NAME] + local button = _G[BUTTON_NAME] + + if container and button then + SetupMover(container, button) + + if E.private.CoA.extraActionBar then + SkinButton(button) + end + end + + return container ~= nil and button ~= nil +end + +function CoA:InitializeExtraActionBar() + if TryHook() then return end + + self.extraActionBarTimer = self:ScheduleRepeatingTimer(function() + if TryHook() then + self:CancelTimer(self.extraActionBarTimer) + self.extraActionBarTimer = nil + end + end, 0.5) +end diff --git a/README.md b/README.md new file mode 100644 index 0000000..64f3571 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# ElvUI_CoA + +ElvUI plugin that hides and skins the custom Conquest of Azeroth (Ascension WoW, client 3.3.5) server frames not covered by stock ElvUI — e.g. the `ExtraActionBar`. + +## Requirements + +- [ElvUI](https://www.tukui.org/elvui/) (3.3.5 backport) diff --git a/core.lua b/core.lua new file mode 100644 index 0000000..6aa8616 --- /dev/null +++ b/core.lua @@ -0,0 +1,61 @@ +local E, L, V, P, G = unpack(ElvUI) +local EP = E.Libs.EP + +local AddOnName = ... + +local CoA = E:NewModule("CoA", "AceEvent-3.0", "AceTimer-3.0") +E.CoA = CoA + +V.CoA = { + extraActionBar = true, +} + +local function getOptions() + local options = { + order = 55, + type = "group", + childGroups = "tab", + name = string.format("|cff1784d1%s|r", "Conquest of Azeroth"), + args = { + skin = { + order = 1, + type = "group", + name = "Skins", + get = function(info) return E.private.CoA[info[#info]] end, + set = function(info, value) + E.private.CoA[info[#info]] = value + E:StaticPopup_Show("PRIVATE_RL") + end, + args = { + header = { + order = 1, + type = "header", + name = "Skins", + }, + extraActionBar = { + order = 2, + type = "toggle", + name = "Extra Action Bar", + desc = "Skin the ExtraActionBar frame.", + }, + }, + }, + }, + } + + E.Options.args.CoA = options +end + +function CoA:Initialize() + EP:RegisterPlugin(AddOnName, getOptions) + + if self.InitializeExtraActionBar then + self:InitializeExtraActionBar() + end +end + +local function InitializeCallback() + CoA:Initialize() +end + +E:RegisterModule(CoA:GetName(), InitializeCallback)