feat: add notification card and notification manager

This commit is contained in:
rabbitism 2023-01-13 01:29:53 +08:00
parent 03067ca007
commit 592f9ae285
10 changed files with 307 additions and 1 deletions

View File

@ -9,7 +9,10 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<TabControl Margin="8" TabStripPlacement="Left">
<TabControl
Margin="8"
HorizontalAlignment="Stretch"
TabStripPlacement="Left">
<TabItem Header="Overview">
<pages:Overview />
</TabItem>
@ -38,6 +41,9 @@
<TabItem Header="ListBox">
<pages:ListBoxDemo />
</TabItem>
<TabItem Header="Notification">
<pages:NotificationDemo />
</TabItem>
<TabItem Header="RadioButton">
<pages:RadioButtonDemo />
</TabItem>

View File

@ -1,13 +1,29 @@
using System.Diagnostics;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.VisualTree;
namespace Semi.Avalonia.Demo
{
public partial class MainWindow : Window
{
private readonly WindowNotificationManager _manager;
public MainWindow()
{
InitializeComponent();
_manager = new WindowNotificationManager(this)
{
Position = NotificationPosition.TopLeft,
MaxItems = 3
};
}
internal void Notify(NotificationType t)
{
_manager.Show(new Notification(t.ToString(), "This is a notification message", t));
}
}
}

View File

@ -0,0 +1,19 @@
<UserControl
x:Class="Semi.Avalonia.Demo.Pages.NotificationDemo"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<StackPanel
Margin="300,20,20,20"
HorizontalAlignment="Left"
Spacing="20">
<Button Click="InfoButton_OnClick" Content="Information" />
<Button Click="InfoButton_OnClick" Content="Success" />
<Button Click="InfoButton_OnClick" Content="Warning" />
<Button Click="InfoButton_OnClick" Content="Error" />
</StackPanel>
</UserControl>

View File

@ -0,0 +1,33 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Presenters;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
namespace Semi.Avalonia.Demo.Pages;
public partial class NotificationDemo : UserControl
{
private MainWindow? _window;
public NotificationDemo()
{
InitializeComponent();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_window = VisualRoot as MainWindow;
}
private void InfoButton_OnClick(object? sender, RoutedEventArgs e)
{
if (sender is Button b && b.Content is string s && Enum.TryParse<NotificationType>(s, out NotificationType t))
{
_window?.Notify(t);
}
}
}

View File

@ -0,0 +1,19 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type ContentControl}" TargetType="ContentControl">
<Setter Property="Template">
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Name="PART_ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
CornerRadius="{TemplateBinding CornerRadius}" />
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>

View File

@ -5,11 +5,13 @@
<ResourceInclude Source="avares://Semi.Avalonia/Controls/Button.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/CheckBox.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/ComboBox.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/ContentControl.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/Expander.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/FlyoutPresenter.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/ItemsControl.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/Label.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/ListBox.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/NotificationCard.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/PathIcon.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/Popup.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/RadioButton.axaml" />
@ -24,5 +26,6 @@
<ResourceInclude Source="avares://Semi.Avalonia/Controls/TreeView.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/UserControl.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/Window.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Controls/WindowNotificationManager.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

View File

