157 lines
5.0 KiB
C#
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;
|
|
}
|
|
}
|