102 lines
4.6 KiB
C#
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;
|
|
}
|
|
}
|