@ -0,0 +1,154 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<NotificationCard>
<TextBlock Text="Hello World" />
</NotificationCard>
</Design.PreviewWith>
<ControlTheme x:Key="{x:Type NotificationCard}" TargetType="NotificationCard">
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="MinWidth" Value="{DynamicResource NotificationCardWidth}" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="{DynamicResource NotificationCardForeground}" />
<Setter Property="RenderTransformOrigin" Value="50%,75%" />
<Setter Property="BorderThickness" Value="{DynamicResource NotificationCardBorderThickness}" />
<Setter Property="BorderBrush" Value="{DynamicResource NotificationCardBorderBrush}" />
<Setter Property="Background" Value="{DynamicResource NotificationCardBackground}" />
<Setter Property="CornerRadius" Value="{DynamicResource NotificationCardCornerRadius}" />
<Setter Property="Template">
<ControlTemplate TargetType="NotificationCard">
<LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True">
<Border
Margin="4"
BoxShadow="0 0 14 #1A000000"
CornerRadius="{TemplateBinding CornerRadius}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
ClipToBounds="True"
CornerRadius="{TemplateBinding CornerRadius}">
<DockPanel>
<PathIcon
Name="NotificationIcon"
Width="16"
Height="16"
Margin="16,16,12,0"
VerticalAlignment="Top"
Data="{DynamicResource InformationIconPathData}"
IsVisible="False" />
<ContentControl
Name="PART_Content"
MinHeight="64"
Content="{TemplateBinding Content}">
<ContentControl.DataTemplates>
<DataTemplate DataType="INotification">
<StackPanel Margin="0,8,8,8" Spacing="8">
<TextBlock
FontSize="16"
FontWeight="600"
Text="{Binding Title}" />
<TextBlock
MaxHeight="80"
Margin="0,0,8,0"
FontSize="14"
FontWeight="400"
Text="{Binding Message}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="x:String">
<TextBlock
Margin="12"
Text="{Binding}"
TextWrapping="Wrap" />
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</DockPanel>
</Border>
</Border>
</LayoutTransformControl>
</ControlTemplate>
</Setter>
<ControlTheme.Animations>
<Animation
Easing="QuadraticEaseIn"
FillMode="Forward"
Duration="0:0:0.45">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0" />
<Setter Property="TranslateTransform.Y" Value="20" />
<Setter Property="ScaleTransform.ScaleX" Value="0.85" />
<Setter Property="ScaleTransform.ScaleY" Value="0.85" />
</KeyFrame>
<KeyFrame Cue="30%">
<Setter Property="TranslateTransform.Y" Value="-20" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1" />
<Setter Property="TranslateTransform.Y" Value="0" />
<Setter Property="ScaleTransform.ScaleX" Value="1" />
<Setter Property="ScaleTransform.ScaleY" Value="1" />
</KeyFrame>
</Animation>
</ControlTheme.Animations>
<Style Selector="^[IsClosing=true] /template/ LayoutTransformControl#PART_LayoutTransformControl">
<Setter Property="RenderTransformOrigin" Value="50%,0%" />
<Style.Animations>
<Animation
Easing="QuadraticEaseOut"
FillMode="Forward"
Duration="0:0:0.75">
<KeyFrame Cue="0%">
<Setter Property="TranslateTransform.X" Value="0" />
<Setter Property="ScaleTransform.ScaleY" Value="1" />
</KeyFrame>
<KeyFrame Cue="70%">
<Setter Property="TranslateTransform.X" Value="800" />
<Setter Property="ScaleTransform.ScaleY" Value="1" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="ScaleTransform.ScaleY" Value="0" />
<Setter Property="TranslateTransform.X" Value="800" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="^[IsClosing=true]">
<Style.Animations>
<Animation
Easing="QuadraticEaseOut"
FillMode="Forward"
Duration="0:0:1.25">
<KeyFrame Cue="100%">
<Setter Property="IsClosed" Value="True" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="^:information /template/ PathIcon#NotificationIcon">
<Setter Property="PathIcon.IsVisible" Value="True" />
<Setter Property="PathIcon.Foreground" Value="{DynamicResource NotificationCardInformationIconForeground}" />
<Setter Property="PathIcon.Data" Value="{DynamicResource NotificationCardInformationIconPathData}" />
</Style>
<Style Selector="^:success /template/ PathIcon#NotificationIcon">
<Setter Property="PathIcon.IsVisible" Value="True" />
<Setter Property="PathIcon.Foreground" Value="{DynamicResource NotificationCardSuccessIconForeground}" />
<Setter Property="PathIcon.Data" Value="{DynamicResource NotificationCardSuccessIconPathData}" />
</Style>
<Style Selector="^:warning /template/ PathIcon#NotificationIcon">
<Setter Property="PathIcon.IsVisible" Value="True" />
<Setter Property="PathIcon.Foreground" Value="{DynamicResource NotificationCardWarningIconForeground}" />
<Setter Property="PathIcon.Data" Value="{DynamicResource NotificationCardWarningIconPathData}" />
</Style>
<Style Selector="^:error /template/ PathIcon#NotificationIcon">
<Setter Property="PathIcon.IsVisible" Value="True" />
<Setter Property="PathIcon.Foreground" Value="{DynamicResource NotificationCardErrorIconForeground}" />
<Setter Property="PathIcon.Data" Value="{DynamicResource NotificationCardErrorIconPathData}" />
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@ -0,0 +1,36 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:CompileBindings="True"
x:DataType="WindowNotificationManager">
<ControlTheme x:Key="{x:Type WindowNotificationManager}" TargetType="WindowNotificationManager">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<ControlTemplate>
<ReversibleStackPanel Name="PART_Items" />
</ControlTemplate>
</Setter>
<Style Selector="^:topleft /template/ ReversibleStackPanel#PART_Items">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="^:topright /template/ ReversibleStackPanel#PART_Items">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style Selector="^:bottomleft /template/ ReversibleStackPanel#PART_Items">
<Setter Property="ReverseOrder" Value="True" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="^:bottomright /template/ ReversibleStackPanel#PART_Items">
<Setter Property="ReverseOrder" Value="True" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@ -9,6 +9,7 @@
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/Expander.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/Label.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/ListBox.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/NotificationCard.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/RadioButton.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/ScrollViewer.axaml" />
<ResourceInclude Source="avares://Semi.Avalonia/Themes/Light/TabControl.axaml" />

