From bfb0251a5965cc7404653c988c65eda252fa6d7f Mon Sep 17 00:00:00 2001 From: Krathe Date: Sun, 7 Jun 2026 01:08:04 +0100 Subject: [PATCH 1/2] Resource Bar: custom colours, textures, and Maelstrom/Pain Three resource-bar additions: - Color Mode (Power Type / Class / Custom) with a custom-colour picker, replacing the old Use Class Color checkbox (migrated automatically). - A Texture dropdown so the fill can use any statusbar texture. - Maelstrom (Shaman) and Pain (Vengeance DH) added to the per-power colour list, so those resources can be recoloured instead of Blizzard's default. Colour resolution is centralised in DF:GetResourceBarColor; both render paths call it. The legacy resourceBarClassColor boolean migrates to resourceBarColorMode. --- CHANGELOG.md | 2 ++ Config.lua | 6 ++++++ Core.lua | 48 ++++++++++++++++++++++++++++++++++++++++++++ ExportCategories.lua | 3 +++ Frames/Bars.lua | 38 ++++++++--------------------------- Locales/enUS.lua | 3 +++ Options/Options.lua | 22 ++++++++++++++++++-- 7 files changed, 90 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf226246..e3985a24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * (Fonts) Bundled **Roboto Mono** (SemiBold/Bold) — a monospaced option for perfectly static countdown text. (by Krathe) * (Icons) New **in-combat indicator** — a small crossed-swords icon lights up when a unit is in combat, so you can spot who's engaged at a glance. Off by default, with its own position and size controls. (by Krathe) * (Auto Layouts) Added `/df clearoverride ` to **remove a stuck per-layout override** directly — for overrides the settings UI can't reach (e.g. a pinned-players override while not in a raid). (by Krathe) +* (Resource Bar) Added a **Color Mode** (Power Type / Class / **Custom**) with a custom-colour picker, and a **Texture** dropdown so the resource bar can use any statusbar texture. (by Krathe) ### Improvements @@ -28,6 +29,7 @@ * (Test Mode) The separate **Status / Ready** and **Role / Leader** preview toggles are now a single **Icons** toggle, matching the live status-icon grouping. (by Krathe) * (Auto Layouts) The **override tooltip and `/df overrides` now read clearly** — each changed setting shows as a breadcrumb path with its value, only values that differ from global are listed, Text Designer elements show their names, and the override counts agree across the badge, status line and chat. (by Krathe) * (Aura Designer) Expiring health-bar highlights now **pulse in unison** across all frames — and tint and replace modes share one pulse engine — instead of each frame pulsing on its own timing. (by Krathe) +* (Resource Bar) Added **Maelstrom** and **Pain** to the per-power resource colour options, so Shaman and Vengeance Demon Hunter resource bars can be recoloured. (by Krathe) ### Bug Fixes diff --git a/Config.lua b/Config.lua index fee16e52..c1272ba5 100644 --- a/Config.lua +++ b/Config.lua @@ -1905,6 +1905,8 @@ DF.PartyDefaults = { WARRIOR = true, }, resourceBarClassColor = false, + resourceBarColorMode = "POWER_TYPE", + resourceBarCustomColor = {r = 0, g = 0.5, b = 1, a = 1}, resourceBarEnabled = true, resourceBarFrameLevel = 20, resourceBarHeight = 4, @@ -1916,6 +1918,7 @@ DF.PartyDefaults = { resourceBarShowInSoloMode = true, resourceBarShowTank = false, resourceBarSmooth = true, + resourceBarTexture = "Interface\\AddOns\\DandersFrames\\Media\\DF_Minimalist", resourceBarWidth = 60, resourceBarX = 0, resourceBarY = 1, @@ -3491,6 +3494,8 @@ DF.RaidDefaults = { WARRIOR = true, }, resourceBarClassColor = false, + resourceBarColorMode = "POWER_TYPE", + resourceBarCustomColor = {r = 0, g = 0.5, b = 1, a = 1}, resourceBarEnabled = true, resourceBarFrameLevel = 20, resourceBarHeight = 4, @@ -3502,6 +3507,7 @@ DF.RaidDefaults = { resourceBarShowInSoloMode = true, resourceBarShowTank = false, resourceBarSmooth = true, + resourceBarTexture = "Interface\\AddOns\\DandersFrames\\Media\\DF_Minimalist", resourceBarWidth = 60, resourceBarX = 0, resourceBarY = 1, diff --git a/Core.lua b/Core.lua index 751bcf74..f458bb7f 100644 --- a/Core.lua +++ b/Core.lua @@ -1777,6 +1777,49 @@ function DF:GetPowerColor(powerToken, powerType) return DEFAULT_CLASS_COLOR end +-- Resolve the resource bar's fill colour for a unit per the configured colour +-- mode. Returns r, g, b (0-1). +-- POWER_TYPE → the power-type colour (user override or Blizzard default) +-- CLASS → the unit's class colour +-- CUSTOM → the user's resourceBarCustomColor +-- Honours the legacy resourceBarClassColor boolean when resourceBarColorMode +-- isn't set yet (pre-migration profiles). Uses the same UnitClass/UnitPowerType +-- calls the old inline logic did, so it carries no new secret-value risk. +function DF:GetResourceBarColor(unit, db) + local mode = db.resourceBarColorMode + if not mode then + mode = db.resourceBarClassColor and "CLASS" or "POWER_TYPE" + end + + if mode == "CUSTOM" then + local c = db.resourceBarCustomColor or {r = 0, g = 0.5, b = 1, a = 1} + return c.r or 0, c.g or 0.5, c.b or 1 + elseif mode == "CLASS" then + local _, classToken = UnitClass(unit) + local cc = classToken and DF:GetClassColor(classToken) + if cc then return cc.r, cc.g, cc.b end + -- No class colour available — fall through to the power-type colour. + end + + -- POWER_TYPE (and the CLASS fallback above) + local pType, pToken, altR, altG, altB = UnitPowerType(unit) + local info = DF:GetPowerColor(pToken, pType) + if info then return info.r, info.g, info.b end + if altR then return altR, altG, altB end + return 0, 0, 1 +end + +-- Migrate the legacy resourceBarClassColor boolean to the new +-- resourceBarColorMode tri-state. Idempotent; leaves the legacy key in place +-- (the render helper still honours it as a fallback) — same pattern as the +-- border-key migrations. +function DF:MigrateResourceBarColorMode(modeDb) + if not modeDb then return end + if modeDb.resourceBarColorMode == nil and modeDb.resourceBarClassColor ~= nil then + modeDb.resourceBarColorMode = modeDb.resourceBarClassColor and "CLASS" or "POWER_TYPE" + end +end + -- ============================================================ -- STATE DRIVERS FOR TEST MODE COMBAT SAFETY -- When test mode is active, state drivers are registered on all @@ -3416,6 +3459,11 @@ DF._MainEventDispatcher = function(self, event, arg1) DF:MigrateResourceBarBorderKeys(DF.db.party) DF:MigrateResourceBarBorderKeys(DF.db.raid) end + -- Resource Bar: resourceBarClassColor (bool) → resourceBarColorMode (tri-state). + if DF.MigrateResourceBarColorMode then + DF:MigrateResourceBarColorMode(DF.db.party) + DF:MigrateResourceBarColorMode(DF.db.raid) + end -- Aura icons: buff/debuffBorderEnabled → ShowBorder, BorderThickness → -- BorderSize (Stage 5.5 Phase 2 — full toolkit for buff/debuff borders). if DF.MigrateAuraBorderKeys then diff --git a/ExportCategories.lua b/ExportCategories.lua index e6d37b96..f207fc8d 100644 --- a/ExportCategories.lua +++ b/ExportCategories.lua @@ -151,6 +151,9 @@ DF.ExportCategories = { -- Resource/Power Bar "resourceBarClassColor", + "resourceBarColorMode", + "resourceBarCustomColor", + "resourceBarTexture", "resourceBarEnabled", "resourceBarAnchor", "resourceBarX", diff --git a/Frames/Bars.lua b/Frames/Bars.lua index d12a1f18..3bb3790d 100644 --- a/Frames/Bars.lua +++ b/Frames/Bars.lua @@ -101,6 +101,9 @@ function DF:ApplyResourceBarLayout(frame) bar:Show() bar:ClearAllPoints() + -- Fill texture (configurable; defaults to the DF house texture) + DF:SafeSetStatusBarTexture(bar, db.resourceBarTexture or "Interface\\AddOns\\DandersFrames\\Media\\DF_Minimalist") + -- Orientation & Fill Direction bar:SetOrientation(db.resourceBarOrientation or "HORIZONTAL") bar:SetReverseFill(db.resourceBarReverseFill) @@ -206,19 +209,8 @@ function DF:ApplyResourceBarLayout(frame) local maxPower = UnitPowerMax(unit) bar:SetMinMaxValues(0, maxPower) bar:SetValue(power) - local pType, pToken, altR, altG, altB = UnitPowerType(unit) - local info = DF:GetPowerColor(pToken, pType) - local _, classToken = UnitClass(unit) - local classColor = db.resourceBarClassColor and classToken and DF:GetClassColor(classToken) - if classColor then - bar:SetStatusBarColor(classColor.r, classColor.g, classColor.b, 1) - elseif info then - bar:SetStatusBarColor(info.r, info.g, info.b, 1) - elseif altR then - bar:SetStatusBarColor(altR, altG, altB, 1) - else - bar:SetStatusBarColor(0, 0, 1, 1) - end + local cr, cg, cb = DF:GetResourceBarColor(unit, db) + bar:SetStatusBarColor(cr, cg, cb, 1) end end end @@ -254,23 +246,9 @@ function DF:UpdateResourceBar(frame) bar:SetMinMaxValues(0, maxPower) DF.SetBarValue(bar, power, frame) - -- Get power type for coloring - local pType, pToken, altR, altG, altB = UnitPowerType(unit) - - -- Get color from custom overrides or Blizzard defaults - local info = DF:GetPowerColor(pToken, pType) - - local _, classToken = UnitClass(unit) - local classColor = db.resourceBarClassColor and classToken and DF:GetClassColor(classToken) - if classColor then - bar:SetStatusBarColor(classColor.r, classColor.g, classColor.b, 1) - elseif info then - bar:SetStatusBarColor(info.r, info.g, info.b, 1) - elseif altR then - bar:SetStatusBarColor(altR, altG, altB, 1) - else - bar:SetStatusBarColor(0, 0, 1, 1) -- Default to blue (mana) - end + -- Resolve fill colour per the configured colour mode (power / class / custom). + local cr, cg, cb = DF:GetResourceBarColor(unit, db) + bar:SetStatusBarColor(cr, cg, cb, 1) else bar:Hide() end diff --git a/Locales/enUS.lua b/Locales/enUS.lua index 57a0b005..e7eccb33 100644 --- a/Locales/enUS.lua +++ b/Locales/enUS.lua @@ -973,6 +973,7 @@ L["Logged Categories"] = true L["Low"] = true L["Low Health (0%)"] = true L["Lunar Power"] = true +L["Maelstrom"] = true L["Mage"] = true L["Magic"] = true L["Major defensive cooldowns like Divine Shield, Ice Block, or Barkskin."] = true @@ -1270,6 +1271,8 @@ L["Rows"] = true L["Rows Grow From"] = true L["Run"] = true L["Run Script"] = true +L["Pain"] = true +L["Power Type"] = true L["Run Setup Wizard"] = true L["Runic Power"] = true L["Runtime"] = true diff --git a/Options/Options.lua b/Options/Options.lua index 5b7d51d8..aee5b9d7 100644 --- a/Options/Options.lua +++ b/Options/Options.lua @@ -3782,8 +3782,24 @@ function DF:SetupGUIPages(GUI, CreateCategory, CreateSubTab, BuildPage) local colorGroup = GUI:CreateSettingsGroup(self.child, 280) colorGroup:AddWidget(GUI:CreateHeader(self.child, L["Resource Colors"]), 40) colorGroup:AddWidget(GUI:CreateLabel(self.child, L["Customize resource bar colors per power type. Shared across party and raid frames."], 260), 40) - colorGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Use Class Color"], db, "resourceBarClassColor", function() DF:RefreshAllVisibleFrames() end), 30) - + -- Fill texture (configurable; defaults to the DF house texture). + colorGroup:AddWidget(GUI:CreateTextureDropdown(self.child, L["Texture"], db, "resourceBarTexture", function() DF:UpdateAllFrames() end), 55) + + -- Colour mode: Power Type (per-power colours below) / Class / Custom. + local RESOURCE_COLOR_MODES = { + POWER_TYPE = L["Power Type"], CLASS = L["Class"], CUSTOM = L["Custom"], + _order = { "POWER_TYPE", "CLASS", "CUSTOM" }, + } + colorGroup:AddWidget(GUI:CreateDropdown(self.child, L["Color Mode"], RESOURCE_COLOR_MODES, db, "resourceBarColorMode", function() + DF:RefreshAllVisibleFrames() + self:RefreshStates() -- re-evaluate the custom colour picker's hideOn + end), 54) + + -- Custom colour — only shown in Custom mode. + local resourceCustomColor = GUI:CreateColorPicker(self.child, L["Custom Color"], db, "resourceBarCustomColor", false, function() DF:RefreshAllVisibleFrames() end, function() DF:RefreshAllVisibleFrames() end, true) + resourceCustomColor.hideOn = function() return (db.resourceBarColorMode or "POWER_TYPE") ~= "CUSTOM" end + colorGroup:AddWidget(resourceCustomColor, 30) + local powerColorsDB = DF.db.powerColors if not powerColorsDB then DF.db.powerColors = {} @@ -3798,7 +3814,9 @@ function DF:SetupGUIPages(GUI, CreateCategory, CreateSubTab, BuildPage) { token = "RUNIC_POWER", name = L["Runic Power"] }, { token = "INSANITY", name = L["Insanity"] }, { token = "FURY", name = L["Fury"] }, + { token = "PAIN", name = L["Pain"] }, { token = "LUNAR_POWER", name = L["Lunar Power"] }, + { token = "MAELSTROM", name = L["Maelstrom"] }, } for _, info in ipairs(POWER_LIST) do From 2ee613529172d03073cdf20c62d287881a55c67f Mon Sep 17 00:00:00 2001 From: Krathe Date: Sun, 7 Jun 2026 01:27:13 +0100 Subject: [PATCH 2/2] Resource Bar: group Texture / Orientation / Smooth into a Texture section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror the Health Bar's layout — put the resource bar's Texture dropdown, Orientation, Reverse Fill Direction and Smooth Bar Animation together in one "Texture" section instead of scattering them across groups. Orientation and Reverse Fill stay as two explicit controls (clearer than a combined "Fill Direction" dropdown, where an option like "Bottom to Top" would also silently change the orientation). UI-only; no settings or render changes. --- Options/Options.lua | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Options/Options.lua b/Options/Options.lua index aee5b9d7..bf2d991f 100644 --- a/Options/Options.lua +++ b/Options/Options.lua @@ -3667,7 +3667,6 @@ function DF:SetupGUIPages(GUI, CreateCategory, CreateSubTab, BuildPage) settingsGroup:AddWidget(GUI:CreateCheckbox(self.child, L["DPS"], db, "resourceBarShowDPS", function() DF:UpdateAllFrames() end), 30) local showInSolo = settingsGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Show in Solo Mode"], db, "resourceBarShowInSoloMode", function() DF:UpdateAllFrames() end), 30) showInSolo.hideOn = function() return GUI.SelectedMode == "raid" end - settingsGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Smooth Bar Animation"], db, "resourceBarSmooth", function() DF:UpdateAllFrames() end), 30) Add(settingsGroup, nil, 1) -- ===== CLASS FILTER GROUP (Column 1) ===== @@ -3719,13 +3718,21 @@ function DF:SetupGUIPages(GUI, CreateCategory, CreateSubTab, BuildPage) positionGroup:AddWidget(GUI:CreateSlider(self.child, L["Offset Y"], -50, 50, 1, db, "resourceBarY", nil, function() DF:LightweightUpdatePowerBarPosition() end, true), 55) Add(positionGroup, nil, 2) - -- ===== ORIENTATION GROUP (Column 1) ===== - local orientGroup = GUI:CreateSettingsGroup(self.child, 280) - orientGroup:AddWidget(GUI:CreateHeader(self.child, L["Orientation"]), 40) - local orientOptions = { HORIZONTAL= L["Horizontal"], VERTICAL= L["Vertical"] } - orientGroup:AddWidget(GUI:CreateDropdown(self.child, L["Orientation"], orientOptions, db, "resourceBarOrientation", function() DF:UpdateAllFrames() end), 55) - orientGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Reverse Fill Direction"], db, "resourceBarReverseFill", function() DF:UpdateAllFrames() end), 30) - Add(orientGroup, nil, 1) + -- ===== TEXTURE GROUP (Column 1) — mirrors the Health Bar's Texture group: + -- Texture, Orientation / Reverse Fill, and Smooth Bar Animation in one place. ===== + local textureGroup = GUI:CreateSettingsGroup(self.child, 280) + textureGroup:AddWidget(GUI:CreateHeader(self.child, L["Texture"]), 40) + textureGroup:AddWidget(GUI:CreateTextureDropdown(self.child, L["Texture"], db, "resourceBarTexture", function() DF:UpdateAllFrames() end), 55) + + -- Keep Orientation (Horizontal/Vertical) and Reverse Fill as two explicit + -- controls — clearer than a combined "Fill Direction" dropdown, where an + -- option like "Bottom to Top" silently changes the orientation too. + local orientOptions = { HORIZONTAL = L["Horizontal"], VERTICAL = L["Vertical"] } + textureGroup:AddWidget(GUI:CreateDropdown(self.child, L["Orientation"], orientOptions, db, "resourceBarOrientation", function() DF:UpdateAllFrames() end), 55) + textureGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Reverse Fill Direction"], db, "resourceBarReverseFill", function() DF:UpdateAllFrames() end), 30) + + textureGroup:AddWidget(GUI:CreateCheckbox(self.child, L["Smooth Bar Animation"], db, "resourceBarSmooth", function() DF:UpdateAllFrames() end), 30) + Add(textureGroup, nil, 1) -- ===== BACKGROUND GROUP (Column 2) ===== local bgGroup = GUI:CreateSettingsGroup(self.child, 280) @@ -3782,9 +3789,6 @@ function DF:SetupGUIPages(GUI, CreateCategory, CreateSubTab, BuildPage) local colorGroup = GUI:CreateSettingsGroup(self.child, 280) colorGroup:AddWidget(GUI:CreateHeader(self.child, L["Resource Colors"]), 40) colorGroup:AddWidget(GUI:CreateLabel(self.child, L["Customize resource bar colors per power type. Shared across party and raid frames."], 260), 40) - -- Fill texture (configurable; defaults to the DF house texture). - colorGroup:AddWidget(GUI:CreateTextureDropdown(self.child, L["Texture"], db, "resourceBarTexture", function() DF:UpdateAllFrames() end), 55) - -- Colour mode: Power Type (per-power colours below) / Class / Custom. local RESOURCE_COLOR_MODES = { POWER_TYPE = L["Power Type"], CLASS = L["Class"], CUSTOM = L["Custom"],