-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
AppThemeModeService.cs
138 lines (117 loc) · 4.14 KB
/
AppThemeModeService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.
using Microsoft.Extensions.Logging;
using Microsoft.UI;
using Microsoft.UI.System;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using Windows.Storage;
using Windows.UI;
using Windows.UI.ViewManagement;
namespace Files.App.Services
{
public class AppThemeModeService : IAppThemeModeService
{
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
private UISettings UISettings { get; } = new();
private ThemeSettings ThemeSettings { get; }
/// <inheritdoc/>
public ElementTheme AppThemeMode
{
get
{
var theme = UserSettingsService.AppearanceSettingsService.AppThemeMode;
return EnumExtensions.GetEnum<ElementTheme>(theme);
}
set
{
UserSettingsService.AppearanceSettingsService.AppThemeMode = value.ToString();
SetAppThemeMode();
}
}
/// <inheritdoc/>
public Color DefaultAccentColor
{
get => AppThemeMode switch
{
// these values are from the definition of AccentFillColorDefaultBrush in generic.xaml
// will have to be updated if WinUI changes in the future
ElementTheme.Light => (Color)(App.Current.Resources["SystemAccentColorDark1"]),
ElementTheme.Dark => (Color)(App.Current.Resources["SystemAccentColorLight2"]),
ElementTheme.Default or _ => (App.Current.Resources["AccentFillColorDefaultBrush"] as SolidColorBrush)!.Color
};
}
/// <inheritdoc/>
public event EventHandler? AppThemeModeChanged;
/// <inheritdoc/>
public event EventHandler<bool>? IsHighContrastChanged;
/// <summary>
/// Initializes an instance of <see cref="AppThemeModeService"/>.
/// </summary>
public AppThemeModeService()
{
// Set the desired theme based on what is set in the application settings
SetAppThemeMode();
// Registering to color changes, so that we can notice when changed system theme mode
UISettings.ColorValuesChanged += UISettings_ColorValuesChanged;
var windowId = MainWindow.Instance.AppWindow.Id;
ThemeSettings = ThemeSettings.CreateForWindowId(windowId);
ThemeSettings.Changed += (s, e) => { IsHighContrastChanged?.Invoke(this, s.HighContrast); };
}
/// <inheritdoc/>
public void ApplyResources()
{
// Toggle between the themes to force reload the resource styles
SetAppThemeMode(null, null, ElementTheme.Dark);
SetAppThemeMode(null, null, ElementTheme.Light);
// Restore the theme to the correct one
SetAppThemeMode();
}
/// <inheritdoc/>
public void SetAppThemeMode(Window? window = null, AppWindowTitleBar? titleBar = null, ElementTheme? rootTheme = null, bool callThemeModeChangedEvent = true)
{
try
{
window ??= MainWindow.Instance;
titleBar ??= MainWindow.Instance.AppWindow.TitleBar;
rootTheme ??= AppThemeMode;
if (window.Content is FrameworkElement rootElement)
rootElement.RequestedTheme = (ElementTheme)rootTheme;
if (titleBar is not null)
{
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
switch (rootTheme)
{
case ElementTheme.Default:
titleBar.ButtonHoverBackgroundColor = (Color)Application.Current.Resources["SystemBaseLowColor"];
titleBar.ButtonForegroundColor = (Color)Application.Current.Resources["SystemBaseHighColor"];
break;
case ElementTheme.Light:
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(51, 0, 0, 0);
titleBar.ButtonForegroundColor = Colors.Black;
break;
case ElementTheme.Dark:
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(51, 255, 255, 255);
titleBar.ButtonForegroundColor = Colors.White;
break;
}
}
if (callThemeModeChangedEvent)
AppThemeModeChanged?.Invoke(null, EventArgs.Empty);
}
catch (Exception ex)
{
App.Logger.LogWarning(ex, "Failed to change theme mode of the app.");
}
}
private async void UISettings_ColorValuesChanged(UISettings sender, object args)
{
await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() =>
{
SetAppThemeMode();
});
}
}
}