Added support for IsColorPrevalence background system accent color

This commit is contained in:
Daniel Clark
2021-02-08 23:20:06 +00:00
parent ec847fd6a5
commit e1b3b1e6c9
5 changed files with 94 additions and 40 deletions
@@ -25,6 +25,12 @@
<SolidColorBrush x:Key="NotificationFlyoutPresenterBackgroundBrush" Color="Green" /> <SolidColorBrush x:Key="NotificationFlyoutPresenterBackgroundBrush" Color="Green" />
</ResourceDictionary> </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries> </ResourceDictionary.ThemeDictionaries>
<AcrylicBrush
x:Key="NotificationFlyoutPresenterBackgroundAccentBrush"
BackgroundSource="HostBackdrop"
FallbackColor="{ThemeResource SystemAccentColorDark1}"
TintColor="{ThemeResource SystemAccentColorDark1}"
TintOpacity="0.8" />
<Style TargetType="controls:NotificationFlyoutContentPresenter"> <Style TargetType="controls:NotificationFlyoutContentPresenter">
<Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" /> <Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" />
<Setter Property="Template"> <Setter Property="Template">
@@ -54,6 +60,16 @@
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" /> ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer> </ScrollViewer>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ThemeStates">
<VisualState x:Name="DefaultTheme" />
<VisualState x:Name="ColorPrevalenceTheme">
<VisualState.Setters>
<Setter Target="Root.Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundAccentBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
@@ -8,6 +8,7 @@ namespace NotificationFlyout.Uwp.UI.Controls
{ {
private NotificationFlyoutContentPresenter _contentPresenter; private NotificationFlyoutContentPresenter _contentPresenter;
private bool _isColorPrevalence;
private ElementTheme _systemTheme; private ElementTheme _systemTheme;
public NotificationFlyoutPresenter() public NotificationFlyoutPresenter()
@@ -15,11 +16,9 @@ namespace NotificationFlyout.Uwp.UI.Controls
DefaultStyleKey = typeof(NotificationFlyoutPresenter); DefaultStyleKey = typeof(NotificationFlyoutPresenter);
RegisterPropertyChangedCallback(RequestedThemeProperty, RequestedThemePropertyChanged); RegisterPropertyChangedCallback(RequestedThemeProperty, RequestedThemePropertyChanged);
} }
public void UpdateFlyoutTheme(string theme, bool isColorPrevalence)
public void SetBackground(string theme)
{ {
if (_contentPresenter == null) return; _isColorPrevalence = isColorPrevalence;
switch (theme) switch (theme)
{ {
case "Dark": case "Dark":
@@ -30,18 +29,21 @@ namespace NotificationFlyout.Uwp.UI.Controls
break; break;
} }
if (RequestedTheme == ElementTheme.Default) UpdateThemeVisualState();
{
_contentPresenter.SetValue(RequestedThemeProperty, _systemTheme);
}
} }
protected override void OnApplyTemplate() protected override void OnApplyTemplate()
{ {
_contentPresenter = GetTemplateChild("ContentPresenter") as NotificationFlyoutContentPresenter; _contentPresenter = GetTemplateChild("ContentPresenter") as NotificationFlyoutContentPresenter;
Loaded += OnLoaded;
} }
private void RequestedThemePropertyChanged(DependencyObject sender, DependencyProperty dp) private void OnLoaded(object sender, RoutedEventArgs args)
{
UpdateThemeVisualState();
}
private void RequestedThemePropertyChanged(DependencyObject sender, DependencyProperty dependencyProperty)
{ {
if (RequestedTheme == ElementTheme.Default) if (RequestedTheme == ElementTheme.Default)
{ {
@@ -52,5 +54,16 @@ namespace NotificationFlyout.Uwp.UI.Controls
_contentPresenter.SetValue(RequestedThemeProperty, RequestedTheme); _contentPresenter.SetValue(RequestedThemeProperty, RequestedTheme);
} }
} }
private void UpdateThemeVisualState()
{
if (_contentPresenter == null) return;
if (RequestedTheme == ElementTheme.Default)
{
_contentPresenter.SetValue(RequestedThemeProperty, _systemTheme);
}
VisualStateManager.GoToState(_contentPresenter, _isColorPrevalence ? "ColorPrevalenceTheme" : "DefaultTheme", true);
}
} }
} }
@@ -15,12 +15,12 @@ namespace NotificationFlyout.Wpf.UI.Controls
private const double WindowSize = 5; private const double WindowSize = 5;
private ImageSource _defaultIconSource; private ImageSource _defaultIconSource;
private bool _isLoaded;
private ImageSource _lightIconSource; private ImageSource _lightIconSource;
private NotificationIconHelper _notificationIconHelper; private NotificationIconHelper _notificationIconHelper;
private SystemPersonalisationHelper _systemPersonalisationHelper; private SystemPersonalisationHelper _systemPersonalisationHelper;
private TaskbarHelper _taskbarHelper; private TaskbarHelper _taskbarHelper;
private WindowsXamlHost _xamlHost; private WindowsXamlHost _xamlHost;
private bool _isLoaded;
public NotificationFlyoutXamlHost() public NotificationFlyoutXamlHost()
{ {
@@ -36,6 +36,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
if (flyoutHost != null) if (flyoutHost != null)
{ {
flyoutHost.FlyoutPresenter = flyoutPresenter; flyoutHost.FlyoutPresenter = flyoutPresenter;
var theme = _systemPersonalisationHelper.Theme.ToString();
var isColorPrevalence = _systemPersonalisationHelper.IsColorPrevalence;
flyoutHost.FlyoutPresenter.UpdateFlyoutTheme(theme, isColorPrevalence);
} }
} }
@@ -104,6 +109,25 @@ namespace NotificationFlyout.Wpf.UI.Controls
UpdateWindow(); UpdateWindow();
} }
private void OnThemeChanged(object sender, SystemPersonalisationChangedEventArgs args)
{
NewMethod(args);
UpdateIcon();
}
private void NewMethod(SystemPersonalisationChangedEventArgs args)
{
var flyoutHost = GetFlyoutHost();
if (flyoutHost != null)
{
var theme = args.Theme.ToString();
var isColorPrevalence = args.IsColorPrevalence;
flyoutHost.FlyoutPresenter.UpdateFlyoutTheme(theme, isColorPrevalence);
}
}
private void PrepareDefaultWindow() private void PrepareDefaultWindow()
{ {
ShowInTaskbar = false; ShowInTaskbar = false;
@@ -125,17 +149,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
_systemPersonalisationHelper.ThemeChanged += OnThemeChanged; _systemPersonalisationHelper.ThemeChanged += OnThemeChanged;
} }
private void OnThemeChanged(object sender, ThemeChangedEventArgs args)
{
var flyoutHost = GetFlyoutHost();
if (flyoutHost != null)
{
flyoutHost.FlyoutPresenter.SetBackground(args.Theme.ToString());
}
UpdateIcon();
}
private void PrepareTaskbar() private void PrepareTaskbar()
{ {
_taskbarHelper = TaskbarHelper.Create(this); _taskbarHelper = TaskbarHelper.Create(this);
@@ -164,7 +177,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
var dpi = WindowHelper.GetDpi(shellTrayHandle); var dpi = WindowHelper.GetDpi(shellTrayHandle);
var iconSource = _systemPersonalisationHelper.SystemTheme == SystemTheme.Dark ? _defaultIconSource : _lightIconSource; var iconSource = _systemPersonalisationHelper.Theme == SystemTheme.Dark ? _defaultIconSource : _lightIconSource;
if (iconSource == null) return; if (iconSource == null) return;
using var icon = iconSource.ConvertToIcon(dpi); using var icon = iconSource.ConvertToIcon(dpi);
@@ -1,4 +1,5 @@
using NotificationFlyout.Wpf.UI.Extensions; using Microsoft.Win32;
using NotificationFlyout.Wpf.UI.Extensions;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
@@ -10,22 +11,23 @@ namespace NotificationFlyout.Wpf.UI.Helpers
public class SystemPersonalisationHelper public class SystemPersonalisationHelper
{ {
private readonly UISettings _settings = new(); private readonly UISettings _settings = new();
private readonly string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private SystemTheme _currentTheme; private SystemTheme _currentTheme;
private bool _isColorPrevalence;
private SystemPersonalisationHelper(Window window) private SystemPersonalisationHelper(Window window)
{ {
var source = HwndSource.FromHwnd(window.GetHandle()); var source = HwndSource.FromHwnd(window.GetHandle());
source.AddHook(new HwndSourceHook(WndProc)); source.AddHook(new HwndSourceHook(WndProc));
_settings.ColorValuesChanged += OnColorValuesChanged; _currentTheme = GetTheme();
_currentTheme = GetSystemTheme(); _isColorPrevalence = GetIsColorPrevalence();
} }
public event EventHandler<ThemeChangedEventArgs> ThemeChanged; public event EventHandler<SystemPersonalisationChangedEventArgs> ThemeChanged;
public SystemTheme SystemTheme => GetSystemTheme(); public bool IsColorPrevalence => GetIsColorPrevalence();
public SystemTheme Theme => GetTheme();
public static SystemPersonalisationHelper Create(Window window) public static SystemPersonalisationHelper Create(Window window)
{ {
@@ -35,24 +37,30 @@ namespace NotificationFlyout.Wpf.UI.Helpers
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam);
private SystemTheme GetSystemTheme() private bool GetIsColorPrevalence()
{
using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
using var subKey = baseKey.OpenSubKey(PersonalizeKey);
return subKey.GetValue<int>("ColorPrevalence", 0) > 0;
}
private SystemTheme GetTheme()
{ {
var color = _settings.GetColorValue(UIColorType.Background).ToString(); var color = _settings.GetColorValue(UIColorType.Background).ToString();
return color == "#FFFFFFFF" ? SystemTheme.Light : SystemTheme.Dark; return color == "#FFFFFFFF" ? SystemTheme.Light : SystemTheme.Dark;
} }
private void OnColorValuesChanged(UISettings sender, object args)
{
RaiseThemeChangedEvent();
}
private void RaiseThemeChangedEvent() private void RaiseThemeChangedEvent()
{ {
var theme = GetSystemTheme(); var theme = GetTheme();
if (theme != _currentTheme) var isColorPrevalence = GetIsColorPrevalence();
if (theme != _currentTheme || _isColorPrevalence != isColorPrevalence)
{ {
ThemeChanged?.Invoke(this, new ThemeChangedEventArgs(theme));
_currentTheme = theme; _currentTheme = theme;
_isColorPrevalence = isColorPrevalence;
ThemeChanged?.Invoke(this, new SystemPersonalisationChangedEventArgs(theme, isColorPrevalence));
} }
} }
@@ -2,13 +2,17 @@
namespace NotificationFlyout.Wpf.UI.Helpers namespace NotificationFlyout.Wpf.UI.Helpers
{ {
public class ThemeChangedEventArgs : EventArgs public class SystemPersonalisationChangedEventArgs : EventArgs
{ {
internal ThemeChangedEventArgs(SystemTheme theme) internal SystemPersonalisationChangedEventArgs(SystemTheme theme, bool isColorPrevalence)
{ {
Theme = theme; Theme = theme;
IsColorPrevalence = isColorPrevalence;
} }
public SystemTheme Theme { get; private set; } public SystemTheme Theme { get; private set; }
public bool IsColorPrevalence { get; private set; }
} }
} }