Files
Taskbar-Launcher/Services/ThemeService.cs
2026-08-25 17:22:26 -04:00

102 lines
4.6 KiB
C#

using System.Windows;
using System.Windows.Media;
using Microsoft.Win32;
using MediaColor = System.Windows.Media.Color;
namespace TaskbarLauncher.Services;
public static class ThemeService
{
private const string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private const string DwmKey = @"Software\Microsoft\Windows\DWM";
public static void Apply()
{
bool isLight = IsLightTheme();
MediaColor accent = GetAccentColor();
MediaColor orange = MediaColor.FromRgb(0xD8, 0x78, 0x1D);
MediaColor window = isLight ? MediaColor.FromRgb(0xF6, 0xF1, 0xEA) : MediaColor.FromRgb(0x18, 0x16, 0x14);
MediaColor surface = isLight ? MediaColor.FromRgb(0xFF, 0xFC, 0xF8) : MediaColor.FromRgb(0x22, 0x1F, 0x1B);
MediaColor panel = isLight ? MediaColor.FromRgb(0xFF, 0xF7, 0xEE) : MediaColor.FromRgb(0x2A, 0x24, 0x1E);
MediaColor control = isLight ? MediaColor.FromRgb(0xFA, 0xF1, 0xE7) : MediaColor.FromRgb(0x32, 0x2B, 0x24);
MediaColor hover = isLight ? MediaColor.FromRgb(0xFF, 0xED, 0xDA) : MediaColor.FromRgb(0x42, 0x34, 0x28);
MediaColor text = isLight ? MediaColor.FromRgb(0x24, 0x1D, 0x17) : MediaColor.FromRgb(0xF8, 0xF2, 0xEA);
MediaColor muted = isLight ? MediaColor.FromRgb(0x75, 0x68, 0x5C) : MediaColor.FromRgb(0xC3, 0xB5, 0xA6);
MediaColor border = isLight ? MediaColor.FromRgb(0xE4, 0xD1, 0xBC) : MediaColor.FromRgb(0x5B, 0x4B, 0x3C);
MediaColor accentSoft = Blend(accent, surface, isLight ? 0.14 : 0.24);
MediaColor orangeSoft = Blend(orange, surface, isLight ? 0.16 : 0.30);
MediaColor selectedText = IsDark(accent) ? System.Windows.Media.Colors.White : System.Windows.Media.Colors.Black;
SetBrush("AppWindowBrush", window);
SetBrush("AppSurfaceBrush", surface);
SetBrush("AppPanelBrush", panel);
SetBrush("AppControlBrush", control);
SetBrush("AppControlHoverBrush", hover);
SetBrush("AppTextBrush", text);
SetBrush("AppMutedTextBrush", muted);
SetBrush("AppBorderBrush", border);
SetBrush("AppAccentBrush", accent);
SetBrush("AppAccentSoftBrush", accentSoft);
SetBrush("AppOrangeBrush", orange);
SetBrush("AppOrangeSoftBrush", orangeSoft);
SetBrush("AppSelectedTextBrush", selectedText);
SetBrush(System.Windows.SystemColors.WindowBrushKey, surface);
SetBrush(System.Windows.SystemColors.WindowTextBrushKey, text);
SetBrush(System.Windows.SystemColors.ControlBrushKey, control);
SetBrush(System.Windows.SystemColors.ControlTextBrushKey, text);
SetBrush(System.Windows.SystemColors.ControlDarkBrushKey, border);
SetBrush(System.Windows.SystemColors.HighlightBrushKey, accent);
SetBrush(System.Windows.SystemColors.HighlightTextBrushKey, selectedText);
}
private static bool IsLightTheme()
{
object? value = Registry.CurrentUser.OpenSubKey(PersonalizeKey)?.GetValue("AppsUseLightTheme");
return value is null || Convert.ToInt32(value) != 0;
}
private static MediaColor GetAccentColor()
{
object? value = Registry.CurrentUser.OpenSubKey(DwmKey)?.GetValue("AccentColor");
if (value is int colorValue)
{
byte r = (byte)(colorValue & 0xFF);
byte g = (byte)((colorValue >> 8) & 0xFF);
byte b = (byte)((colorValue >> 16) & 0xFF);
return MediaColor.FromRgb(r, g, b);
}
return MediaColor.FromRgb(0x00, 0x78, 0xD4);
}
private static MediaColor Blend(MediaColor foreground, MediaColor background, double foregroundAmount)
{
double amount = Math.Clamp(foregroundAmount, 0, 1);
byte r = (byte)Math.Round((foreground.R * amount) + (background.R * (1 - amount)));
byte g = (byte)Math.Round((foreground.G * amount) + (background.G * (1 - amount)));
byte b = (byte)Math.Round((foreground.B * amount) + (background.B * (1 - amount)));
return MediaColor.FromRgb(r, g, b);
}
private static void SetBrush(string key, MediaColor color)
{
SolidColorBrush brush = new(color);
brush.Freeze();
System.Windows.Application.Current.Resources[key] = brush;
}
private static void SetBrush(ResourceKey key, MediaColor color)
{
SolidColorBrush brush = new(color);
brush.Freeze();
System.Windows.Application.Current.Resources[key] = brush;
}
private static bool IsDark(MediaColor color)
{
double luminance = (0.299 * color.R) + (0.587 * color.G) + (0.114 * color.B);
return luminance < 140;
}
}