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" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<AcrylicBrush
x:Key="NotificationFlyoutPresenterBackgroundAccentBrush"
BackgroundSource="HostBackdrop"
FallbackColor="{ThemeResource SystemAccentColorDark1}"
TintColor="{ThemeResource SystemAccentColorDark1}"
TintOpacity="0.8" />
<Style TargetType="controls:NotificationFlyoutContentPresenter">
<Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" />
<Setter Property="Template">
@@ -54,6 +60,16 @@
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</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>
</ControlTemplate>
</Setter.Value>
@@ -8,6 +8,7 @@ namespace NotificationFlyout.Uwp.UI.Controls
{
private NotificationFlyoutContentPresenter _contentPresenter;
private bool _isColorPrevalence;
private ElementTheme _systemTheme;
public NotificationFlyoutPresenter()
@@ -15,11 +16,9 @@ namespace NotificationFlyout.Uwp.UI.Controls
DefaultStyleKey = typeof(NotificationFlyoutPresenter);
RegisterPropertyChangedCallback(RequestedThemeProperty, RequestedThemePropertyChanged);
}
public void SetBackground(string theme)
public void UpdateFlyoutTheme(string theme, bool isColorPrevalence)
{
if (_contentPresenter == null) return;
_isColorPrevalence = isColorPrevalence;
switch (theme)
{
case "Dark":
@@ -30,18 +29,21 @@ namespace NotificationFlyout.Uwp.UI.Controls
break;
}
if (RequestedTheme == ElementTheme.Default)
{
_contentPresenter.SetValue(RequestedThemeProperty, _systemTheme);
}
UpdateThemeVisualState();
}
protected override void OnApplyTemplate()
{
_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)
{
@@ -52,5 +54,16 @@ namespace NotificationFlyout.Uwp.UI.Controls
_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 ImageSource _defaultIconSource;
private bool _isLoaded;
private ImageSource _lightIconSource;
private NotificationIconHelper _notificationIconHelper;
private SystemPersonalisationHelper _systemPersonalisationHelper;
private TaskbarHelper _taskbarHelper;
private WindowsXamlHost _xamlHost;
private bool _isLoaded;
public NotificationFlyoutXamlHost()
{
@@ -36,6 +36,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
if (flyoutHost != null)
{
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();
}
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()
{
ShowInTaskbar = false;
@@ -125,17 +149,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
_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()
{
_taskbarHelper = TaskbarHelper.Create(this);
@@ -164,7 +177,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
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;
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.Runtime.InteropServices;
using System.Windows;
@@ -10,22 +11,23 @@ namespace NotificationFlyout.Wpf.UI.Helpers
public class SystemPersonalisationHelper
{
private readonly UISettings _settings = new();
private readonly string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private SystemTheme _currentTheme;
private bool _isColorPrevalence;
private SystemPersonalisationHelper(Window window)
{
var source = HwndSource.FromHwnd(window.GetHandle());
source.AddHook(new HwndSourceHook(WndProc));
_settings.ColorValuesChanged += OnColorValuesChanged;
_currentTheme = GetSystemTheme();
_currentTheme = GetTheme();
_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)
{
@@ -35,24 +37,30 @@ namespace NotificationFlyout.Wpf.UI.Helpers
[DllImport("user32.dll", SetLastError = true)]
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();
return color == "#FFFFFFFF" ? SystemTheme.Light : SystemTheme.Dark;
}
private void OnColorValuesChanged(UISettings sender, object args)
{
RaiseThemeChangedEvent();
}
private void RaiseThemeChangedEvent()
{
var theme = GetSystemTheme();
if (theme != _currentTheme)
var theme = GetTheme();
var isColorPrevalence = GetIsColorPrevalence();
if (theme != _currentTheme || _isColorPrevalence != isColorPrevalence)
{
ThemeChanged?.Invoke(this, new ThemeChangedEventArgs(theme));
_currentTheme = theme;
_isColorPrevalence = isColorPrevalence;
ThemeChanged?.Invoke(this, new SystemPersonalisationChangedEventArgs(theme, isColorPrevalence));
}
}
@@ -2,13 +2,17 @@
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;
IsColorPrevalence = isColorPrevalence;
}
public SystemTheme Theme { get; private set; }
public bool IsColorPrevalence { get; private set; }
}
}