View File

@ -0,0 +1,19 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
<SolidColorBrush x:Key="NotificationCardForeground" Color="#1C1F23" />
<SolidColorBrush x:Key="NotificationCardBorderBrush" Opacity="0.08" Color="#1C1F23" />
<SolidColorBrush x:Key="NotificationCardBackground" Color="White" />
<SolidColorBrush x:Key="NotificationCardInformationIconForeground" Color="#0077FA" />
<SolidColorBrush x:Key="NotificationCardSuccessIconForeground" Color="#3BB346" />
<SolidColorBrush x:Key="NotificationCardWarningIconForeground" Color="#FC8800" />
<SolidColorBrush x:Key="NotificationCardErrorIconForeground" Color="#F93920" />
<sys:Double x:Key="NotificationCardWidth">320</sys:Double>
<Thickness x:Key="NotificationCardBorderThickness">1</Thickness>
<CornerRadius x:Key="NotificationCardCornerRadius">6</CornerRadius>
<Geometry x:Key="NotificationCardInformationIconPathData">M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM14 7C14 8.10457 13.1046 9 12 9C10.8954 9 10 8.10457 10 7C10 5.89543 10.8954 5 12 5C13.1046 5 14 5.89543 14 7ZM9 10.75C9 10.3358 9.33579 10 9.75 10H12.5C13.0523 10 13.5 10.4477 13.5 11V16.5H14.25C14.6642 16.5 15 16.8358 15 17.25C15 17.6642 14.6642 18 14.25 18H9.75C9.33579 18 9 17.6642 9 17.25C9 16.8358 9.33579 16.5 9.75 16.5H10.5V11.5H9.75C9.33579 11.5 9 11.1642 9 10.75Z</Geometry>
<Geometry x:Key="NotificationCardSuccessIconPathData">M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM17.8831 9.82235L11.6854 17.4112C11.4029 17.7806 10.965 17.9981 10.5 18C10.035 18.0019 9.59533 17.788 9.30982 17.421L5.81604 13.4209C5.30744 12.767 5.42524 11.8246 6.07916 11.316C6.73308 10.8074 7.67549 10.9252 8.1841 11.5791L10.4838 14.0439L15.5 8C16.0032 7.34193 16.9446 7.21641 17.6027 7.71964C18.2608 8.22287 18.3863 9.16428 17.8831 9.82235Z</Geometry>
<Geometry x:Key="NotificationCardWarningIconPathData">M10.2268 2.3986L1.52616 19.0749C0.831449 20.4064 1.79747 22 3.29933 22H20.7007C22.2025 22 23.1686 20.4064 22.4739 19.0749L13.7732 2.3986C13.0254 0.965441 10.9746 0.965442 10.2268 2.3986ZM13.1415 14.0101C13.0603 14.5781 12.5739 15 12.0001 15C11.4263 15 10.9398 14.5781 10.8586 14.0101L10.2829 9.97992C10.1336 8.93495 10.9445 8.00002 12.0001 8.00002C13.0556 8.00002 13.8665 8.93495 13.7172 9.97992L13.1415 14.0101ZM13.5001 18.5C13.5001 19.3284 12.8285 20 12.0001 20C11.1716 20 10.5001 19.3284 10.5001 18.5C10.5001 17.6716 11.1716 17 12.0001 17C12.8285 17 13.5001 17.6716 13.5001 18.5Z</Geometry>
<Geometry x:Key="NotificationCardErrorIconPathData">M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM13.5 17.5C13.5 16.6716 12.8284 16 12 16C11.1716 16 10.5 16.6716 10.5 17.5C10.5 18.3284 11.1716 19 12 19C12.8284 19 13.5 18.3284 13.5 17.5ZM12 5C10.9138 5 10.0507 5.91244 10.1109 6.99692L10.4168 12.5023C10.4635 13.3426 11.1584 14 12 14C12.8416 14 13.5365 13.3426 13.5832 12.5023L13.8891 6.99692C13.9493 5.91244 13.0862 5 12 5Z</Geometry>
</ResourceDictionary>