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 } } }) -- Golden UI runs the same recolor pass with a gold palette (like the WoW -- Forever client): textures are tinted gold, borders and tooltip edges get a -- softer gold, and backgrounds keep their own colors. local golden = ShaguTweaks:register({ title = T["Golden UI"], description = T["Turns the borders of the interface, tooltips and dialogs gold, like the WoW Forever client. Darkened UI takes priority when both are enabled."], expansions = { ["vanilla"] = true }, category = T["Interface"], enabled = nil, config = { ["goldmode.color"] = { r = 1, g = .78, b = .4, a = 1 }, ["goldmode.border"] = { r = .8, g = .62, b = .32, a = 1 }, ["goldmode.text"] = { r = .84, g = .72, b = .48, a = 1 }, ["goldmode.bar"] = { r = .8, g = .63, b = .62, a = 1 }, } }) -- Active palette, set by whichever of the two modules is enabled: -- tint goes on textures, edge on backdrop borders and added button borders. local tint, edge 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 }, -- the mail inbox uses the same parchment art as ItemTextFrame; the send -- page already has its own stationery on top ["^InboxFrame$"] = { 300, 355, 24, -74 }, } 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 }, -- VCB's buff and weapon-buff buttons, like the Blizzard buff buttons ["^VCB_BF_BUFF_BUTTON%d+$"] = 3, ["^VCB_BF_WEAPON_BUTTON%d+$"] = 3, } 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" }, ["Artisan"] = { "ArtisanFrame" }, } -- 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 -- Frame art that ships inside an addon (the "AddOns" entry above skips -- addon textures, which are mostly icons) but should follow the palette. local whitelist = { "outfitter\\textures\\outfitterframe", "outfitter\\textures\\scrollbartrench", -- Artisan swaps in its own lower half of the profession window "artisan\\textures\\bottomleft", "artisan\\textures\\bottomright", -- RollFor's classic loot window "rollfor\\assets\\og-loot-frame", } -- Addon windows that build their rows while opening: recolored every time -- they are shown (and once more on the next frame, after the rows exist). local showframes = { ["RollForLootFrameHeader"] = true, } local function IsBlacklisted(texture) local name = texture:GetName() local texture = texture:GetTexture() if not texture then return true end local lower = string.lower(texture) for i = 1, table.getn(whitelist) do if string.find(lower, whitelist[i], 1, true) then return nil end 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 neither Darkened UI nor Golden UI is enabled if not tint then return end -- set defaults if not r and not g and not b then r, g, b, a = tint.r, tint.g, tint.b, tint.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 the palette's backdrop border color everywhere frame:SetBackdropBorderColor(edge.r, edge.g, edge.b, edge.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, edge) 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 -- Other addons that draw their own tooltip-style borders. Their frames (and -- everything inside them) keep following the palette even when the addon -- sets its border color again later, or builds a window only when opened. local ADDON_PREFIXES = { "ShaguDPS", "Bagshui", "Outfitter", "SoulstoneTracker", "SSWarlock", "SSTClassic", "SSTracker", "TrinketMenu", "OctoBus", "RollFor", "VCB_", } local function IsAddonFrameName(name) if not name then return end for i = 1, table.getn(ADDON_PREFIXES) do if string.find(name, ADDON_PREFIXES[i], 1, true) == 1 then return true end end end -- Only light grey/white/silver borders follow the palette. Colored borders -- (item quality, hover highlights, class or theme colors) and dark ones stay -- as the addon set them. local function IsLightNeutral(r, g, b) r, g, b = tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0 local hi, lo = math.max(r, g, b), math.min(r, g, b) return hi - lo < .1 and hi >= .35 end local function LockBorder(frame) if not frame or frame.stBorderLock or not frame.SetBackdropBorderColor then return end frame.stBorderLock = true local setColor, setBackdrop = frame.SetBackdropBorderColor, frame.SetBackdrop frame.SetBackdropBorderColor = function(self, r, g, b, a) if IsLightNeutral(r, g, b) then setColor(self, edge.r, edge.g, edge.b, a or 1) else setColor(self, r, g, b, a) end end -- a new backdrop starts with a white border if setBackdrop then frame.SetBackdrop = function(self, backdrop) setBackdrop(self, backdrop) if backdrop and backdrop.edgeFile then setColor(self, edge.r, edge.g, edge.b, 1) end end end -- run the current color through the filter once if frame.GetBackdropBorderColor then local ok, r, g, b, a = pcall(frame.GetBackdropBorderColor, frame) if ok and r then frame:SetBackdropBorderColor(r, g, b, a) end end end -- Border textures (VCB's buff and weapon borders): same rule, on the -- texture's vertex color. local function LockTextureBorder(texture) if texture.stBorderLock or not texture.SetVertexColor then return end texture.stBorderLock = true local setColor = texture.SetVertexColor texture.SetVertexColor = function(self, r, g, b, a) if IsLightNeutral(r, g, b) then setColor(self, edge.r, edge.g, edge.b, a or 1) else setColor(self, r, g, b, a) end end if texture.GetVertexColor then local ok, r, g, b, a = pcall(texture.GetVertexColor, texture) if ok and r then texture:SetVertexColor(r, g, b, a) end end end local function LockTree(frame) if not frame then return end LockBorder(frame) if frame.GetRegions then local regions = { frame:GetRegions() } for i = 1, table.getn(regions) do local region = regions[i] local name = region.GetName and region:GetName() if name and string.find(name, "Border$") and region.GetObjectType and region:GetObjectType() == "Texture" then LockTextureBorder(region) end end end if frame.GetChildren then local children = { frame:GetChildren() } for i = 1, table.getn(children) do LockTree(children[i]) end end end -- find the addon frames that exist already, anywhere below UIParent local function FindAddonFrames(frame) local children = { frame:GetChildren() } for i = 1, table.getn(children) do local child = children[i] if IsAddonFrameName(child.GetName and child:GetName()) then LockTree(child) else FindAddonFrames(child) end end end -- The round border of addon minimap buttons (most use the stock tracking -- border texture). Those buttons are often made after login. local function TintMinimapButton(frame) if not frame or not frame.GetRegions then return end local regions = { frame:GetRegions() } for i = 1, table.getn(regions) do local region = regions[i] local texture = region.GetTexture and region:GetTexture() if texture and string.find(string.lower(texture), "minimap%-trackingborder") then region:SetVertexColor(tint.r, tint.g, tint.b, 1) end end end local function RecolorOnShow(frame) if not frame or frame.stRecolorOnShow then return end frame.stRecolorOnShow = true if golden.rollforLoot and frame:GetName() == "RollForLootFrameHeader" then golden.rollforLoot(frame) end ShaguTweaks.HookScript(frame, "OnShow", function() DarkenFrame(frame) if _G.C_Timer and _G.C_Timer.After then _G.C_Timer.After(0, function() DarkenFrame(frame) end) end end) if frame:IsShown() then DarkenFrame(frame) end end local function LockAddonFrames() FindAddonFrames(UIParent) for name in pairs(showframes) do RecolorOnShow(_G[name]) end if Minimap then local buttons = { Minimap:GetChildren() } for i = 1, table.getn(buttons) do TintMinimapButton(buttons[i]) end end -- frames those addons create later: named after the addon, or created -- inside one of their frames (templates bring their children along) local create = CreateFrame CreateFrame = function(a1, a2, a3, a4, a5, a6) local frame = create(a1, a2, a3, a4, a5, a6) if frame and (IsAddonFrameName(a2) or (type(a3) == "table" and a3.stBorderLock)) then LockTree(frame) end if frame and type(a2) == "string" and showframes[a2] then RecolorOnShow(frame) end -- buttons that get an extra border (VCB buffs made after login) if frame and type(a2) == "string" then for pattern, inset in pairs(borders) do if string.find(a2, pattern) then AddBorder(frame, inset, edge) end end end -- minimap buttons get their border texture right after they are made if frame and a3 and a3 == Minimap then if _G.C_Timer and _G.C_Timer.After then _G.C_Timer.After(0, function() TintMinimapButton(frame) end) end end return frame end end local function Apply(tintColor, edgeColor, darkBackgrounds) if tint then return end tint, edge = tintColor, edgeColor ShaguTweaks.UITint = tint ShaguTweaks.UIBorder = edge 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, edge) end end TOOLTIP_DEFAULT_COLOR.r = edge.r TOOLTIP_DEFAULT_COLOR.g = edge.g TOOLTIP_DEFAULT_COLOR.b = edge.b -- Darkened UI also greys the tooltip background; Golden UI keeps it. if darkBackgrounds then TOOLTIP_DEFAULT_BACKGROUND_COLOR.r = tint.r TOOLTIP_DEFAULT_BACKGROUND_COLOR.g = tint.g TOOLTIP_DEFAULT_BACKGROUND_COLOR.b = tint.b end DarkenFrame(UIParent) DarkenFrame(WorldMapFrame) DarkenFrame(DropDownList1) DarkenFrame(DropDownList2) DarkenFrame(DropDownList3) LockAddonFrames() -- the loot window gets its art set again when it opens if LootFrame then ShaguTweaks.HookScript(LootFrame, "OnShow", function() DarkenFrame(LootFrame) end) end -- 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(math.min(tint.r+.2, 1), math.min(tint.g+.2, 1), math.min(tint.b+.2, 1), 1) end end end end HookAddonOrVariable("Blizzard_AuctionUI", function() for i = 1, 15 do local tex = _G["AuctionFilterButton"..i]:GetNormalTexture() tex:SetVertexColor(tint.r, tint.g, tint.b, 1) end for i = 1, 8 do _G["BrowseButton"..i.."Left"]:SetVertexColor(tint.r, tint.g, tint.b, 1) _G["BrowseButton"..i.."Right"]:SetVertexColor(tint.r, tint.g, tint.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 module.enable = function(self) ShaguTweaks.DarkMode = true Apply(module.config["darkmode.color"], module.config["darkmode.color"], true) end -- Title bars: the dark strips the window titles sit on. Golden UI -- multiplies them toward WoW Forever's red-brown with a MOD layer. Measured -- from the window art: rows below the frame's top edge, and how far the strip -- runs from the left (after the portrait) and from the right (before the -- close button). local STRIP_A = { 72, -16, -60, -34 } -- character, spellbook, mail, quest log art local STRIP_B = { 72, -15, -62, -33 } -- merchant, friends art local function Shade(parent, layer, color) local shade = parent:CreateTexture(nil, layer) shade:SetTexture(1, 1, 1, 1) shade:SetVertexColor(tonumber(color.r) or .8, tonumber(color.g) or .63, tonumber(color.b) or .62, 1) shade:SetBlendMode("MOD") return shade end local function PlaceStrip(shade, frame, strip) shade:ClearAllPoints() shade:SetPoint("TOPLEFT", frame, "TOPLEFT", strip[1], strip[2]) shade:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", strip[3], strip[4]) end -- The shade has to sit above the window art, which would darken a title -- that is drawn in the same frame. Those titles are drawn again on top and -- the original is kept, invisible, for its position and text. local function RedrawTitle(holder, title, gold) if not title then return end local copy = holder:CreateFontString(nil, "OVERLAY", "GameFontNormal") local font = not gold and title.GetFontObject and title:GetFontObject() if font then copy:SetFontObject(font) end -- titles drawn in white (Turtle's quest log) get the same gold as the rest if gold and NORMAL_FONT_COLOR then copy:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) end copy:SetAllPoints(title) if title.GetJustifyH then copy:SetJustifyH(title:GetJustifyH()) end copy:SetText(title:GetText()) title:SetAlpha(0) local setText = title.SetText title.SetText = function(self, text) setText(self, text) copy:SetText(text) end return copy end local function ShadeTitleBar(frame, strip, title, color, level, gold) if not frame or frame.stTitleBar then return end local bar = CreateFrame("Frame", nil, frame) bar:SetAllPoints(frame) if level then bar:SetFrameLevel(level) end frame.stTitleBar = bar bar.shade = Shade(bar, "BACKGROUND", color) PlaceStrip(bar.shade, frame, strip) bar.title = RedrawTitle(bar, title, gold) return bar end -- frames whose titles live in child frames (or above the art layer): the -- shade is a plain texture in the window itself, nothing to redraw local function ShadeStripInFrame(frame, strip, layer, color) if not frame or frame.stTitleShade then return end frame.stTitleShade = Shade(frame, layer, color) PlaceStrip(frame.stTitleShade, frame, strip) end local function ShadeTitleBars(color) -- world map: its strip is 3 to 21 px below the top of its art (384 above -- the frame center), from the left corner to the window buttons if WorldMapFrame and WorldMapFrameTitle and not WorldMapFrame.stTitleBar then local bar = ShadeTitleBar(WorldMapFrame, { 0, 0, 0, 0 }, WorldMapFrameTitle, color) bar.shade:ClearAllPoints() bar.shade:SetPoint("TOPLEFT", WorldMapFrame, "CENTER", -510, 381) bar.shade:SetPoint("BOTTOMRIGHT", WorldMapFrame, "CENTER", 455, 363) -- the stone art is lighter around the seam of its first two pieces -- (measured in 8 px columns): darken those columns a bit more so the -- bar comes out even local even = { { -272, .81 }, { -264, .76 }, { -256, .66 }, { -248, .52 }, { -240, .49 }, { -232, .47 }, { -224, .53 }, { -216, .54 }, { -208, .52 }, { -200, .58 }, { -192, .69 }, { -184, .76 }, { -176, .68 }, { -168, .68 }, { -160, .69 }, { -152, .71 }, { -144, .78 }, { -136, .86 }, } for i = 1, table.getn(even) do local x, f = even[i][1], even[i][2] local fix = Shade(bar, "BACKGROUND", { r = f, g = f, b = f }) fix:SetPoint("TOPLEFT", WorldMapFrame, "CENTER", x, 381) fix:SetPoint("BOTTOMRIGHT", WorldMapFrame, "CENTER", x + 8, 363) end end ShadeTitleBar(MerchantFrame, STRIP_B, MerchantNameText, color) ShadeTitleBar(SpellBookFrame, STRIP_A, SpellBookTitleText, color) ShadeTitleBar(FriendsFrame, STRIP_B, FriendsFrameTitleText, color) -- the quest log is wider: its strip ends before the close button ShadeTitleBar(QuestLogFrame, { 72, -16, -121, -34 }, QuestLogTitleText, color, nil, true) -- mail: the art is on the BORDER layer, the titles are on the page frames ShadeStripInFrame(MailFrame, STRIP_A, "ARTWORK", color) -- character: the art is on the tab pages (PaperDollFrame and the others), -- the name on CharacterNameFrame. The shade goes between the two. if CharacterFrame and PaperDollFrame and CharacterNameFrame then local level = PaperDollFrame:GetFrameLevel() + 1 if CharacterNameFrame:GetFrameLevel() <= level then CharacterNameFrame:SetFrameLevel(level + 1) end ShadeTitleBar(CharacterFrame, STRIP_A, nil, color, level) end end -- RollFor's classic loot window: the art is on the BACKGROUND layer and the -- "Items" title on ARTWORK, so the shade fits between them. The strip runs -- 12 to 30 px down, from the portrait to 25 px before the right edge (the -- window width changes with the item names). local function ShadeRollForLoot(frame, color) ShadeStripInFrame(frame, { 68, -12, -25, -30 }, "BORDER", color) end golden.enable = function(self) -- Both recolor the same textures; Darkened UI wins when both are ticked. if ShaguTweaks_config and ShaguTweaks_config[T["Darkened UI"]] == 1 then return end ShaguTweaks.GoldMode = true Apply(golden.config["goldmode.color"], golden.config["goldmode.border"], false) -- the softer, browner gold of WoW Forever's titles and labels instead of -- the stock bright yellow (every text that uses the "normal" gold font) local text = golden.config["goldmode.text"] local r, g, b = tonumber(text.r) or .84, tonumber(text.g) or .72, tonumber(text.b) or .48 if NORMAL_FONT_COLOR then NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b = r, g, b end local fonts = { "GameFontNormal", "GameFontNormalSmall", "GameFontNormalLarge", "GameFontNormalHuge" } for i = 1, table.getn(fonts) do local font = _G[fonts[i]] if font and font.SetTextColor then font:SetTextColor(r, g, b) end end ShadeTitleBars(golden.config["goldmode.bar"]) golden.rollforLoot = function(frame) ShadeRollForLoot(frame, golden.config["goldmode.bar"]) end if _G.RollForLootFrameHeader then golden.rollforLoot(_G.RollForLootFrameHeader) end end