416 lines
14 KiB
Lua
416 lines
14 KiB
Lua
local _G = ShaguTweaks.GetGlobalEnv()
|
|
local T = ShaguTweaks.T
|
|
local HookAddonOrVariable = ShaguTweaks.HookAddonOrVariable
|
|
local GetExpansion = ShaguTweaks.GetExpansion
|
|
local AddBorder = ShaguTweaks.AddBorder
|
|
|
|
local module = ShaguTweaks:register({
|
|
title = T["Darkened UI"],
|
|
description = T["Turns the entire interface into darker colors."],
|
|
expansions = { ["vanilla"] = true },
|
|
category = T["Interface"],
|
|
enabled = nil,
|
|
config = {
|
|
["darkmode.color"] = { r = .3, g = .3, b = .3, a = .9 }
|
|
}
|
|
})
|
|
|
|
local blacklist = {
|
|
["Solid Texture"] = true,
|
|
["WHITE8X8"] = true,
|
|
["StatusBar"] = true,
|
|
["BarFill"] = true,
|
|
["Portrait"] = true,
|
|
["Button"] = true,
|
|
["Icon"] = true,
|
|
["AddOns"] = true,
|
|
["StationeryTest"] = true,
|
|
["TargetDead"] = true, -- LootFrame Icon
|
|
["^KeyRing"] = true, -- bag frame
|
|
["GossipIcon"] = true,
|
|
["WorldMap\\(.+)\\"] = true,
|
|
["PetHappiness"] = true,
|
|
["Elite"] = true,
|
|
["Rare"] = true,
|
|
["ColorPickerWheel"] = true,
|
|
["ComboPoint"] = true,
|
|
["Skull"] = true,
|
|
|
|
-- LFT:
|
|
["battlenetworking0"] = true,
|
|
["damage"] = true,
|
|
["tank"] = true,
|
|
["healer"] = true,
|
|
}
|
|
|
|
local regionskips = {
|
|
-- colorpicker gradient
|
|
["ColorPickerFrame"] = { [15] = true },
|
|
-- EQL3: background art tiles on the main frame - BookIcon(1), TopLeft(2), Top_Switch_Off(3), BottomLeft(4), Bottom_Switch_Off(5), Top_Switch_On(6), Bottom_Switch_On(7)
|
|
["EQL3_QuestLogFrame"] = { [1]=true, [2]=true, [3]=true, [4]=true, [5]=true, [6]=true, [7]=true },
|
|
-- EQL3: parchment tiles on the description panel - TopMiddle(1), TopRight(2), BottomMiddle(3), BottomRight(4)
|
|
["EQL3_QuestLogFrame_Description"] = { [1]=true, [2]=true, [3]=true, [4]=true },
|
|
}
|
|
|
|
local backgrounds = {
|
|
["^SpellBookFrame$"] = { 325, 355, 17, -74 },
|
|
["^ItemTextFrame$"] = { 300, 355, 24, -74 },
|
|
["^QuestLogDetailScrollFrame$"] = { QuestLogDetailScrollChildFrame:GetWidth(), QuestLogDetailScrollChildFrame:GetHeight(), 0, 0 },
|
|
["^QuestFrame(.+)Panel$"] = { 300, 330, 24, -82 },
|
|
["^GossipFrameGreetingPanel$"] = { 300, 330, 24, -82 },
|
|
}
|
|
|
|
local borders = {
|
|
["ShapeshiftButton"] = 3,
|
|
["BuffButton"] = 3,
|
|
["TargetFrameBuff"] = 3,
|
|
["TempEnchant"] = 3,
|
|
["SpellButton"] = 3,
|
|
["SpellBookSkillLineTab"] = 3,
|
|
["ActionButton%d+$"] = 3,
|
|
["MultiBar(.+)Button%d+$"] = 3,
|
|
["KeyRingButton"] = 2,
|
|
["ActionBarUpButton"] = -3,
|
|
["ActionBarDownButton"] = -3,
|
|
["MainMenuBarPerformanceBarFrameButton"] = { -12, -1, -8, 4 },
|
|
["Character(.+)Slot$"] = 3,
|
|
["Inspect(.+)Slot$"] = 3,
|
|
["ContainerFrame(.+)Item"] = 3,
|
|
["MainMenuBarBackpackButton$"] = 3,
|
|
["CharacterBag(.+)Slot$"] = 3,
|
|
["ChatFrame(.+)Button"] = -2,
|
|
["PetFrameHappiness"] = 2,
|
|
["MicroButton"] = { -21, 0, 0, 0 },
|
|
}
|
|
|
|
local addonframes = {
|
|
["Blizzard_TalentUI"] = { "TalentFrame" },
|
|
["Blizzard_AuctionUI"] = { "AuctionFrame", "AuctionDressUpFrame" },
|
|
["Blizzard_CraftUI"] = { "CraftFrame" },
|
|
["Blizzard_InspectUI"] = {
|
|
"InspectPaperDollFrame",
|
|
"InspectHonorFrame",
|
|
"InspectFrameTab1",
|
|
"InspectFrameTab2",
|
|
},
|
|
["Blizzard_MacroUI"] = { "MacroFrame", "MacroPopupFrame" },
|
|
["Blizzard_RaidUI"] = { "ReadyCheckFrame" },
|
|
["Blizzard_TradeSkillUI"] = { "TradeSkillFrame" },
|
|
["Blizzard_TrainerUI"] = { "ClassTrainerFrame" },
|
|
}
|
|
|
|
-- Turtle WoW exposes these extra inspect pages. Keep them out of the generic
|
|
-- Vanilla path so missing Turtle-only frames don't leave compatibility lurkers
|
|
-- registered for the whole session.
|
|
local isTurtle = TargetHPText and TargetHPPercText
|
|
if isTurtle then
|
|
table.insert(addonframes["Blizzard_InspectUI"], "InspectArenaFrame")
|
|
table.insert(addonframes["Blizzard_InspectUI"], "InspectTalentsFrame")
|
|
table.insert(addonframes["Blizzard_InspectUI"], "InspectFrameTab3")
|
|
table.insert(addonframes["Blizzard_InspectUI"], "InspectFrameTab4")
|
|
end
|
|
|
|
-- sizing is a bit different on tbc
|
|
if GetExpansion() == "tbc" then
|
|
borders["BuffButton"] = 2
|
|
borders["TempEnchant"] = 2
|
|
borders["MicroButton"] = { -21, 0, 0, 0 }
|
|
end
|
|
|
|
local function IsBlacklisted(texture)
|
|
local name = texture:GetName()
|
|
local texture = texture:GetTexture()
|
|
if not texture then return true end
|
|
|
|
if name then
|
|
for entry in pairs(blacklist) do
|
|
if string.find(name, entry, 1) then return true end
|
|
end
|
|
end
|
|
|
|
for entry in pairs(blacklist) do
|
|
if string.find(texture, entry, 1) then return true end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function AddSpecialBackground(frame, w, h, x, y)
|
|
frame.Material = frame.Material or frame:CreateTexture(nil, "OVERLAY")
|
|
frame.Material:SetTexture("Interface\\Stationery\\StationeryTest1")
|
|
frame.Material:SetWidth(w)
|
|
frame.Material:SetHeight(h)
|
|
frame.Material:SetPoint("TOPLEFT", frame, x, y)
|
|
frame.Material:SetVertexColor(.8, .8, .8)
|
|
end
|
|
|
|
local function DarkenFrame(frame, r, g, b, a)
|
|
-- dont't do anything if disabled
|
|
if not ShaguTweaks.DarkMode then return end
|
|
|
|
-- set defaults
|
|
if not r and not g and not b then
|
|
r, g, b, a = module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, module.config["darkmode.color"].a
|
|
end
|
|
|
|
-- iterate through all subframes
|
|
if frame and frame.GetChildren then
|
|
for _, frame in pairs({frame:GetChildren()}) do
|
|
DarkenFrame(frame, r, g, b, a)
|
|
end
|
|
end
|
|
|
|
-- set vertex on all regions
|
|
if frame and frame.GetRegions then
|
|
-- read name
|
|
local name = frame.GetName and frame:GetName()
|
|
|
|
-- set a dark backdrop border color everywhere
|
|
frame:SetBackdropBorderColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, module.config["darkmode.color"].a)
|
|
|
|
-- add special backgrounds to quests and such
|
|
for pattern, inset in pairs(backgrounds) do
|
|
if name and string.find(name, pattern) then AddSpecialBackground(frame, inset[1], inset[2], inset[3], inset[4]) end
|
|
end
|
|
|
|
-- add black borders around specified buttons
|
|
for pattern, inset in pairs(borders) do
|
|
if name and string.find(name, pattern) then AddBorder(frame, inset, module.config["darkmode.color"]) end
|
|
end
|
|
|
|
-- scan through all regions (textures)
|
|
for id, region in pairs({frame:GetRegions()}) do
|
|
if region.SetVertexColor and region:GetObjectType() == "Texture" then
|
|
if region:GetTexture() and string.find(region:GetTexture(), "UI%-Panel%-Button%-Up") then
|
|
-- monochrome buttons
|
|
-- region:SetDesaturated(true)
|
|
elseif name and id and regionskips[name] and regionskips[name][id] then
|
|
-- skip special regions
|
|
elseif region.GetBlendMode and region:GetBlendMode() == "ADD" then
|
|
-- skip blend over textures
|
|
elseif IsBlacklisted(region) then
|
|
-- skip blacklisted texture names
|
|
else
|
|
region:SetVertexColor(r,g,b,a)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- register darken frame to global
|
|
ShaguTweaks.DarkenFrame = DarkenFrame
|
|
|
|
module.enable = function(self)
|
|
ShaguTweaks.DarkMode = true
|
|
|
|
local name, original, r, g, b
|
|
local hookBuffButton_Update = BuffButton_Update
|
|
function BuffButton_Update(buttonName, index, filter)
|
|
hookBuffButton_Update(buttonName, index, filter)
|
|
|
|
-- tbc passes buttonName and index arguments, vanilla uses "this" context
|
|
name = buttonName and index and buttonName .. index or this:GetName()
|
|
original = _G[name.."Border"]
|
|
|
|
if original and this.ShaguTweaks_border then
|
|
r, g, b = original:GetVertexColor()
|
|
this.ShaguTweaks_border:SetBackdropBorderColor(r, g, b, 1)
|
|
original:SetAlpha(0)
|
|
elseif not original and _G[name] then
|
|
-- tbc buff buttons don't have borders, so we
|
|
-- need to manually add a dark one.
|
|
AddBorder(_G[name], 2, module.config["darkmode.color"])
|
|
end
|
|
end
|
|
|
|
TOOLTIP_DEFAULT_COLOR.r = module.config["darkmode.color"].r
|
|
TOOLTIP_DEFAULT_COLOR.g = module.config["darkmode.color"].g
|
|
TOOLTIP_DEFAULT_COLOR.b = module.config["darkmode.color"].b
|
|
|
|
TOOLTIP_DEFAULT_BACKGROUND_COLOR.r = module.config["darkmode.color"].r
|
|
TOOLTIP_DEFAULT_BACKGROUND_COLOR.g = module.config["darkmode.color"].g
|
|
TOOLTIP_DEFAULT_BACKGROUND_COLOR.b = module.config["darkmode.color"].b
|
|
|
|
DarkenFrame(UIParent)
|
|
DarkenFrame(WorldMapFrame)
|
|
DarkenFrame(DropDownList1)
|
|
DarkenFrame(DropDownList2)
|
|
DarkenFrame(DropDownList3)
|
|
|
|
-- align all actionbutton textures
|
|
local bars = { "Action", "BonusAction", "MultiBarBottomLeft", "MultiBarBottomRight", "MultiBarLeft", "MultiBarRight", "Shapeshift" }
|
|
for _, prefix in pairs(bars) do
|
|
for i = 1, NUM_ACTIONBAR_BUTTONS do
|
|
local button = _G[prefix .. "Button" .. i]
|
|
local texture = _G[prefix.."Button"..i.."NormalTexture"]
|
|
|
|
if button and texture then
|
|
texture:SetWidth(60)
|
|
texture:SetHeight(60)
|
|
texture:SetPoint("CENTER", 0, 0)
|
|
ShaguTweaks.AddBorder(button, 3)
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, button in pairs({ MinimapZoomOut, MinimapZoomIn }) do
|
|
for _, func in pairs({ "GetNormalTexture", "GetDisabledTexture", "GetPushedTexture" }) do
|
|
if button[func] then
|
|
local tex = button[func](button)
|
|
if tex then
|
|
tex:SetVertexColor(module.config["darkmode.color"].r+.2, module.config["darkmode.color"].g+.2, module.config["darkmode.color"].b+.2, 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
HookAddonOrVariable("Blizzard_AuctionUI", function()
|
|
for i = 1, 15 do
|
|
local tex = _G["AuctionFilterButton"..i]:GetNormalTexture()
|
|
tex:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
|
end
|
|
|
|
for i = 1, 8 do
|
|
_G["BrowseButton"..i.."Left"]:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
|
_G["BrowseButton"..i.."Right"]:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
|
end
|
|
end)
|
|
|
|
for addon, data in pairs(addonframes) do
|
|
for _, frame in pairs(data) do
|
|
local frame = frame
|
|
HookAddonOrVariable(frame, function()
|
|
DarkenFrame(_G[frame])
|
|
end)
|
|
end
|
|
end
|
|
|
|
-- Turtle's inspect talent tree is rebuilt by TWTalentFrame_Update().
|
|
-- Its background textures are assigned during that update, so the initial
|
|
-- InspectTalentsFrame pass may happen too early. Re-darken the parent after
|
|
-- each rebuild; it already contains TWTalentFrame, so one recursive scan is
|
|
-- sufficient and avoids traversing the same tree twice.
|
|
if isTurtle then
|
|
HookAddonOrVariable("TWTalentFrame", function()
|
|
if not _G.TWTalentFrame or not _G.TWTalentFrame_Update then return end
|
|
|
|
if not _G.TWTalentFrame.ShaguTweaksDarkHook then
|
|
_G.TWTalentFrame.ShaguTweaksDarkHook = true
|
|
ShaguTweaks.hooksecurefunc("TWTalentFrame_Update", function()
|
|
DarkenFrame(_G.InspectTalentsFrame or _G.TWTalentFrame)
|
|
end)
|
|
end
|
|
|
|
DarkenFrame(_G.InspectTalentsFrame or _G.TWTalentFrame)
|
|
end)
|
|
end
|
|
|
|
HookAddonOrVariable("Blizzard_TimeManager", function()
|
|
DarkenFrame(TimeManagerClockButton)
|
|
end)
|
|
|
|
HookAddonOrVariable("GameTooltipStatusBarBackdrop", function()
|
|
DarkenFrame(_G["GameTooltipStatusBarBackdrop"])
|
|
end)
|
|
|
|
-- Prefer BlizzNameplatesPlus' own nameplate provider whenever available.
|
|
-- This is capability-based instead of version-based, so BNP updates keep
|
|
-- working as long as its public libnameplate callback API remains available.
|
|
local bnpNameplates = BNP
|
|
and BNP.libnameplate
|
|
and BNP.libnameplate.OnInit
|
|
and BNP.libnameplate.OnShow
|
|
|
|
if bnpNameplates then
|
|
local pending = {}
|
|
local updater = CreateFrame("Frame")
|
|
|
|
local function StopUpdaterIfIdle()
|
|
if not next(pending) then
|
|
updater:SetScript("OnUpdate", nil)
|
|
end
|
|
end
|
|
|
|
local function ReapplyBNPDarkMode(plate)
|
|
plate = plate or this
|
|
if not plate or not plate:IsShown() then return end
|
|
if plate.darkened then return end
|
|
|
|
plate.darkened = true
|
|
DarkenFrame(plate)
|
|
|
|
-- Blizzard can restore some nameplate textures immediately after OnShow.
|
|
-- Queue one delayed pass, then stop completely. If BNP's own Shagu
|
|
-- compatibility already darkened the plate first, the marker above makes
|
|
-- this path a no-op and avoids duplicate work.
|
|
pending[plate] = GetTime() + 0.08
|
|
if not updater:GetScript("OnUpdate") then
|
|
updater:SetScript("OnUpdate", function()
|
|
local now = GetTime()
|
|
local current, due
|
|
for current, due in pairs(pending) do
|
|
if now >= due then
|
|
pending[current] = nil
|
|
if current and current:IsShown() then
|
|
current.darkened = nil
|
|
DarkenFrame(current)
|
|
current.darkened = true
|
|
end
|
|
end
|
|
end
|
|
StopUpdaterIfIdle()
|
|
end)
|
|
end
|
|
end
|
|
|
|
table.insert(BNP.libnameplate.OnInit, ReapplyBNPDarkMode)
|
|
table.insert(BNP.libnameplate.OnShow, ReapplyBNPDarkMode)
|
|
else
|
|
-- Native ShaguTweaks nameplates only need darkening when a plate is first
|
|
-- discovered or shown. Avoid keeping a per-frame libnameplate callback
|
|
-- alive just to test the permanent "darkened" marker.
|
|
local pending = {}
|
|
local updater = CreateFrame("Frame")
|
|
|
|
local function StopUpdaterIfIdle()
|
|
if not next(pending) then
|
|
updater:SetScript("OnUpdate", nil)
|
|
end
|
|
end
|
|
|
|
local function ReapplyShaguDarkMode(plate)
|
|
plate = plate or this
|
|
if not plate or not plate:IsShown() then return end
|
|
|
|
plate.darkened = nil
|
|
DarkenFrame(plate)
|
|
plate.darkened = true
|
|
|
|
-- Some clients restore nameplate textures immediately after OnShow.
|
|
-- Re-apply once after that short window, then stop completely.
|
|
pending[plate] = GetTime() + 0.08
|
|
if not updater:GetScript("OnUpdate") then
|
|
updater:SetScript("OnUpdate", function()
|
|
local now = GetTime()
|
|
local current, due
|
|
for current, due in pairs(pending) do
|
|
if now >= due then
|
|
pending[current] = nil
|
|
if current and current:IsShown() then
|
|
current.darkened = nil
|
|
DarkenFrame(current)
|
|
current.darkened = true
|
|
end
|
|
end
|
|
end
|
|
StopUpdaterIfIdle()
|
|
end)
|
|
end
|
|
end
|
|
|
|
table.insert(ShaguTweaks.libnameplate.OnInit, ReapplyShaguDarkMode)
|
|
table.insert(ShaguTweaks.libnameplate.OnShow, ReapplyShaguDarkMode)
|
|
end
|
|
end
|