Files
ShrlAlgoToolkit/WPFluent/Appearance/ApplicationThemeManager.cs
2025-04-24 20:56:44 +08:00

157 lines
5.0 KiB
C#

using WPFluent.Controls;
using WPFluent.Extensions;
namespace WPFluent.Appearance;
/// <summary>
/// 允许通过交换包含动态资源的资源字典来管理应用程序主题。
/// </summary>
/// <example>
/// <code lang="csharp"> ApplicationThemeManager.Apply( ApplicationTheme.Light );</code> <code lang="csharp"> if
/// (ApplicationThemeManager.GetAppTheme() == ApplicationTheme.Dark) { ApplicationThemeManager.Apply(
/// ApplicationTheme.Light ); }</code> <code> ApplicationThemeManager.Changed += (theme, accent) => {
/// Debug.WriteLine($"Application theme changed to {theme.ToString()}"); };</code>
/// </example>
public static class ApplicationThemeManager
{
internal const string LibraryNamespace = "WPFluent;";
public const string ThemesDictionaryPath = "pack://application:,,,/WPFluent;component/Themes/";
private static ApplicationTheme _cachedApplicationTheme = ApplicationTheme.Unknown;
/// <summary>
/// Event triggered when the application's theme is changed.
/// </summary>
public static event ThemeChangedEvent? Changed;
/// <summary>
/// 尝试猜测当前设置的应用程序主题。
/// </summary>
private static void FetchApplicationTheme()
{
ResourceDictionaryManager appDictionaries = new(LibraryNamespace);
ResourceDictionary? themeDictionary = appDictionaries.GetDictionary("themes");
if (themeDictionary == null)
{
return;
}
var themeUri = themeDictionary.Source.ToString();
if (themeUri.Contains("light", StringComparison.OrdinalIgnoreCase))
{
_cachedApplicationTheme = ApplicationTheme.Light;
}
if (themeUri.Contains("dark", StringComparison.OrdinalIgnoreCase))
{
_cachedApplicationTheme = ApplicationTheme.Dark;
}
}
/// <summary>
/// 将资源应用于 <paramref name="frameworkElement"/>.
/// </summary>
public static void Apply(FrameworkElement frameworkElement)
{
if (frameworkElement.Resources.MergedDictionaries.Count <
UiApplication.Current.Resources.MergedDictionaries.Count)
{
foreach (var dictionary in UiApplication.Current.Resources.MergedDictionaries)
{
frameworkElement.Resources.MergedDictionaries.Add(dictionary);
}
}
}
/// <summary>
/// 更改当前应用程序主题。
/// </summary>
/// <param name="applicationTheme">Theme to set.</param>
/// <param name="backgroundEffect">Whether the custom background effect should be applied.</param>
/// <param name="updateAccent">Whether the color accents should be changed.</param>
public static void Apply(
ApplicationTheme applicationTheme,
WindowBackdropType backgroundEffect = WindowBackdropType.Mica,
bool updateAccent = true)
{
if (updateAccent)
{
//TODO
ApplicationAccentColorManager.Apply(
Color.FromRgb(194, 115, 37),
applicationTheme,
false);
}
if (applicationTheme == ApplicationTheme.Unknown)
{
return;
}
ResourceDictionaryManager appDictionaries = new(LibraryNamespace);
string themeDictionaryName = "Light";
switch (applicationTheme)
{
case ApplicationTheme.Dark:
themeDictionaryName = "Dark";
break;
case ApplicationTheme.Auto:
break;
case ApplicationTheme.Unknown:
break;
case ApplicationTheme.Light:
themeDictionaryName = "Light";
break;
case ApplicationTheme.HC1:
themeDictionaryName = "HC1";
break;
case ApplicationTheme.HC2:
themeDictionaryName = "HC2";
break;
case ApplicationTheme.HCBlack:
themeDictionaryName = "HCBlack";
break;
case ApplicationTheme.HCWhite:
themeDictionaryName = "HCWhite";
break;
}
if (!appDictionaries.UpdateDictionary(
"themes",
new Uri($"{ThemesDictionaryPath}{themeDictionaryName}.xaml", UriKind.Absolute)))
{
return;
}
_cachedApplicationTheme = applicationTheme;
Changed?.Invoke(applicationTheme, ApplicationAccentColorManager.SystemAccent);
if (UiApplication.Current.MainWindow is Window mainWindow)
{
WindowBackgroundManager.UpdateBackground(mainWindow, applicationTheme, backgroundEffect);
}
}
/// <summary>
/// 获取当前设置的应用程序主题。
/// </summary>
/// <returns><see cref="ApplicationTheme.Unknown"/> if something goes wrong.</returns>
public static ApplicationTheme GetAppTheme()
{
if (_cachedApplicationTheme == ApplicationTheme.Unknown)
{
FetchApplicationTheme();
}
return _cachedApplicationTheme;
}
}