feat: pfUI theme

This commit is contained in:
Vati
2026-03-17 23:22:55 +04:00
parent fc802454f0
commit 964a801709
5 changed files with 224 additions and 48 deletions
+9
View File
@@ -143,6 +143,15 @@ function DB:Initialize()
Guda_CharDB.settings.autoLockSetItems = true Guda_CharDB.settings.autoLockSetItems = true
end end
-- Auto-detect pfUI on first load (theme not yet set)
if Guda_CharDB.settings.theme == nil then
if pfUI then
Guda_CharDB.settings.theme = "pfui"
Guda_CharDB.settings.hideBorders = true
Guda_CharDB.settings.bgTransparency = 0
end
end
-- Initialize locked items storage -- Initialize locked items storage
if not Guda_CharDB.lockedItems then if not Guda_CharDB.lockedItems then
Guda_CharDB.lockedItems = {} Guda_CharDB.lockedItems = {}
+98 -25
View File
@@ -30,8 +30,8 @@ local themes = {
insets = { left = 11, right = 12, top = 12, bottom = 11 } insets = { left = 11, right = 12, top = 12, bottom = 11 }
}, },
borderMinimal = { borderMinimal = {
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeFile = "",
edgeSize = 2, edgeSize = 0,
insets = { left = 0, right = 0, top = 0, bottom = 0 } insets = { left = 0, right = 0, top = 0, bottom = 0 }
}, },
nineSlice = { nineSlice = {
@@ -59,8 +59,8 @@ local themes = {
insets = { left = 11, right = 12, top = 12, bottom = 11 } insets = { left = 11, right = 12, top = 12, bottom = 11 }
}, },
borderMinimal = { borderMinimal = {
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeFile = "",
edgeSize = 2, edgeSize = 0,
insets = { left = 0, right = 0, top = 0, bottom = 0 } insets = { left = 0, right = 0, top = 0, bottom = 0 }
}, },
nineSlice = { nineSlice = {
@@ -78,6 +78,31 @@ local themes = {
headerButtonBg = { 0.15, 0.12, 0.10, 0.6 }, headerButtonBg = { 0.15, 0.12, 0.10, 0.6 },
headerButtonBorder = { 0.45, 0.40, 0.35, 1 }, headerButtonBorder = { 0.45, 0.40, 0.35, 1 },
}, },
pfui = {
bgTexture = "Interface\\Buttons\\WHITE8x8",
bgColor = { r = 0, g = 0, b = 0 },
bgTile = false,
bgTileSize = 1,
border = {
edgeFile = "Interface\\Buttons\\WHITE8x8",
edgeSize = 1,
insets = { left = -1, right = -1, top = -1, bottom = -1 }
},
borderMinimal = {
edgeFile = "Interface\\Buttons\\WHITE8x8",
edgeSize = 1,
insets = { left = -1, right = -1, top = -1, bottom = -1 }
},
nineSlice = nil,
titleColor = { r = 1, g = 1, b = 1 },
slotBgAlpha = { empty = 0.5, filled = 0.3 },
footerButtonBg = { 0, 0, 0, 1 },
footerButtonBorder = { 0.2, 0.2, 0.2, 1 },
showHeaderButtonBg = false,
slotStyle = "square",
borderColor = { 0.2, 0.2, 0.2, 1 },
qualityBorderStyle = "square",
},
} }
-- Cached active theme -- Cached active theme
@@ -109,6 +134,16 @@ function Theme:GetValue(key)
return t[key] return t[key]
end end
-- Get slot style (square for pfUI, rounded for others)
function Theme:GetSlotStyle()
return self:GetValue("slotStyle") or "rounded"
end
-- Get quality border style
function Theme:GetQualityBorderStyle()
return self:GetValue("qualityBorderStyle") or "rounded"
end
-- Get border config based on hideBorders setting -- Get border config based on hideBorders setting
local function GetBorderConfig(t) local function GetBorderConfig(t)
local hideBorders = false local hideBorders = false
@@ -134,15 +169,16 @@ end
-- Apply or hide a TGA background texture (for themes where bgFile TGA doesn't work with SetBackdrop) -- Apply or hide a TGA background texture (for themes where bgFile TGA doesn't work with SetBackdrop)
-- Uses ARTWORK layer so it always renders above the backdrop's BACKGROUND fill, -- Uses ARTWORK layer so it always renders above the backdrop's BACKGROUND fill,
-- preventing the intermittent z-order issue where both share the same BACKGROUND layer. -- preventing the intermittent z-order issue where both share the same BACKGROUND layer.
local function ApplyBgTexture(frame, texturePath, alpha) local function ApplyBgTexture(frame, texturePath, alpha, padding)
if not frame._gudaBgTex then if not frame._gudaBgTex then
frame._gudaBgTex = frame:CreateTexture(nil, "ARTWORK") frame._gudaBgTex = frame:CreateTexture(nil, "ARTWORK")
end end
local p = padding or 6
local tex = frame._gudaBgTex local tex = frame._gudaBgTex
tex:ClearAllPoints() tex:ClearAllPoints()
tex:SetTexture(texturePath) tex:SetTexture(texturePath)
tex:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -6) tex:SetPoint("TOPLEFT", frame, "TOPLEFT", p, -p)
tex:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 6) tex:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -p, p)
tex:SetAlpha(alpha or 1) tex:SetAlpha(alpha or 1)
tex:Show() tex:Show()
end end
@@ -328,28 +364,47 @@ function Theme:ApplyToFrame(frame)
ApplyNineSlice(frame, t.nineSlice) ApplyNineSlice(frame, t.nineSlice)
ThemeDebug(" SetBackdrop done (bgFile + NineSlice border)") ThemeDebug(" SetBackdrop done (bgFile + NineSlice border)")
else else
-- Standard backdrop with edgeFile border -- Standard backdrop with edgeFile border (or no border when hidden)
local backdrop = { local hasEdge = borderCfg.edgeFile and borderCfg.edgeFile ~= ""
bgFile = t.bgTexture, local backdrop
edgeFile = borderCfg.edgeFile, if hasEdge then
tile = true, backdrop = {
tileSize = t.bgTileSize, bgFile = t.bgTexture,
edgeSize = borderCfg.edgeSize, edgeFile = borderCfg.edgeFile,
insets = { tile = true,
left = borderCfg.insets.left, tileSize = t.bgTileSize,
right = borderCfg.insets.right, edgeSize = borderCfg.edgeSize,
top = borderCfg.insets.top, insets = {
bottom = borderCfg.insets.bottom, left = borderCfg.insets.left,
right = borderCfg.insets.right,
top = borderCfg.insets.top,
bottom = borderCfg.insets.bottom,
}
} }
} else
-- No border: omit edgeFile key entirely (WoW 1.12 renders a black
-- line when edgeFile is "" or nil inside the table)
backdrop = {
bgFile = t.bgTexture,
tile = true,
tileSize = t.bgTileSize,
edgeSize = 0,
insets = { left = 0, right = 0, top = 0, bottom = 0 }
}
end
frame:SetBackdrop(nil) frame:SetBackdrop(nil)
frame:SetBackdrop(backdrop) frame:SetBackdrop(backdrop)
HideNineSlice(frame) HideNineSlice(frame)
ThemeDebug(" SetBackdrop done (bgFile + edgeFile border)") ThemeDebug(" SetBackdrop done (bgFile + %s border)", hasEdge and "edgeFile" or "none")
end end
if isMinimal then -- Apply border color when an edge is present
frame:SetBackdropBorderColor(1, 1, 1, 1) local hasEdge = borderCfg.edgeFile and borderCfg.edgeFile ~= ""
if hasEdge then
local bc = t.borderColor or { 1, 1, 1, 1 }
if isMinimal or t.borderColor then
frame:SetBackdropBorderColor(bc[1], bc[2], bc[3], bc[4])
end
end end
-- Background quadrant textures (disabled for testing) -- Background quadrant textures (disabled for testing)
@@ -361,7 +416,8 @@ function Theme:ApplyToFrame(frame)
if addon.Modules and addon.Modules.DB then if addon.Modules and addon.Modules.DB then
transparency = addon.Modules.DB:GetSetting("bgTransparency") or 0.15 transparency = addon.Modules.DB:GetSetting("bgTransparency") or 0.15
end end
ApplyBgTexture(frame, t.bgOverlay, 1.0 - transparency) local bgPadding = isMinimal and 0 or 6
ApplyBgTexture(frame, t.bgOverlay, 1.0 - transparency, bgPadding)
else else
HideBgTexture(frame) HideBgTexture(frame)
end end
@@ -445,14 +501,31 @@ function Theme:ApplyToAllFrames()
ThemeDebug("=== ApplyToAllFrames done ===") ThemeDebug("=== ApplyToAllFrames done ===")
end end
-- Update emptySlotBg alpha on all visible item buttons -- Update emptySlotBg alpha and style on all visible item buttons
function Theme:UpdateAllSlotBackgrounds(sa) function Theme:UpdateAllSlotBackgrounds(sa)
local slotStyle = self:GetSlotStyle()
local i = 1 local i = 1
while true do while true do
local btn = getglobal("Guda_ItemButton" .. i) local btn = getglobal("Guda_ItemButton" .. i)
if not btn then break end if not btn then break end
local bg = getglobal(btn:GetName() .. "_EmptySlotBg") local bg = getglobal(btn:GetName() .. "_EmptySlotBg")
if bg then if bg then
-- Update texture and anchors based on slot style
if slotStyle == "square" then
bg:SetTexture("Interface\\Buttons\\WHITE8x8")
bg:SetVertexColor(0.05, 0.05, 0.05, 1)
bg:ClearAllPoints()
bg:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0)
bg:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0)
bg:SetTexCoord(0, 1, 0, 1)
else
bg:SetTexture("Interface\\Buttons\\UI-EmptySlot")
bg:SetVertexColor(1, 1, 1, 1)
bg:ClearAllPoints()
bg:SetPoint("TOPLEFT", btn, "TOPLEFT", -9, 9)
bg:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 9, -9)
bg:SetTexCoord(0, 1, 0, 1)
end
local alpha = btn.hasItem and sa.filled or sa.empty local alpha = btn.hasItem and sa.filled or sa.empty
if alpha > 0 then if alpha > 0 then
bg:SetAlpha(alpha) bg:SetAlpha(alpha)
+16 -6
View File
@@ -2867,12 +2867,22 @@ end
-- Apply footer button backdrop styling -- Apply footer button backdrop styling
function Guda_BagSlot_ApplyBackdrop(button) function Guda_BagSlot_ApplyBackdrop(button)
local Theme = addon.Modules.Theme local Theme = addon.Modules.Theme
button:SetBackdrop({ local qStyle = Theme:GetQualityBorderStyle()
bgFile = "Interface\\Buttons\\WHITE8x8", if qStyle == "square" then
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", button:SetBackdrop({
edgeSize = 8, bgFile = "Interface\\Buttons\\WHITE8x8",
insets = { left = 2, right = 2, top = 2, bottom = 2 }, edgeFile = "Interface\\Buttons\\WHITE8x8",
}) edgeSize = 1,
insets = { left = -1, right = -1, top = -1, bottom = -1 },
})
else
button:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8x8",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
edgeSize = 8,
insets = { left = 2, right = 2, top = 2, bottom = 2 },
})
end
local fbBg = Theme:GetValue("footerButtonBg") or { 0.12, 0.12, 0.12, 1 } local fbBg = Theme:GetValue("footerButtonBg") or { 0.12, 0.12, 0.12, 1 }
local fbBorder = Theme:GetValue("footerButtonBorder") or { 0.30, 0.30, 0.30, 1 } local fbBorder = Theme:GetValue("footerButtonBorder") or { 0.30, 0.30, 0.30, 1 }
button:SetBackdropColor(fbBg[1], fbBg[2], fbBg[3], fbBg[4]) button:SetBackdropColor(fbBg[1], fbBg[2], fbBg[3], fbBg[4])
+58 -14
View File
@@ -383,17 +383,51 @@ local qualityBorderBackdrop = {
insets = { left = 0, right = 0, top = 0, bottom = 0 }, insets = { left = 0, right = 0, top = 0, bottom = 0 },
} }
local qualityBorderBackdropSquare = {
edgeFile = "Interface\\Buttons\\WHITE8x8",
edgeSize = 2,
insets = { left = 0, right = 0, top = 0, bottom = 0 },
}
-- Get or create the quality border frame for a button -- Get or create the quality border frame for a button
local function GetQualityBorderFrame(button) local function GetQualityBorderFrame(button)
if button._qualityBorder then return button._qualityBorder end local qStyle = "rounded"
if addon.Modules and addon.Modules.Theme then
qStyle = addon.Modules.Theme:GetQualityBorderStyle()
end
if button._qualityBorder then
-- Update backdrop if style changed
if button._qualityBorderStyle ~= qStyle then
button._qualityBorderStyle = qStyle
local pad = QUALITY_BORDER_PADDING
button._qualityBorder:ClearAllPoints()
if qStyle == "square" then
button._qualityBorder:SetBackdrop(qualityBorderBackdropSquare)
button._qualityBorder:SetPoint("TOPLEFT", button, "TOPLEFT", -pad, pad)
button._qualityBorder:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", pad, -pad)
else
button._qualityBorder:SetBackdrop(qualityBorderBackdrop)
button._qualityBorder:SetPoint("TOPLEFT", button, "TOPLEFT", -pad, pad)
button._qualityBorder:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", pad, -pad)
end
end
return button._qualityBorder
end
local frame = CreateFrame("Frame", nil, button) local frame = CreateFrame("Frame", nil, button)
frame:SetFrameLevel(button:GetFrameLevel() + 3) frame:SetFrameLevel(button:GetFrameLevel() + 3)
local pad = QUALITY_BORDER_PADDING local pad = QUALITY_BORDER_PADDING
frame:SetPoint("TOPLEFT", button, "TOPLEFT", -pad, pad) frame:SetPoint("TOPLEFT", button, "TOPLEFT", -pad, pad)
frame:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", pad, -pad) frame:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", pad, -pad)
frame:SetBackdrop(qualityBorderBackdrop) if qStyle == "square" then
frame:SetBackdrop(qualityBorderBackdropSquare)
else
frame:SetBackdrop(qualityBorderBackdrop)
end
frame:Hide() frame:Hide()
button._qualityBorder = frame button._qualityBorder = frame
button._qualityBorderStyle = qStyle
return frame return frame
end end
@@ -1240,15 +1274,30 @@ local function UpdateTrackingCheckmark(self, Utils)
end end
end end
-- Resize empty slot background to match icon size -- Resize empty slot background to match icon size and slot style
local function UpdateEmptySlotBackground(self, emptySlotBg, iconSize) local function UpdateEmptySlotBackground(self, emptySlotBg, iconSize)
if not emptySlotBg then return end if not emptySlotBg then return end
-- Extend 9px past button edges so the rounded corners of UI-EmptySlot local slotStyle = "rounded"
-- cover the square corners of the icon texture (same as GudaBags) if addon.Modules and addon.Modules.Theme then
slotStyle = addon.Modules.Theme:GetSlotStyle()
end
emptySlotBg:ClearAllPoints() emptySlotBg:ClearAllPoints()
emptySlotBg:SetPoint("TOPLEFT", self, "TOPLEFT", -9, 9) if slotStyle == "square" then
emptySlotBg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 9, -9) -- Flush anchors for pixel-perfect squared slots
emptySlotBg:SetTexture("Interface\\Buttons\\WHITE8x8")
emptySlotBg:SetVertexColor(0.05, 0.05, 0.05, 1)
emptySlotBg:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
emptySlotBg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
else
-- Extend 9px past button edges so the rounded corners of UI-EmptySlot
-- cover the square corners of the icon texture (same as GudaBags)
emptySlotBg:SetTexture("Interface\\Buttons\\UI-EmptySlot")
emptySlotBg:SetVertexColor(1, 1, 1, 1)
emptySlotBg:SetPoint("TOPLEFT", self, "TOPLEFT", -9, 9)
emptySlotBg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 9, -9)
end
emptySlotBg:SetTexCoord(0, 1, 0, 1) emptySlotBg:SetTexCoord(0, 1, 0, 1)
end end
@@ -1552,13 +1601,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
-- Update lock icon -- Update lock icon
UpdateLockIcon(self, iconSize) UpdateLockIcon(self, iconSize)
-- Extend empty slot bg 9px past button edges for rounded corner coverage -- Update empty slot bg anchors/texture based on slot style
if emptySlotBg then UpdateEmptySlotBackground(self, emptySlotBg, iconSize)
emptySlotBg:ClearAllPoints()
emptySlotBg:SetPoint("TOPLEFT", self, "TOPLEFT", -9, 9)
emptySlotBg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 9, -9)
emptySlotBg:SetTexCoord(0, 1, 0, 1)
end
-- Also resize the underlying slot textures so the border/background scale with the button. -- Also resize the underlying slot textures so the border/background scale with the button.
-- On 1.12/Turtle, ItemButtonTemplate uses fixed-size textures, so we explicitly size them -- On 1.12/Turtle, ItemButtonTemplate uses fixed-size textures, so we explicitly size them
+43 -3
View File
@@ -1553,6 +1553,7 @@ end
local themeOptions = { local themeOptions = {
{ text = "Guda", value = "guda" }, { text = "Guda", value = "guda" },
{ text = "Blizzard", value = "blizzard" }, { text = "Blizzard", value = "blizzard" },
{ text = "pfUI", value = "pfui" },
} }
local function Guda_ThemeDropdown_Initialize() local function Guda_ThemeDropdown_Initialize()
@@ -1575,7 +1576,7 @@ function Guda_SettingsPopup_ThemeDropdown_OnLoad(self)
UIDropDownMenu_Initialize(self, Guda_ThemeDropdown_Initialize) UIDropDownMenu_Initialize(self, Guda_ThemeDropdown_Initialize)
UIDropDownMenu_SetWidth(130, self) UIDropDownMenu_SetWidth(130, self)
local currentTheme = Guda.Modules.DB:GetSetting("theme") or "guda" local currentTheme = Guda.Modules.DB:GetSetting("theme") or "guda"
local names = { guda = "Guda", blizzard = "Blizzard" } local names = { guda = "Guda", blizzard = "Blizzard", pfui = "pfUI" }
UIDropDownMenu_SetSelectedValue(self, currentTheme) UIDropDownMenu_SetSelectedValue(self, currentTheme)
UIDropDownMenu_SetText(names[currentTheme] or currentTheme, self) UIDropDownMenu_SetText(names[currentTheme] or currentTheme, self)
@@ -1588,7 +1589,35 @@ end
-- Apply selected theme -- Apply selected theme
function Guda_SettingsPopup_ApplyTheme(themeId) function Guda_SettingsPopup_ApplyTheme(themeId)
Guda.Modules.DB:SetSetting("theme", themeId) local DB = Guda.Modules.DB
local oldTheme = DB:GetSetting("theme") or "guda"
-- Save current hideBorders/bgTransparency when leaving pfUI theme
if oldTheme == "pfui" and themeId ~= "pfui" then
-- Restore previously saved values (from before pfUI was applied)
local prevHide = DB:GetSetting("_prePfui_hideBorders")
local prevTransp = DB:GetSetting("_prePfui_bgTransparency")
if prevHide ~= nil then
DB:SetSetting("hideBorders", prevHide)
else
DB:SetSetting("hideBorders", false)
end
if prevTransp ~= nil then
DB:SetSetting("bgTransparency", prevTransp)
else
DB:SetSetting("bgTransparency", 0.15)
end
end
-- Save current values before switching to pfUI, then apply pfUI defaults
if themeId == "pfui" and oldTheme ~= "pfui" then
DB:SetSetting("_prePfui_hideBorders", DB:GetSetting("hideBorders"))
DB:SetSetting("_prePfui_bgTransparency", DB:GetSetting("bgTransparency"))
DB:SetSetting("hideBorders", true)
DB:SetSetting("bgTransparency", 0)
end
DB:SetSetting("theme", themeId)
-- Clear theme cache -- Clear theme cache
if Guda.Modules.Theme then if Guda.Modules.Theme then
@@ -1598,7 +1627,7 @@ function Guda_SettingsPopup_ApplyTheme(themeId)
-- Update dropdown text -- Update dropdown text
local dropdown = getglobal("Guda_SettingsPopup_ThemeDropdown") local dropdown = getglobal("Guda_SettingsPopup_ThemeDropdown")
if dropdown then if dropdown then
local names = { guda = "Guda", blizzard = "Blizzard" } local names = { guda = "Guda", blizzard = "Blizzard", pfui = "pfUI" }
UIDropDownMenu_SetSelectedValue(dropdown, themeId) UIDropDownMenu_SetSelectedValue(dropdown, themeId)
UIDropDownMenu_SetText(names[themeId] or themeId, dropdown) UIDropDownMenu_SetText(names[themeId] or themeId, dropdown)
end end
@@ -1607,6 +1636,17 @@ function Guda_SettingsPopup_ApplyTheme(themeId)
if Guda.Modules.Theme then if Guda.Modules.Theme then
Guda.Modules.Theme:ApplyToAllFrames() Guda.Modules.Theme:ApplyToAllFrames()
end end
-- Refresh settings UI controls to reflect changed hideBorders/bgTransparency
local hideBordersCheckbox = getglobal("Guda_SettingsPopup_HideBordersCheckbox")
if hideBordersCheckbox then
local hb = DB:GetSetting("hideBorders")
hideBordersCheckbox:SetChecked(hb and 1 or 0)
end
local bgTransparencySlider = getglobal("Guda_SettingsPopup_BgTransparencySlider")
if bgTransparencySlider then
bgTransparencySlider:SetValue(DB:GetSetting("bgTransparency") or 0.15)
end
end end
-- Bag View Dropdown -- Bag View Dropdown