Files
hide-coa-ui/HideCoA.lua
T
Narcasung ea4849fc10 Revamp options UI: dropdown-based class picker and per-character override tab
Replaces the 21-tab class sidebar with a single Classes tab driven by a
dropdown plus Hide All/Show All bulk actions. Reworks the old Profiles tab
into "Character Override": a single toggle that lets a character's frame
hide/show choices bypass its class settings, backed by a new
characterOverrides table alongside the existing profile data. Adds an
empty About tab, restyles sidebar tabs gold/white, and drops the unused
subtitle line.
2026-07-07 23:23:25 +02:00

397 lines
9.4 KiB
Lua

HideCoA = {}
local f = CreateFrame("Frame")
HideCoA.CUSTOM_CLASSES = {
"NECROMANCER",
"PYROMANCER",
"CULTIST",
"STARCALLER",
"SUNCLERIC",
"TINKER",
"SPIRITMAGE",
"WILDWALKER",
"REAPER",
"PROPHET",
"CHRONOMANCER",
"SONOFARUGAL",
"GUARDIAN",
"STORMBRINGER",
"DEMONHUNTER",
"BARBARIAN",
"WITCHDOCTOR",
"WITCHHUNTER",
"FLESHWARDEN",
"MONK",
"RANGER",
}
HideCoA.FRAMES = {
"CoAResourceSegmentBar",
"CoAResourceOrb",
"CoAResourceBar",
}
local function CreateDefaultClassSettings()
local classSettings = {}
for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do
classSettings[class] = {}
for _, frameName in ipairs(HideCoA.FRAMES) do
classSettings[class][frameName] = true
end
end
return classSettings
end
local function EnsureClassSettingsComplete(classSettings)
for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do
if type(classSettings[class]) ~= "table" then
classSettings[class] = {}
end
for _, frameName in ipairs(HideCoA.FRAMES) do
if classSettings[class][frameName] == nil then
classSettings[class][frameName] = true
end
end
end
end
local function GetCharacterKey()
return UnitName("player") .. " - " .. GetRealmName()
end
HideCoA.GetCharacterKey = GetCharacterKey
local function GetActiveProfileName()
local charKey = GetCharacterKey()
local assigned = HideCoADB.charProfile and HideCoADB.charProfile[charKey]
if assigned and HideCoADB.profiles[assigned] then
return assigned
end
return charKey
end
HideCoA.GetActiveProfileName = GetActiveProfileName
local function SetActiveProfileName(name)
HideCoADB.charProfile[GetCharacterKey()] = name
end
HideCoA.SetActiveProfileName = SetActiveProfileName
local function GetActiveClassSettings()
local name = GetActiveProfileName()
local profile = HideCoADB.profiles[name]
if not profile then
profile = { classSettings = CreateDefaultClassSettings() }
HideCoADB.profiles[name] = profile
end
if not profile.classSettings then
profile.classSettings = CreateDefaultClassSettings()
end
return profile.classSettings
end
HideCoA.GetActiveClassSettings = GetActiveClassSettings
local function CopyProfile(sourceName, destName)
local source = HideCoADB.profiles[sourceName]
if not source or not source.classSettings then
return
end
local copy = {}
for class, settings in pairs(source.classSettings) do
copy[class] = {}
for frameName, value in pairs(settings) do
copy[class][frameName] = value
end
end
if not HideCoADB.profiles[destName] then
HideCoADB.profiles[destName] = {}
end
HideCoADB.profiles[destName].classSettings = copy
HideCoA.ApplySetting()
end
HideCoA.CopyProfile = CopyProfile
local function ResetProfile()
local name = GetActiveProfileName()
if not HideCoADB.profiles[name] then
HideCoADB.profiles[name] = {}
end
HideCoADB.profiles[name].classSettings = CreateDefaultClassSettings()
HideCoA.ApplySetting()
end
HideCoA.ResetProfile = ResetProfile
local function DeleteProfile(name)
if name == "Default" then
return
end
local wasActive = (name == GetActiveProfileName())
HideCoADB.profiles[name] = nil
for charKey, assigned in pairs(HideCoADB.charProfile) do
if assigned == name then
HideCoADB.charProfile[charKey] = nil
end
end
if wasActive then
HideCoADB.charProfile[GetCharacterKey()] = "Default"
end
end
HideCoA.DeleteProfile = DeleteProfile
local function EnsureCharacterOverride(charKey)
if not HideCoADB.characterOverrides then
HideCoADB.characterOverrides = {}
end
local override = HideCoADB.characterOverrides[charKey]
if not override then
override = { enabled = false, frameSettings = {} }
HideCoADB.characterOverrides[charKey] = override
end
for _, frameName in ipairs(HideCoA.FRAMES) do
if override.frameSettings[frameName] == nil then
override.frameSettings[frameName] = true
end
end
return override
end
local function GetCharacterOverride()
return EnsureCharacterOverride(GetCharacterKey())
end
HideCoA.GetCharacterOverride = GetCharacterOverride
local function SetCharacterOverrideEnabled(enabled)
GetCharacterOverride().enabled = enabled
HideCoA.ApplySetting()
end
HideCoA.SetCharacterOverrideEnabled = SetCharacterOverrideEnabled
local function SetCharacterOverrideFrameHidden(frameName, hide)
GetCharacterOverride().frameSettings[frameName] = hide
HideCoA.ApplySetting()
end
HideCoA.SetCharacterOverrideFrameHidden = SetCharacterOverrideFrameHidden
local function SetAllClassesHidden(hide)
local classSettings = GetActiveClassSettings()
for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do
for _, frameName in ipairs(HideCoA.FRAMES) do
classSettings[class][frameName] = hide
end
end
end
local function HideAllFrames()
SetAllClassesHidden(true)
HideCoA.ApplySetting()
end
HideCoA.HideAllFrames = HideAllFrames
local function ShowAllFrames()
SetAllClassesHidden(false)
HideCoA.ApplySetting()
end
HideCoA.ShowAllFrames = ShowAllFrames
local function ShouldHideForClass(playerClass, frameName)
local classSettings = GetActiveClassSettings()[playerClass]
if not classSettings or classSettings[frameName] == nil then
return true
end
return classSettings[frameName]
end
local function ShouldHideFrame(frameName)
local override = GetCharacterOverride()
if override.enabled then
return override.frameSettings[frameName]
end
local _, playerClass = UnitClass("player")
return ShouldHideForClass(playerClass, frameName)
end
local hookedFrames = {}
local seenNaturalShow = {}
local function ApplySetting()
for _, frameName in ipairs(HideCoA.FRAMES) do
local frame = _G[frameName]
if frame then
if not hookedFrames[frameName] then
frame:HookScript("OnShow", function(self)
seenNaturalShow[frameName] = true
if ShouldHideFrame(frameName) then
self:Hide()
end
end)
hookedFrames[frameName] = true
end
local hide = ShouldHideFrame(frameName)
if hide then
frame:Hide()
elseif seenNaturalShow[frameName] then
-- The server never Show()s a frame the current class doesn't use,
-- so its data (powerType, maxValue, ...) is never populated. Forcing
-- Show() on it exposes that uninitialized state and crashes the
-- server's own OnUpdate handler. Only force-show a frame we've
-- already seen the game display naturally at least once.
frame:Show()
end
if frame.EnableMouse then
frame:EnableMouse(not hide)
end
end
end
end
HideCoA.ApplySetting = ApplySetting
f:RegisterEvent("ADDON_LOADED")
f:RegisterEvent("PLAYER_LOGIN")
f:SetScript("OnEvent", function(self, event, arg1)
if event == "ADDON_LOADED" and arg1 == "HideCoA" then
if not HideCoADB then
HideCoADB = {}
end
if not HideCoADB.profiles then
HideCoADB.profiles = {}
end
if not HideCoADB.charProfile then
HideCoADB.charProfile = {}
end
-- Legacy pre-profile saved variables stored a single flat classSettings
-- table shared by every character. Fold it into "Default" so nobody's
-- existing hide/show choices vanish when profiles were introduced.
if HideCoADB.classSettings and not HideCoADB.profiles["Default"] then
HideCoADB.profiles["Default"] = { classSettings = HideCoADB.classSettings }
end
HideCoADB.classSettings = nil
if not HideCoADB.profiles["Default"] then
HideCoADB.profiles["Default"] = { classSettings = CreateDefaultClassSettings() }
end
local charKey = GetCharacterKey()
-- The profile-name syntax used to be "realm - character"; rename any
-- existing profile created under that scheme to the new ordering
-- instead of leaving it orphaned in the list.
local oldCharKey = GetRealmName() .. " - " .. UnitName("player")
if HideCoADB.profiles[oldCharKey] and not HideCoADB.profiles[charKey] then
HideCoADB.profiles[charKey] = HideCoADB.profiles[oldCharKey]
HideCoADB.profiles[oldCharKey] = nil
end
if not HideCoADB.profiles[charKey] then
HideCoADB.profiles[charKey] = { classSettings = CreateDefaultClassSettings() }
end
for _, profile in pairs(HideCoADB.profiles) do
if not profile.classSettings then
profile.classSettings = CreateDefaultClassSettings()
end
EnsureClassSettingsComplete(profile.classSettings)
end
if not HideCoADB.charProfile[charKey] then
HideCoADB.charProfile[charKey] = charKey
end
EnsureCharacterOverride(charKey)
HideCoADB.selectedProfile = nil
elseif event == "PLAYER_LOGIN" then
ApplySetting()
end
end)