This commit is contained in:
Daniel Clark
2021-02-08 01:13:24 +00:00
parent 72941706d9
commit 1f9e90c8fe
12 changed files with 283 additions and 53 deletions
@@ -2,13 +2,15 @@
x:Class="NotificationFlyout.Sample.NotificationFlyoutPresenter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls"
CornerRadius="4"
RequestedTheme="Default">
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls">
<Grid
Width="330"
Height="360"
Margin="23">
<ToggleSwitch x:Name="test" Toggled="ToggleSwitch_Toggled" />
Margin="24">
<ComboBox x:Name="test" Margin="0,0,0,8" SelectionChanged="test_SelectionChanged">
<ComboBoxItem>System</ComboBoxItem>
<ComboBoxItem>Dark</ComboBoxItem>
<ComboBoxItem>Light</ComboBoxItem>
</ComboBox>
</Grid>
</controls:NotificationFlyoutPresenter>
@@ -7,13 +7,21 @@
InitializeComponent();
}
private void ToggleSwitch_Toggled(object sender, Windows.UI.Xaml.RoutedEventArgs e)
private void test_SelectionChanged(object sender, Windows.UI.Xaml.Controls.SelectionChangedEventArgs e)
{
if (test.IsOn)
if (test.SelectedIndex == 0)
{
this.RequestedTheme = Windows.UI.Xaml.ElementTheme.Default;
}
if (test.SelectedIndex == 1)
{
this.RequestedTheme = Windows.UI.Xaml.ElementTheme.Dark;
}
else
if (test.SelectedIndex == 2)
{
this.RequestedTheme = Windows.UI.Xaml.ElementTheme.Light;
@@ -14,7 +14,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
@@ -121,6 +121,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="NotificationFlyoutHost\NotificationFlyoutHost.cs" />
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutContentPresenter.cs" />
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\NotificationFlyout.Uwp.UI.Controls.rd.xml" />
@@ -138,6 +139,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NotificationFlyoutPresenter\NotificationFlyoutContentPresenter.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -162,4 +167,7 @@
<EnableTypeInfoReflection>false</EnableTypeInfoReflection>
<EnableXBindDiagnostics>false</EnableXBindDiagnostics>
</PropertyGroup>
<PropertyGroup>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
</Project>
@@ -0,0 +1,12 @@
using Windows.UI.Xaml.Controls;
namespace NotificationFlyout.Uwp.UI.Controls
{
public class NotificationFlyoutContentPresenter : ContentControl
{
public NotificationFlyoutContentPresenter()
{
DefaultStyleKey = typeof(NotificationFlyoutContentPresenter);
}
}
}
@@ -0,0 +1,62 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#2C2C2C"
TintColor="#2C2C2C"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#F9F9F9"
TintColor="#FCFCFC"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="NotificationFlyoutPresenterBackgroundBrush" Color="Green" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<Style TargetType="controls:NotificationFlyoutContentPresenter">
<Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutContentPresenter">
<Border
x:Name="Root"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BackgroundSizing="OuterBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer
x:Name="ScrollViewer"
AutomationProperties.AccessibilityView="Raw"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -1,12 +1,47 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace NotificationFlyout.Uwp.UI.Controls
{
public class NotificationFlyoutPresenter : ContentControl
{
private NotificationFlyoutContentPresenter _contentPresenter;
public NotificationFlyoutPresenter()
{
DefaultStyleKey = typeof(NotificationFlyoutPresenter);
ActualThemeChanged += OnActualThemeChanged;
}
protected override void OnApplyTemplate()
{
_contentPresenter = GetTemplateChild("ContentPresenter") as NotificationFlyoutContentPresenter;
}
public void SetBackground(string theme)
{
if (_contentPresenter == null) return;
if (RequestedTheme == ElementTheme.Default)
{
ActualThemeChanged -= OnActualThemeChanged;
switch (theme)
{
case "Dark":
_contentPresenter.SetValue(RequestedThemeProperty, ElementTheme.Dark);
break;
case "Light":
_contentPresenter.SetValue(RequestedThemeProperty, ElementTheme.Light);
break;
}
ActualThemeChanged += OnActualThemeChanged;
}
}
private void OnActualThemeChanged(FrameworkElement sender, object args)
{
_contentPresenter.SetValue(RequestedThemeProperty, RequestedTheme);
}
}
}
@@ -2,47 +2,14 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<StaticResource x:Key="NotificationFlyoutPresenterBackground" ResourceKey="SystemControlTransientBackgroundBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<StaticResource x:Key="NotificationFlyoutPresenterBackground" ResourceKey="SystemControlPageBackgroundChromeMediumLowBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<StaticResource x:Key="NotificationFlyoutPresenterBackground" ResourceKey="SystemControlTransientBackgroundBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<Style TargetType="controls:NotificationFlyoutPresenter">
<Setter Property="Background" Value="{ThemeResource SystemControlTransientBackgroundBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutPresenter">
<Border
x:Name="Root"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BackgroundSizing="OuterBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer
x:Name="ScrollViewer"
AutomationProperties.AccessibilityView="Raw"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer>
</Border>
<controls:NotificationFlyoutContentPresenter
x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</ControlTemplate>
</Setter.Value>
</Setter>
@@ -2,5 +2,7 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutHost/NotificationFlyoutHost.xaml" />
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml" />
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutContentPresenter.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -0,0 +1,119 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Reflection;
using Windows.UI;
using Color = Windows.UI.Color;
namespace NotificationFlyout.Uwp.UI.Helpers
{
public static class ColorHelper
{
public static Color ToColor(this string colorString)
{
if (string.IsNullOrEmpty(colorString))
{
ThrowArgumentException();
}
if (colorString[0] == '#')
{
switch (colorString.Length)
{
case 9:
{
var cuint = Convert.ToUInt32(colorString.Substring(1), 16);
var a = (byte)(cuint >> 24);
var r = (byte)((cuint >> 16) & 0xff);
var g = (byte)((cuint >> 8) & 0xff);
var b = (byte)(cuint & 0xff);
return Color.FromArgb(a, r, g, b);
}
case 7:
{
var cuint = Convert.ToUInt32(colorString.Substring(1), 16);
var r = (byte)((cuint >> 16) & 0xff);
var g = (byte)((cuint >> 8) & 0xff);
var b = (byte)(cuint & 0xff);
return Color.FromArgb(255, r, g, b);
}
case 5:
{
var cuint = Convert.ToUInt16(colorString.Substring(1), 16);
var a = (byte)(cuint >> 12);
var r = (byte)((cuint >> 8) & 0xf);
var g = (byte)((cuint >> 4) & 0xf);
var b = (byte)(cuint & 0xf);
a = (byte)(a << 4 | a);
r = (byte)(r << 4 | r);
g = (byte)(g << 4 | g);
b = (byte)(b << 4 | b);
return Color.FromArgb(a, r, g, b);
}
case 4:
{
var cuint = Convert.ToUInt16(colorString.Substring(1), 16);
var r = (byte)((cuint >> 8) & 0xf);
var g = (byte)((cuint >> 4) & 0xf);
var b = (byte)(cuint & 0xf);
r = (byte)(r << 4 | r);
g = (byte)(g << 4 | g);
b = (byte)(b << 4 | b);
return Color.FromArgb(255, r, g, b);
}
default: return ThrowFormatException();
}
}
if (colorString.Length > 3 && colorString[0] == 's' && colorString[1] == 'c' && colorString[2] == '#')
{
var values = colorString.Split(',');
if (values.Length == 4)
{
var scA = double.Parse(values[0].Substring(3), CultureInfo.InvariantCulture);
var scR = double.Parse(values[1], CultureInfo.InvariantCulture);
var scG = double.Parse(values[2], CultureInfo.InvariantCulture);
var scB = double.Parse(values[3], CultureInfo.InvariantCulture);
return Color.FromArgb((byte)(scA * 255), (byte)(scR * 255), (byte)(scG * 255), (byte)(scB * 255));
}
if (values.Length == 3)
{
var scR = double.Parse(values[0].Substring(3), CultureInfo.InvariantCulture);
var scG = double.Parse(values[1], CultureInfo.InvariantCulture);
var scB = double.Parse(values[2], CultureInfo.InvariantCulture);
return Color.FromArgb(255, (byte)(scR * 255), (byte)(scG * 255), (byte)(scB * 255));
}
return ThrowFormatException();
}
var prop = typeof(Colors).GetTypeInfo().GetDeclaredProperty(colorString);
if (prop != null)
{
return (Color)prop.GetValue(null);
}
return ThrowFormatException();
static void ThrowArgumentException() => throw new ArgumentException("The parameter \"colorString\" must not be null or empty.");
static Color ThrowFormatException() => throw new FormatException("The parameter \"colorString\" is not a recognized Color format.");
}
}
}
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
</Project>
@@ -99,11 +99,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
}
private void OnSystemThemeChanged(object sender, EventArgs args)
{
UpdateIcon();
}
private void OnTaskbarChanged(object sender, EventArgs args)
{
UpdateWindow();
@@ -127,7 +122,18 @@ namespace NotificationFlyout.Wpf.UI.Controls
_notificationIconHelper.IconInvoked += OnIconInvoked;
_systemPersonalisationHelper = SystemPersonalisationHelper.Create(this);
_systemPersonalisationHelper.ThemeChanged += OnSystemThemeChanged;
_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()