diff --git a/Directory.Build.props b/Directory.Build.props index 107eabd..0d94c5a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,12 +1,12 @@ - + enable enable latest - - - + + + diff --git a/Directory.Build.targets b/Directory.Build.targets index bafae10..fdfca22 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/App.axaml.cs b/samples/AtomUI.Demo.Desktop/App.axaml.cs index 43bca16..19e13d4 100644 --- a/samples/AtomUI.Demo.Desktop/App.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/App.axaml.cs @@ -1,11 +1,11 @@ +using AtomUI.Demo.Desktop.Views; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using AtomUI.Demo.Desktop.Views; namespace AtomUI.Demo.Desktop; -public partial class App : Application +public class App : Application { public override void Initialize() { diff --git a/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg b/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg index bac1d28..b3f7ef0 100644 --- a/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg +++ b/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg @@ -1 +1,43 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj b/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj index ea36139..e7aa238 100644 --- a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj +++ b/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj @@ -1,6 +1,6 @@  - - + + WinExe @@ -9,8 +9,8 @@ - - + + @@ -19,19 +19,19 @@ - - - - - - - + + + + + + + - - - + + + - + diff --git a/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs b/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs index 96a5c4c..576a1ef 100644 --- a/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs +++ b/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs @@ -1,61 +1,65 @@ +using AtomUI.Controls; using Avalonia; using Avalonia.Controls; using Avalonia.LogicalTree; using Avalonia.Media; +using Separator = AtomUI.Controls.Separator; namespace AtomUI.Demo.Desktop; public class ShowCaseItem : ContentControl { - private bool _initialized = false; - public string Title { get; set; } = string.Empty; - public string Description { get; set; } = string.Empty; + private bool _initialized; + public string Title { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; - private void SetupUi() - { - var mainLayout = new StackPanel(); - var showCaseTitle = new AtomUI.Controls.Separator() - { - Title = Title, - TitlePosition = AtomUI.Controls.SeparatorTitlePosition.Left, - FontWeight = FontWeight.Bold, - }; + private void SetupUi() + { + var mainLayout = new StackPanel(); + var showCaseTitle = new Separator + { + Title = Title, + TitlePosition = SeparatorTitlePosition.Left, + FontWeight = FontWeight.Bold + }; - if (Content is Control contentControl) { - LogicalChildren.Remove(contentControl); - mainLayout.Children.Add(contentControl); - } - - mainLayout.Children.Add(new Border - { - Height = 10, - Background = Brushes.Transparent - }); - mainLayout.Children.Add(showCaseTitle); - mainLayout.Children.Add(new TextBlock() - { - Text = Description, - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(0, 10, 0, 0) - }); - - var outerBorder = new Border() - { - BorderBrush = new SolidColorBrush(new Color(10, 5, 5, 5)), - BorderThickness = new Thickness(1), - Padding = new Thickness(20), - Child = mainLayout, - CornerRadius = new CornerRadius(8) - }; - - Content = outerBorder; - } + if (Content is Control contentControl) + { + LogicalChildren.Remove(contentControl); + mainLayout.Children.Add(contentControl); + } - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - if (!_initialized) { - SetupUi(); - _initialized = true; - } - } + mainLayout.Children.Add(new Border + { + Height = 10, + Background = Brushes.Transparent + }); + mainLayout.Children.Add(showCaseTitle); + mainLayout.Children.Add(new TextBlock + { + Text = Description, + TextWrapping = TextWrapping.Wrap, + Margin = new Thickness(0, 10, 0, 0) + }); + + var outerBorder = new Border + { + BorderBrush = new SolidColorBrush(new Color(10, 5, 5, 5)), + BorderThickness = new Thickness(1), + Padding = new Thickness(20), + Child = mainLayout, + CornerRadius = new CornerRadius(8) + }; + + Content = outerBorder; + } + + protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) + { + if (!_initialized) + { + SetupUi(); + _initialized = true; + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs b/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs index f6ffea4..fa03069 100644 --- a/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs +++ b/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs @@ -10,83 +10,82 @@ namespace AtomUI.Demo.Desktop; public class ShowCasePanel : Control { - public string? Id { get; protected set; } - private bool _initialized = false; - private StackPanel _leftContainer = default!; - private StackPanel _rightContainer = default!; - - [Content] - public AvaloniaControlList Children { get; } = new AvaloniaControlList(); + private bool _initialized; + private StackPanel _leftContainer = default!; + private StackPanel _rightContainer = default!; - public ShowCasePanel() - { - } + public string? Id { get; protected set; } - protected void SetupUi() - { - var mainLayout = new UniformGrid() - { - Rows = 1, - Columns = 2, - Margin = new Thickness(0) - }; - _leftContainer = new StackPanel() - { - Orientation = Orientation.Vertical, - Spacing = 10, - Margin = new Thickness(0, 0, 10, 0), - }; - _rightContainer = new StackPanel() - { - Orientation = Orientation.Vertical, - Spacing = 10, - }; - mainLayout.Children.Add(_leftContainer); - mainLayout.Children.Add(_rightContainer); + [Content] public AvaloniaControlList Children { get; } = new(); - for (int i = 0; i < Children.Count; ++i) { - var control = Children[i]; - if (i % 2 == 0) { - _leftContainer.Children.Add(control); - } else { - _rightContainer.Children.Add(control); - } - } - var scrollView = new ScrollViewer() - { - Content = mainLayout, - }; - LogicalChildren.Add(scrollView); - VisualChildren.Add(scrollView); - } + protected void SetupUi() + { + var mainLayout = new UniformGrid + { + Rows = 1, + Columns = 2, + Margin = new Thickness(0) + }; + _leftContainer = new StackPanel + { + Orientation = Orientation.Vertical, + Spacing = 10, + Margin = new Thickness(0, 0, 10, 0) + }; + _rightContainer = new StackPanel + { + Orientation = Orientation.Vertical, + Spacing = 10 + }; + mainLayout.Children.Add(_leftContainer); + mainLayout.Children.Add(_rightContainer); - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - if (!_initialized) { - SetupUi(); - NotifyShowCaseLayoutReady(); - _initialized = true; - } - base.OnAttachedToLogicalTree(e); - } + for (var i = 0; i < Children.Count; ++i) + { + var control = Children[i]; + if (i % 2 == 0) + _leftContainer.Children.Add(control); + else + _rightContainer.Children.Add(control); + } - internal virtual void NotifyAboutToActive() - { - } + var scrollView = new ScrollViewer + { + Content = mainLayout + }; + LogicalChildren.Add(scrollView); + VisualChildren.Add(scrollView); + } - internal virtual void NotifyActivated() - { - } + protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) + { + if (!_initialized) + { + SetupUi(); + NotifyShowCaseLayoutReady(); + _initialized = true; + } - internal virtual void NotifyAboutToDeactivated() - { - } + base.OnAttachedToLogicalTree(e); + } - internal virtual void NotifyDeactivated() - { - } + internal virtual void NotifyAboutToActive() + { + } - protected virtual void NotifyShowCaseLayoutReady() - { - } + internal virtual void NotifyActivated() + { + } + + internal virtual void NotifyAboutToDeactivated() + { + } + + internal virtual void NotifyDeactivated() + { + } + + protected virtual void NotifyShowCaseLayoutReady() + { + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml index 93ac497..96f4e4e 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml +++ b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml @@ -39,4 +39,4 @@ - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs index c609c78..bf3657b 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs +++ b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs @@ -1,15 +1,19 @@ +using AtomUI.Demo.Desktop.ViewModels; using Avalonia; using Avalonia.Controls.Primitives; using Avalonia.Input; using CommunityToolkit.Mvvm.Messaging; -using AtomUI.Demo.Desktop.ViewModels; namespace AtomUI.Demo.Desktop.Controls; public class ColorItemControl : TemplatedControl { - public static readonly StyledProperty ColorNameProperty = AvaloniaProperty.Register( - nameof(ColorName)); + public static readonly StyledProperty ColorNameProperty = + AvaloniaProperty.Register( + nameof(ColorName)); + + public static readonly StyledProperty HexProperty = AvaloniaProperty.Register( + nameof(Hex)); public string? ColorName { @@ -17,22 +21,15 @@ public class ColorItemControl : TemplatedControl set => SetValue(ColorNameProperty, value); } - public static readonly StyledProperty HexProperty = AvaloniaProperty.Register( - nameof(Hex)); - public string? Hex { get => GetValue(HexProperty); set => SetValue(HexProperty, value); } - + protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); - if (this.DataContext is ColorItemViewModel v) - { - WeakReferenceMessenger.Default.Send(v); - } - + if (DataContext is ColorItemViewModel v) WeakReferenceMessenger.Default.Send(v); } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs index b07a34e..402783a 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs +++ b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs @@ -6,12 +6,13 @@ namespace AtomUI.Demo.Desktop.Controls; public class ColorListControl : TemplatedControl { - public static readonly StyledProperty ListDataProperty = AvaloniaProperty.Register( - nameof(ListData), new ColorListViewModel()); + public static readonly StyledProperty ListDataProperty = + AvaloniaProperty.Register( + nameof(ListData), new ColorListViewModel()); - public ColorListViewModel ListData - { - get => GetValue(ListDataProperty); - set => SetValue(ListDataProperty, value); - } + public ColorListViewModel ListData + { + get => GetValue(ListDataProperty); + set => SetValue(ListDataProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs index 7c3aae5..aa4e09c 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs +++ b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs @@ -6,12 +6,13 @@ namespace AtomUI.Demo.Desktop.Controls; public class ColorListGroupControl : TemplatedControl { - public static readonly StyledProperty GroupDataProperty = AvaloniaProperty.Register( - nameof(GroupData), new ColorGroupViewModel()); + public static readonly StyledProperty GroupDataProperty = + AvaloniaProperty.Register( + nameof(GroupData), new ColorGroupViewModel()); - public ColorGroupViewModel GroupData - { - get => GetValue(GroupDataProperty); - set => SetValue(GroupDataProperty, value); - } + public ColorGroupViewModel GroupData + { + get => GetValue(GroupDataProperty); + set => SetValue(GroupDataProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs index eab4b92..a9323b2 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs @@ -1,50 +1,47 @@ +using AtomUI.Demo.Desktop.ViewModels; +using AtomUI.Icon; using Avalonia; using Avalonia.Controls.Primitives; using Avalonia.Input; -using CommunityToolkit.Mvvm.Messaging; -using AtomUI.Demo.Desktop.ViewModels; -using AtomUI.Icon; using Avalonia.LogicalTree; +using CommunityToolkit.Mvvm.Messaging; namespace AtomUI.Demo.Desktop.Controls; public class IconGallery : TemplatedControl { - private bool _initialized = false; - private IconGalleryModel _galleryModel; - - public static readonly StyledProperty IconThemeTypeProperty = AvaloniaProperty.Register( - nameof(IconThemeType)); + public static readonly StyledProperty IconThemeTypeProperty = + AvaloniaProperty.Register( + nameof(IconThemeType)); - public IconThemeType? IconThemeType - { - get => GetValue(IconThemeTypeProperty); - set => SetValue(IconThemeTypeProperty, value); - } + private readonly IconGalleryModel _galleryModel; + private bool _initialized; - public IconGallery() - { - _galleryModel = new IconGalleryModel(); - DataContext = _galleryModel; - } + public IconGallery() + { + _galleryModel = new IconGalleryModel(); + DataContext = _galleryModel; + } - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - base.OnPointerPressed(e); - if (this.DataContext is ColorItemViewModel v) { - WeakReferenceMessenger.Default.Send(v); - } - } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - base.OnAttachedToLogicalTree(e); - if (!_initialized) { - if (IconThemeType.HasValue) { - _galleryModel.LoadThemeIcons(IconThemeType.Value); - } - _initialized = true; - } - } - + public IconThemeType? IconThemeType + { + get => GetValue(IconThemeTypeProperty); + set => SetValue(IconThemeTypeProperty, value); + } + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + base.OnPointerPressed(e); + if (DataContext is ColorItemViewModel v) WeakReferenceMessenger.Default.Send(v); + } + + protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) + { + base.OnAttachedToLogicalTree(e); + if (!_initialized) + { + if (IconThemeType.HasValue) _galleryModel.LoadThemeIcons(IconThemeType.Value); + _initialized = true; + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs index 11cfbfb..de1d233 100644 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs @@ -5,21 +5,21 @@ namespace AtomUI.Demo.Desktop.Controls; public class IconInfoItem : TemplatedControl { - public static readonly StyledProperty IconNameProperty = AvaloniaProperty.Register( - nameof(IconName)); + public static readonly StyledProperty IconNameProperty = AvaloniaProperty.Register( + nameof(IconName)); - public string IconName - { - get => GetValue(IconNameProperty); - set => SetValue(IconNameProperty, value); - } - - public static readonly StyledProperty IconKindProperty = AvaloniaProperty.Register( - nameof(IconKind)); + public static readonly StyledProperty IconKindProperty = AvaloniaProperty.Register( + nameof(IconKind)); - public string IconKind - { - get => GetValue(IconKindProperty); - set => SetValue(IconKindProperty, value); - } + public string IconName + { + get => GetValue(IconNameProperty); + set => SetValue(IconNameProperty, value); + } + + public string IconKind + { + get => GetValue(IconKindProperty); + set => SetValue(IconKindProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Program.cs b/samples/AtomUI.Demo.Desktop/Program.cs index 951320e..6123611 100644 --- a/samples/AtomUI.Demo.Desktop/Program.cs +++ b/samples/AtomUI.Demo.Desktop/Program.cs @@ -4,41 +4,43 @@ using AtomUI.Theme; using Avalonia; using Avalonia.Dialogs; using Avalonia.Media; - #if DEBUG using Nlnet.Avalonia.DevTools; #endif namespace AtomUI.Demo.Desktop; -class Program +internal class Program { - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. - [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .With(new FontManagerOptions - { - FontFallbacks = new[] - { - new FontFallback - { - FontFamily = new FontFamily("Microsoft YaHei") - } - } - }) - .StartWithClassicDesktopLifetime(args); - - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .UseManagedSystemDialogs() - .UsePlatformDetect() - .UseAtomUI() + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) + { + BuildAvaloniaApp() + .With(new FontManagerOptions + { + FontFallbacks = new[] + { + new FontFallback + { + FontFamily = new FontFamily("Microsoft YaHei") + } + } + }) + .StartWithClassicDesktopLifetime(args); + } + + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UseManagedSystemDialogs() + .UsePlatformDetect() + .UseAtomUI() #if DEBUG - .UseDevToolsForAvalonia() + .UseDevToolsForAvalonia() #endif - .UseIconPackage(true) - .With(new Win32PlatformOptions()) - .LogToTrace(); + .UseIconPackage(true) + .With(new Win32PlatformOptions()) + .LogToTrace(); } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml index 0aefa7d..ffec1d9 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -15,7 +14,8 @@ - + Success Text Info Text @@ -29,9 +29,10 @@ Warning Text Warning Text Warning Text Warning Text Warning Text Warning TextWarning Text - + Error Text - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs index 8402940..d57fb13 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class AlertShowCase : UserControl { - public AlertShowCase() - { - InitializeComponent(); - } + public AlertShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml index 400fa7d..a986c24 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs index 31dec67..eed53d3 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class AvatarShowCase : UserControl { - public AvatarShowCase() - { - InitializeComponent(); - } + public AvatarShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml index 41e1280..c860bd7 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml @@ -5,11 +5,11 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + - + - + - + - + @@ -294,7 +298,8 @@ - + DynamicBadgeCountProperty = - AvaloniaProperty.Register(nameof(DynamicBadgeCount), 5); - - public static readonly StyledProperty DynamicDotBadgeVisibleProperty = - AvaloniaProperty.Register(nameof(DynamicDotBadgeVisible), true); - - public static readonly StyledProperty StandaloneSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(StandaloneSwitchChecked), true); - - public static readonly StyledProperty StandaloneBadgeCount1Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount1), 11); - - public static readonly StyledProperty StandaloneBadgeCount2Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount2), 25); - - public static readonly StyledProperty StandaloneBadgeCount3Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount3), 109); - - public double DynamicBadgeCount - { - get => GetValue(DynamicBadgeCountProperty); - set => SetValue(DynamicBadgeCountProperty, value); - } - - public bool DynamicDotBadgeVisible - { - get => GetValue(DynamicDotBadgeVisibleProperty); - set => SetValue(DynamicDotBadgeVisibleProperty, value); - } - - public bool StandaloneSwitchChecked - { - get => GetValue(StandaloneSwitchCheckedProperty); - set => SetValue(StandaloneSwitchCheckedProperty, value); - } - - public double StandaloneBadgeCount1 - { - get => GetValue(StandaloneBadgeCount1Property); - set => SetValue(StandaloneBadgeCount1Property, value); - } - - public double StandaloneBadgeCount2 - { - get => GetValue(StandaloneBadgeCount2Property); - set => SetValue(StandaloneBadgeCount2Property, value); - } - - public double StandaloneBadgeCount3 - { - get => GetValue(StandaloneBadgeCount3Property); - set => SetValue(StandaloneBadgeCount3Property, value); - } - - public BadgeShowCase() - { - DataContext = this; - InitializeComponent(); - } - - public void AddDynamicBadgeCount() - { - DynamicBadgeCount += 1; - } + public static readonly StyledProperty DynamicBadgeCountProperty = + AvaloniaProperty.Register(nameof(DynamicBadgeCount), 5); - public void SubDynamicBadgeCount() - { - var value = DynamicBadgeCount; - value -= 1; - value = Math.Max(value, 0); - DynamicBadgeCount = value; - } - - public void RandomDynamicBadgeCount() - { - var random = new Random(); - DynamicBadgeCount = random.Next(0, 110); - } + public static readonly StyledProperty DynamicDotBadgeVisibleProperty = + AvaloniaProperty.Register(nameof(DynamicDotBadgeVisible), true); - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs args) - { - base.OnPropertyChanged(args); - if (args.Property == StandaloneSwitchCheckedProperty) { - var isChecked = args.GetNewValue(); - if (isChecked) { - StandaloneBadgeCount1 = 11; - StandaloneBadgeCount2 = 25; - StandaloneBadgeCount3 = 109; - } else { - StandaloneBadgeCount1 = 0; - StandaloneBadgeCount2 = 0; - StandaloneBadgeCount3 = 0; - } - } - } + public static readonly StyledProperty StandaloneSwitchCheckedProperty = + AvaloniaProperty.Register(nameof(StandaloneSwitchChecked), true); + + public static readonly StyledProperty StandaloneBadgeCount1Property = + AvaloniaProperty.Register(nameof(StandaloneBadgeCount1), 11); + + public static readonly StyledProperty StandaloneBadgeCount2Property = + AvaloniaProperty.Register(nameof(StandaloneBadgeCount2), 25); + + public static readonly StyledProperty StandaloneBadgeCount3Property = + AvaloniaProperty.Register(nameof(StandaloneBadgeCount3), 109); + + public BadgeShowCase() + { + DataContext = this; + InitializeComponent(); + } + + public double DynamicBadgeCount + { + get => GetValue(DynamicBadgeCountProperty); + set => SetValue(DynamicBadgeCountProperty, value); + } + + public bool DynamicDotBadgeVisible + { + get => GetValue(DynamicDotBadgeVisibleProperty); + set => SetValue(DynamicDotBadgeVisibleProperty, value); + } + + public bool StandaloneSwitchChecked + { + get => GetValue(StandaloneSwitchCheckedProperty); + set => SetValue(StandaloneSwitchCheckedProperty, value); + } + + public double StandaloneBadgeCount1 + { + get => GetValue(StandaloneBadgeCount1Property); + set => SetValue(StandaloneBadgeCount1Property, value); + } + + public double StandaloneBadgeCount2 + { + get => GetValue(StandaloneBadgeCount2Property); + set => SetValue(StandaloneBadgeCount2Property, value); + } + + public double StandaloneBadgeCount3 + { + get => GetValue(StandaloneBadgeCount3Property); + set => SetValue(StandaloneBadgeCount3Property, value); + } + + public void AddDynamicBadgeCount() + { + DynamicBadgeCount += 1; + } + + public void SubDynamicBadgeCount() + { + var value = DynamicBadgeCount; + value -= 1; + value = Math.Max(value, 0); + DynamicBadgeCount = value; + } + + public void RandomDynamicBadgeCount() + { + var random = new Random(); + DynamicBadgeCount = random.Next(0, 110); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs args) + { + base.OnPropertyChanged(args); + if (args.Property == StandaloneSwitchCheckedProperty) + { + var isChecked = args.GetNewValue(); + if (isChecked) + { + StandaloneBadgeCount1 = 11; + StandaloneBadgeCount2 = 25; + StandaloneBadgeCount3 = 109; + } + else + { + StandaloneBadgeCount1 = 0; + StandaloneBadgeCount2 = 0; + StandaloneBadgeCount3 = 0; + } + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml index 0ea635e..ba56f40 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -13,7 +12,8 @@ - + Primary Button Default Button @@ -22,7 +22,8 @@ - + - + - + - + @@ -200,7 +204,8 @@ - + @@ -236,7 +241,8 @@ - + @@ -292,7 +298,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs index e93842f..76d6387 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs @@ -9,46 +9,46 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class ButtonShowCase : UserControl { - public static readonly StyledProperty ButtonSizeTypeProperty = - AvaloniaProperty.Register(nameof(ButtonSizeType), SizeType.Large); - - public SizeType ButtonSizeType - { - get => GetValue(ButtonSizeTypeProperty); - set => SetValue(ButtonSizeTypeProperty, value); - } - - public ButtonShowCase() - { - InitializeComponent(); - DataContext = this; - - ButtonSizeTypeOptionGroup.OptionCheckedChanged += HandleButtonSizeTypeOptionCheckedChanged; - LoadingBtn1.Click += HandleLoadingBtnClick; - LoadingBtn2.Click += HandleLoadingBtnClick; - LoadingBtn3.Click += HandleLoadingBtnClick; - } - - private void HandleButtonSizeTypeOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) { - ButtonSizeType = SizeType.Large; - } else if (args.Index == 1) { - ButtonSizeType = SizeType.Middle; - } else { - ButtonSizeType = SizeType.Small; - } - } + public static readonly StyledProperty ButtonSizeTypeProperty = + AvaloniaProperty.Register(nameof(ButtonSizeType)); - private void HandleLoadingBtnClick(object? sender, RoutedEventArgs args) - { - if (sender is Button button) { - button.IsLoading = true; - Dispatcher.UIThread.InvokeAsync(async () => - { - await Task.Delay(TimeSpan.FromSeconds(3)); - button.IsLoading = false; - }); - } - } + public ButtonShowCase() + { + InitializeComponent(); + DataContext = this; + + ButtonSizeTypeOptionGroup.OptionCheckedChanged += HandleButtonSizeTypeOptionCheckedChanged; + LoadingBtn1.Click += HandleLoadingBtnClick; + LoadingBtn2.Click += HandleLoadingBtnClick; + LoadingBtn3.Click += HandleLoadingBtnClick; + } + + public SizeType ButtonSizeType + { + get => GetValue(ButtonSizeTypeProperty); + set => SetValue(ButtonSizeTypeProperty, value); + } + + private void HandleButtonSizeTypeOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) + { + if (args.Index == 0) + ButtonSizeType = SizeType.Large; + else if (args.Index == 1) + ButtonSizeType = SizeType.Middle; + else + ButtonSizeType = SizeType.Small; + } + + private void HandleLoadingBtnClick(object? sender, RoutedEventArgs args) + { + if (sender is Button button) + { + button.IsLoading = true; + Dispatcher.UIThread.InvokeAsync(async () => + { + await Task.Delay(TimeSpan.FromSeconds(3)); + button.IsLoading = false; + }); + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml index 687e057..07f2f82 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -16,7 +15,8 @@ - + @@ -130,7 +130,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs index 50a3138..3fcd158 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs @@ -4,39 +4,35 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class ButtonSpinnerShowCase : UserControl { - public ButtonSpinnerShowCase() - { - InitializeComponent(); - } - - public void HandleSpin(object sender, SpinEventArgs e) - { - var spinner = (ButtonSpinner)sender; + private readonly string[] _spinnerItems = + { + "床前明月光", + "疑是地上霜", + "举头望明月", + "低头思故乡" + }; - if (spinner.Content is TextBlock textBlock) - { - int value = Array.IndexOf(_spinnerItems, textBlock.Text); - if (e.Direction == SpinDirection.Increase) { - value++; - } else { - value--; - } + public ButtonSpinnerShowCase() + { + InitializeComponent(); + } - if (value < 0) { - value = _spinnerItems.Length - 1; - } else if (value >= _spinnerItems.Length) { - value = 0; - } - textBlock.Text = _spinnerItems[value]; - } + public void HandleSpin(object sender, SpinEventArgs e) + { + var spinner = (ButtonSpinner)sender; - } - - private readonly string[] _spinnerItems = new[] - { - "床前明月光", - "疑是地上霜", - "举头望明月", - "低头思故乡" - }; + if (spinner.Content is TextBlock textBlock) + { + var value = Array.IndexOf(_spinnerItems, textBlock.Text); + if (e.Direction == SpinDirection.Increase) + value++; + else + value--; + + if (value < 0) + value = _spinnerItems.Length - 1; + else if (value >= _spinnerItems.Length) value = 0; + textBlock.Text = _spinnerItems[value]; + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml index 1d89a62..abfdef0 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs index 0375dfe..27982f0 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class CardShowCase : UserControl { - public CardShowCase() - { - InitializeComponent(); - } + public CardShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml index 2065161..3e8fbd8 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -79,7 +78,8 @@ - + @@ -111,7 +111,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs index ce54b25..d2f01c1 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs @@ -5,9 +5,9 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class CheckBoxShowCase : UserControl { - public CheckBoxShowCase() - { - DataContext = new CheckBoxShowCaseModel(); - InitializeComponent(); - } + public CheckBoxShowCase() + { + DataContext = new CheckBoxShowCaseModel(); + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml index 9605355..88224c9 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + @@ -28,7 +28,8 @@ - + @@ -65,7 +66,8 @@ - + @@ -155,17 +157,20 @@ Description="Render extra element in the top-right corner of each panel."> - + A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - + A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - + A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs index eab86f2..66872da 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs @@ -6,28 +6,27 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class CollapseShowCase : UserControl { - public static readonly StyledProperty CollapseExpandIconPositionProperty = - AvaloniaProperty.Register(nameof(CollapseExpandIconPosition), CollapseExpandIconPosition.Start); - - public CollapseExpandIconPosition CollapseExpandIconPosition - { - get => GetValue(CollapseExpandIconPositionProperty); - set => SetValue(CollapseExpandIconPositionProperty, value); - } - - public CollapseShowCase() - { - InitializeComponent(); - DataContext = this; - //ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; - } - - private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) { - CollapseExpandIconPosition = CollapseExpandIconPosition.Start; - } else if (args.Index == 1) { - CollapseExpandIconPosition = CollapseExpandIconPosition.End; - } - } + public static readonly StyledProperty CollapseExpandIconPositionProperty = + AvaloniaProperty.Register(nameof(CollapseExpandIconPosition)); + + public CollapseShowCase() + { + InitializeComponent(); + DataContext = this; + + //ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; + } + + public CollapseExpandIconPosition CollapseExpandIconPosition + { + get => GetValue(CollapseExpandIconPositionProperty); + set => SetValue(CollapseExpandIconPositionProperty, value); + } + + private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) + { + if (args.Index == 0) + CollapseExpandIconPosition = CollapseExpandIconPosition.Start; + else if (args.Index == 1) CollapseExpandIconPosition = CollapseExpandIconPosition.End; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml index a8848fc..7bfa4d5 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -19,7 +18,8 @@ - + @@ -148,7 +148,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs index b0b4efd..2552c89 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class ComboBoxShowCase : UserControl { - public ComboBoxShowCase() - { - InitializeComponent(); - } + public ComboBoxShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs index 48a23e8..62d4bf7 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class DatePickerShowCase : UserControl { - public DatePickerShowCase() - { - InitializeComponent(); - } + public DatePickerShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml index c136226..5937b32 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml @@ -1,11 +1,9 @@  \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml index 2867976..d367667 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" xmlns:utils="clr-namespace:AtomUI.Demo.Desktop.Utils" mc:Ignorable="d"> @@ -51,7 +50,8 @@ - + @@ -66,15 +66,17 @@ - + - + - + @@ -102,9 +105,10 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs index 65ecc1f..2686364 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs @@ -8,28 +8,22 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class DrawerShowCase : UserControl { - public DrawerShowCase() - { - InitializeComponent(); - } + public DrawerShowCase() + { + InitializeComponent(); + } - private void Button_OnClick(object? sender, RoutedEventArgs e) - { - if (sender is not Button button) - { - return; - } + private void Button_OnClick(object? sender, RoutedEventArgs e) + { + if (sender is not Button button) return; - if (Drawer.GetDrawer(button) is not { } drawer) - { - return; - } + if (Drawer.GetDrawer(button) is not { } drawer) return; - drawer.IsOpen = false; - } + drawer.IsOpen = false; + } - private void ButtonOpenOnCurrentParent_OnClick(object? sender, RoutedEventArgs e) - { - Drawer1.OpenOn = Drawer1.OpenOn?.Parent as Visual; - } + private void ButtonOpenOnCurrentParent_OnClick(object? sender, RoutedEventArgs e) + { + Drawer1.OpenOn = Drawer1.OpenOn?.Parent as Visual; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml index eca2815..29e09b9 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs index b9074f3..ae93eb5 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class DropdownButtonShowCase : UserControl { - public DropdownButtonShowCase() - { - InitializeComponent(); - } + public DropdownButtonShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml index a2ced8e..a31bdc5 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml @@ -5,14 +5,14 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + @@ -22,7 +22,8 @@ - + - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs index 81f2454..afcaa1e 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class EmptyShowCase : UserControl { - public EmptyShowCase() - { - InitializeComponent(); - } + public EmptyShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml index 9ac3467..6b0b06b 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -16,7 +15,8 @@ - + @@ -47,7 +47,8 @@ - + ToggleIconPositionProperty = - AvaloniaProperty.Register(nameof(ToggleIconPosition), ExpanderIconPosition.Start); - - public ExpanderIconPosition ToggleIconPosition - { - get => GetValue(ToggleIconPositionProperty); - set => SetValue(ToggleIconPositionProperty, value); - } - - public static readonly StyledProperty ExpandDirectionProperty = - AvaloniaProperty.Register(nameof(ExpandDirection), ExpandDirection.Down); - - public ExpandDirection ExpandDirection - { - get => GetValue(ExpandDirectionProperty); - set => SetValue(ExpandDirectionProperty, value); - } - - public ExpanderShowCase() - { - InitializeComponent(); - DataContext = this; - ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; - ExpandDirectionOptionGroup.OptionCheckedChanged += HandleExpandDirectionOptionCheckedChanged; - } - - private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) { - ToggleIconPosition = ExpanderIconPosition.Start; - } else if (args.Index == 1) { - ToggleIconPosition = ExpanderIconPosition.End; - } - } - - private void HandleExpandDirectionOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) { - ExpandDirection = ExpandDirection.Down; - } else if (args.Index == 1) { - ExpandDirection = ExpandDirection.Up; - } else if (args.Index == 2) { - ExpandDirection = ExpandDirection.Left; - } else if (args.Index == 3) { - ExpandDirection = ExpandDirection.Right; - } - } + public static readonly StyledProperty ToggleIconPositionProperty = + AvaloniaProperty.Register(nameof(ToggleIconPosition)); + + public static readonly StyledProperty ExpandDirectionProperty = + AvaloniaProperty.Register(nameof(ExpandDirection)); + + public ExpanderShowCase() + { + InitializeComponent(); + DataContext = this; + ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; + ExpandDirectionOptionGroup.OptionCheckedChanged += HandleExpandDirectionOptionCheckedChanged; + } + + public ExpanderIconPosition ToggleIconPosition + { + get => GetValue(ToggleIconPositionProperty); + set => SetValue(ToggleIconPositionProperty, value); + } + + public ExpandDirection ExpandDirection + { + get => GetValue(ExpandDirectionProperty); + set => SetValue(ExpandDirectionProperty, value); + } + + private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) + { + if (args.Index == 0) + ToggleIconPosition = ExpanderIconPosition.Start; + else if (args.Index == 1) ToggleIconPosition = ExpanderIconPosition.End; + } + + private void HandleExpandDirectionOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) + { + if (args.Index == 0) + ExpandDirection = ExpandDirection.Down; + else if (args.Index == 1) + ExpandDirection = ExpandDirection.Up; + else if (args.Index == 2) + ExpandDirection = ExpandDirection.Left; + else if (args.Index == 3) ExpandDirection = ExpandDirection.Right; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml index 956de0a..21f2742 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -18,7 +17,8 @@ - + @@ -44,7 +44,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs index 0e4deec..42e7a90 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class GroupBoxShowCase : UserControl { - public GroupBoxShowCase() - { - InitializeComponent(); - } + public GroupBoxShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs index 8d6bc44..d7d3095 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs @@ -1,25 +1,22 @@ +using AtomUI.Demo.Desktop.ViewModels; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Threading; -using AtomUI.Demo.Desktop.ViewModels; namespace AtomUI.Demo.Desktop.ShowCase; public partial class IconShowCase : UserControl { - public IconShowCase() - { - InitializeComponent(); - } + public IconShowCase() + { + InitializeComponent(); + } - protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - PaletteDemoViewModel vm = new PaletteDemoViewModel(); - await Dispatcher.UIThread.InvokeAsync(() => - { - vm.InitializeResources(); - }); - DataContext = vm; - } + protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + var vm = new PaletteDemoViewModel(); + await Dispatcher.UIThread.InvokeAsync(() => { vm.InitializeResources(); }); + DataContext = vm; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml index c4064b1..0292f9b 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs index 4ec0ddb..b96ffb4 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs @@ -6,44 +6,49 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class InfoFlyoutShowCase : UserControl { - public static readonly StyledProperty ShowArrowProperty = - AvaloniaProperty.Register(nameof(ShowArrow), true); - - public static readonly StyledProperty IsPointAtCenterProperty = - AvaloniaProperty.Register(nameof(IsPointAtCenter), false); + public static readonly StyledProperty ShowArrowProperty = + AvaloniaProperty.Register(nameof(ShowArrow), true); - private Segmented _segmented; - - public bool ShowArrow - { - get => GetValue(ShowArrowProperty); - set => SetValue(ShowArrowProperty, value); - } - - public bool IsPointAtCenter - { - get => GetValue(IsPointAtCenterProperty); - set => SetValue(IsPointAtCenterProperty, value); - } - - public InfoFlyoutShowCase() - { - DataContext = this; - InitializeComponent(); - var control = this as Control; - _segmented = control.FindControl("ArrowSegmented")!; - _segmented.SelectionChanged += (sender, args) => - { - if (_segmented.SelectedIndex == 0) { - ShowArrow = true; - IsPointAtCenter = false; - } else if (_segmented.SelectedIndex == 1) { - ShowArrow = false; - IsPointAtCenter = false; - } else if (_segmented.SelectedIndex == 2) { - IsPointAtCenter = true; - ShowArrow = true; - } - }; - } + public static readonly StyledProperty IsPointAtCenterProperty = + AvaloniaProperty.Register(nameof(IsPointAtCenter)); + + private readonly Segmented _segmented; + + public InfoFlyoutShowCase() + { + DataContext = this; + InitializeComponent(); + var control = this as Control; + _segmented = control.FindControl("ArrowSegmented")!; + _segmented.SelectionChanged += (sender, args) => + { + if (_segmented.SelectedIndex == 0) + { + ShowArrow = true; + IsPointAtCenter = false; + } + else if (_segmented.SelectedIndex == 1) + { + ShowArrow = false; + IsPointAtCenter = false; + } + else if (_segmented.SelectedIndex == 2) + { + IsPointAtCenter = true; + ShowArrow = true; + } + }; + } + + public bool ShowArrow + { + get => GetValue(ShowArrowProperty); + set => SetValue(ShowArrowProperty, value); + } + + public bool IsPointAtCenter + { + get => GetValue(IsPointAtCenterProperty); + set => SetValue(IsPointAtCenterProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml index e843807..08b8156 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml @@ -5,14 +5,14 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + @@ -55,7 +55,8 @@ - + - + Watermark="Enter your username" /> - + @@ -127,7 +130,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs index 0ff4537..3a337d9 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class LineEditShowCase : UserControl { - public LineEditShowCase() - { - InitializeComponent(); - } - + public LineEditShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml index 22958d6..7b9af8d 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs index 7c9b24e..50c1f1a 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class ListBoxShowCase : UserControl { - public ListBoxShowCase() - { - InitializeComponent(); - } + public ListBoxShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml index 816f7fa..87c1070 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml @@ -5,14 +5,14 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs index a1c7be9..0fb6e9e 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs @@ -5,19 +5,18 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class LoadingIndicatorShowCase : UserControl { - public static readonly StyledProperty IsLoadingSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(IsLoadingSwitchChecked), false); - - public bool IsLoadingSwitchChecked - { - get => GetValue(IsLoadingSwitchCheckedProperty); - set => SetValue(IsLoadingSwitchCheckedProperty, value); - } - - public LoadingIndicatorShowCase() - { - DataContext = this; - InitializeComponent(); - } - + public static readonly StyledProperty IsLoadingSwitchCheckedProperty = + AvaloniaProperty.Register(nameof(IsLoadingSwitchChecked)); + + public LoadingIndicatorShowCase() + { + DataContext = this; + InitializeComponent(); + } + + public bool IsLoadingSwitchChecked + { + get => GetValue(IsLoadingSwitchCheckedProperty); + set => SetValue(IsLoadingSwitchCheckedProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml index e776e0b..e2e9944 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -59,7 +58,8 @@ - + - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs index 0efbe47..ef812aa 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class MenuShowCase : UserControl { - public MenuShowCase() - { - InitializeComponent(); - } - + public MenuShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml index ae0fdb5..5fda375 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -14,7 +13,8 @@ - + Success @@ -31,13 +31,15 @@ - + Display a loading indicator - + Display a loading indicator diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs index a09e8e5..d6fea18 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs @@ -7,92 +7,92 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class MessageShowCase : UserControl { - private WindowMessageManager? _messageManager; + private WindowMessageManager? _messageManager; - public MessageShowCase() - { - InitializeComponent(); - } + public MessageShowCase() + { + InitializeComponent(); + } - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var topLevel = TopLevel.GetTopLevel(this); - _messageManager = new WindowMessageManager(topLevel) - { - MaxItems = 10 - }; - } + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + var topLevel = TopLevel.GetTopLevel(this); + _messageManager = new WindowMessageManager(topLevel) + { + MaxItems = 10 + }; + } - private void ShowSimpleMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - content: "Hello, AtomUI/Avalonia!" - )); - } + private void ShowSimpleMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + "Hello, AtomUI/Avalonia!" + )); + } - private void ShowInfoMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Information, - content: "This is a information message." - )); - } + private void ShowInfoMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Information, + content: "This is a information message." + )); + } - private void ShowSuccessMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Success, - content: "This is a success message." - )); - } + private void ShowSuccessMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Success, + content: "This is a success message." + )); + } - private void ShowWarningMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Warning, - content: "This is a warning message." - )); - } + private void ShowWarningMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Warning, + content: "This is a warning message." + )); + } - private void ShowErrorMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Error, - content: "This is a error message." - )); - } + private void ShowErrorMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Error, + content: "This is a error message." + )); + } - private void ShowLoadingMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Loading, - content: "Action in progress..." - )); - } + private void ShowLoadingMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Loading, + content: "Action in progress..." + )); + } - private void ShowSequentialMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Loading, - content: "Action in progress...", - expiration: TimeSpan.FromSeconds(2.5), - onClose: () => - { - _messageManager?.Show(new Message( - type: MessageType.Success, - expiration: TimeSpan.FromSeconds(2.5), - content: "Loading finished", - onClose: () => - { - _messageManager?.Show(new Message( - type: MessageType.Information, - expiration: TimeSpan.FromSeconds(2.5), - content: "Loading finished" - )); - } - )); - } - )); - } + private void ShowSequentialMessage(object? sender, RoutedEventArgs e) + { + _messageManager?.Show(new Message( + type: MessageType.Loading, + content: "Action in progress...", + expiration: TimeSpan.FromSeconds(2.5), + onClose: () => + { + _messageManager?.Show(new Message( + type: MessageType.Success, + expiration: TimeSpan.FromSeconds(2.5), + content: "Loading finished", + onClose: () => + { + _messageManager?.Show(new Message( + type: MessageType.Information, + expiration: TimeSpan.FromSeconds(2.5), + content: "Loading finished" + )); + } + )); + } + )); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml index a97fc41..8ce5316 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -14,13 +13,15 @@ - + Open the notification box - + Success @@ -37,7 +38,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs index 318092a..72dd8d3 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs @@ -8,199 +8,204 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class NotificationShowCase : UserControl { - private WindowNotificationManager? _basicManager; - private WindowNotificationManager? _topLeftManager; - private WindowNotificationManager? _topManager; - private WindowNotificationManager? _topRightManager; - - private WindowNotificationManager? _bottomLeftManager; - private WindowNotificationManager? _bottomManager; - private WindowNotificationManager? _bottomRightManager; - - public NotificationShowCase() - { - InitializeComponent(); - HoverOptionGroup.OptionCheckedChanged += HandleHoverOptionGroupCheckedChanged; - } + private WindowNotificationManager? _basicManager; - private void HandleHoverOptionGroupCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (_basicManager is not null) { - if (args.Index == 0) { - _basicManager.IsPauseOnHover = true; - } else { - _basicManager.IsPauseOnHover = false; - } - } - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var topLevel = TopLevel.GetTopLevel(this); - _basicManager = new WindowNotificationManager(topLevel) - { - MaxItems = 3 - }; - - _topLeftManager = new WindowNotificationManager(topLevel) - { - MaxItems = 3, - Position = NotificationPosition.TopLeft - }; - - _topManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.TopCenter, - MaxItems = 3 - }; - - _topRightManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.TopRight, - MaxItems = 3 - }; - - _bottomLeftManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomLeft, - MaxItems = 3 - }; - - _bottomManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomCenter, - MaxItems = 3 - }; - - _bottomRightManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomRight, - MaxItems = 3 - }; - } + private WindowNotificationManager? _bottomLeftManager; + private WindowNotificationManager? _bottomManager; + private WindowNotificationManager? _bottomRightManager; + private WindowNotificationManager? _topLeftManager; + private WindowNotificationManager? _topManager; + private WindowNotificationManager? _topRightManager; - private void ShowSimpleNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - title: "Notification Title", - content: "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowNeverCloseNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - expiration : TimeSpan.Zero, - title : "Notification Title", - content : "I will never close automatically. This is a purposely very very long description that has many many characters and words." - )); - } - - private void ShowSuccessNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Success, - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowInfoNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Information, - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowWarningNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Warning, - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowErrorNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Error, - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowTopNotification(object? sender, RoutedEventArgs e) - { - _topManager?.Show(new Notification( - title : "Notification Top", - content : "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomNotification(object? sender, RoutedEventArgs e) - { - _bottomManager?.Show(new Notification( - title : "Notification Bottom", - content : "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowTopLeftNotification(object? sender, RoutedEventArgs e) - { - _topLeftManager?.Show(new Notification( - title : "Notification TopLeft", - content : "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowTopRightNotification(object? sender, RoutedEventArgs e) - { - _topRightManager?.Show(new Notification( - title : "Notification TopRight", - content : "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomLeftNotification(object? sender, RoutedEventArgs e) - { - _bottomLeftManager?.Show(new Notification( - title : "Notification BottomLeft", - content : "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomRightNotification(object? sender, RoutedEventArgs e) - { - _bottomRightManager?.Show(new Notification( - title : "Notification BottomRight", - content : "Hello, AtomUI/Avalonia!" - )); - } - - - private void ShowCustomIconNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification.", - icon: new PathIcon() - { - Kind = "SettingOutlined" - } - )); - } - - private void ShowProgressNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Information, - title: "Notification Title", - content: "This is the content of the notification. This is the content of the notification. This is the content of the notification.", - showProgress:true - )); - } + public NotificationShowCase() + { + InitializeComponent(); + HoverOptionGroup.OptionCheckedChanged += HandleHoverOptionGroupCheckedChanged; + } + + private void HandleHoverOptionGroupCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) + { + if (_basicManager is not null) + { + if (args.Index == 0) + _basicManager.IsPauseOnHover = true; + else + _basicManager.IsPauseOnHover = false; + } + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + var topLevel = TopLevel.GetTopLevel(this); + _basicManager = new WindowNotificationManager(topLevel) + { + MaxItems = 3 + }; + + _topLeftManager = new WindowNotificationManager(topLevel) + { + MaxItems = 3, + Position = NotificationPosition.TopLeft + }; + + _topManager = new WindowNotificationManager(topLevel) + { + Position = NotificationPosition.TopCenter, + MaxItems = 3 + }; + + _topRightManager = new WindowNotificationManager(topLevel) + { + Position = NotificationPosition.TopRight, + MaxItems = 3 + }; + + _bottomLeftManager = new WindowNotificationManager(topLevel) + { + Position = NotificationPosition.BottomLeft, + MaxItems = 3 + }; + + _bottomManager = new WindowNotificationManager(topLevel) + { + Position = NotificationPosition.BottomCenter, + MaxItems = 3 + }; + + _bottomRightManager = new WindowNotificationManager(topLevel) + { + Position = NotificationPosition.BottomRight, + MaxItems = 3 + }; + } + + private void ShowSimpleNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + "Notification Title", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowNeverCloseNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + expiration: TimeSpan.Zero, + title: "Notification Title", + content: + "I will never close automatically. This is a purposely very very long description that has many many characters and words." + )); + } + + private void ShowSuccessNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + type: NotificationType.Success, + title: "Notification Title", + content: + "This is the content of the notification. This is the content of the notification. This is the content of the notification." + )); + } + + private void ShowInfoNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + type: NotificationType.Information, + title: "Notification Title", + content: + "This is the content of the notification. This is the content of the notification. This is the content of the notification." + )); + } + + private void ShowWarningNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + type: NotificationType.Warning, + title: "Notification Title", + content: + "This is the content of the notification. This is the content of the notification. This is the content of the notification." + )); + } + + private void ShowErrorNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + type: NotificationType.Error, + title: "Notification Title", + content: + "This is the content of the notification. This is the content of the notification. This is the content of the notification." + )); + } + + private void ShowTopNotification(object? sender, RoutedEventArgs e) + { + _topManager?.Show(new Notification( + "Notification Top", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowBottomNotification(object? sender, RoutedEventArgs e) + { + _bottomManager?.Show(new Notification( + "Notification Bottom", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowTopLeftNotification(object? sender, RoutedEventArgs e) + { + _topLeftManager?.Show(new Notification( + "Notification TopLeft", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowTopRightNotification(object? sender, RoutedEventArgs e) + { + _topRightManager?.Show(new Notification( + "Notification TopRight", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowBottomLeftNotification(object? sender, RoutedEventArgs e) + { + _bottomLeftManager?.Show(new Notification( + "Notification BottomLeft", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowBottomRightNotification(object? sender, RoutedEventArgs e) + { + _bottomRightManager?.Show(new Notification( + "Notification BottomRight", + "Hello, AtomUI/Avalonia!" + )); + } + + private void ShowCustomIconNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + "Notification Title", + "This is the content of the notification. This is the content of the notification. This is the content of the notification.", + icon: new PathIcon + { + Kind = "SettingOutlined" + } + )); + } + + private void ShowProgressNotification(object? sender, RoutedEventArgs e) + { + _basicManager?.Show(new Notification( + type: NotificationType.Information, + title: "Notification Title", + content: + "This is the content of the notification. This is the content of the notification. This is the content of the notification.", + showProgress: true + )); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml index f255e07..2bbb74c 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml @@ -5,14 +5,14 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + @@ -49,7 +49,8 @@ - + - + Watermark="Enter your value" /> - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs index 09e50d1..2379bcc 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class NumberUpDownShowCase : UserControl { - public NumberUpDownShowCase() - { - InitializeComponent(); - } - + public NumberUpDownShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml index e3597ca..8e686ed 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml @@ -3,14 +3,12 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="clr-namespace:Avalonia.Markup.Xaml.Converters;assembly=Avalonia.Markup.Xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:AtomUI.Demo.Desktop.ShowCase" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="1000" d:DesignWidth="1920" mc:Ignorable="d"> - diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs index 0acfd98..40a4037 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs @@ -12,32 +12,32 @@ public partial class Overview : UserControl public string MainInstall { get; set; } = "dotnet add package AtomUI --version 11.0.7"; public string MainStyle { get; set; } = """ - - - -"""; + + + + """; public string ColorPickerInstall { get; set; } = "dotnet add package AtomUI.ColorPicker --version 11.0.7"; public string ColorPickerStyle { get; set; } = """ - - - -"""; + + + + """; public string DataGridInstall { get; set; } = "dotnet add package AtomUI.DataGrid --version 11.0.7"; public string DataGridStyle { get; set; } = """ - - - -"""; + + + + """; public string TreeDataGridInstall { get; set; } = "dotnet add package AtomUI.TreeDataGrid --version 11.0.7"; public string TreeDataGridStyle { get; set; } = """ - - - -"""; + + + + """; } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml index 1907056..046d973 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs index 5b324cc..34080ce 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class PaginationShowCase : UserControl { - public PaginationShowCase() - { - InitializeComponent(); - } + public PaginationShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs index 595d318..10e8e31 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs @@ -1,7 +1,7 @@ +using AtomUI.Demo.Desktop.ViewModels; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Threading; -using AtomUI.Demo.Desktop.ViewModels; namespace AtomUI.Demo.Desktop.ShowCase; @@ -12,14 +12,11 @@ public partial class PaletteShowCase : UserControl InitializeComponent(); } - protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) + protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - PaletteDemoViewModel vm = new PaletteDemoViewModel(); - await Dispatcher.UIThread.InvokeAsync(() => - { - vm.InitializeResources(); - }); + var vm = new PaletteDemoViewModel(); + await Dispatcher.UIThread.InvokeAsync(() => { vm.InitializeResources(); }); DataContext = vm; } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml index b9add2f..74a9f20 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + - + Delete diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs index ef28018..3b418fb 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class PopupConfirmShowCase : UserControl { - public PopupConfirmShowCase() - { - InitializeComponent(); - } + public PopupConfirmShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml index 0f9133d..eeaac1f 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -118,7 +117,8 @@ - + - + - + - + - + - + - + @@ -424,7 +430,8 @@ - + - + - + @@ -576,7 +585,8 @@ - + @@ -618,7 +628,8 @@ - + @@ -660,7 +671,8 @@ - + ProgressValueProperty = + AvaloniaProperty.Register(nameof(ProgressValue), 30); - public LinearGradientBrush ThreeStopsGradientStrokeColor { get; set; } + public static readonly StyledProperty ToggleDisabledTextProperty = + AvaloniaProperty.Register(nameof(ToggleDisabledText), "Disable"); - public List StepsChunkBrushes { get; set; } + public static readonly StyledProperty ToggleStatusProperty = + AvaloniaProperty.Register(nameof(ToggleStatus), true); - public PercentPosition InnerStartPercentPosition { get; set; } - public PercentPosition InnerCenterPercentPosition { get; set; } - public PercentPosition InnerEndPercentPosition { get; set; } - - public PercentPosition OutterStartPercentPosition { get; set; } - public PercentPosition OutterCenterPercentPosition { get; set; } - public PercentPosition OutterEndPercentPosition { get; set; } + public ProgressBarShowCase() + { + InitializeComponent(); + DataContext = this; - public static readonly StyledProperty ProgressValueProperty = - AvaloniaProperty.Register(nameof(ProgressValue), 30); - - public static readonly StyledProperty ToggleDisabledTextProperty = - AvaloniaProperty.Register(nameof(ToggleDisabledText), "Disable"); - - public static readonly StyledProperty ToggleStatusProperty = - AvaloniaProperty.Register(nameof(ToggleStatus), true); - - public double ProgressValue - { - get => GetValue(ProgressValueProperty); - set => SetValue(ProgressValueProperty, value); - } - - public string ToggleDisabledText - { - get => GetValue(ToggleDisabledTextProperty); - set => SetValue(ToggleDisabledTextProperty, value); - } - - public bool ToggleStatus - { - get => GetValue(ToggleStatusProperty); - set => SetValue(ToggleStatusProperty, value); - } - - public ProgressBarShowCase() - { - InitializeComponent(); - DataContext = this; + TwoStopsGradientStrokeColor = new LinearGradientBrush + { + GradientStops = + { + new GradientStop(Color.Parse("#108ee9"), 0), + new GradientStop(Color.Parse("#87d068"), 1) + } + }; + ThreeStopsGradientStrokeColor = new LinearGradientBrush + { + GradientStops = + { + new GradientStop(Color.Parse("#87d068"), 0), + new GradientStop(Color.Parse("#ffe58f"), 0.5), + new GradientStop(Color.Parse("#ffccc7"), 1) + } + }; + StepsChunkBrushes = new List + { + new SolidColorBrush(Colors.Green), + new SolidColorBrush(Colors.Green), + new SolidColorBrush(Colors.Red) + }; - TwoStopsGradientStrokeColor = new LinearGradientBrush() - { - GradientStops = - { - new GradientStop(Color.Parse("#108ee9"), 0), - new GradientStop(Color.Parse("#87d068"), 1) - } - }; - ThreeStopsGradientStrokeColor = new LinearGradientBrush() - { - GradientStops = - { - new GradientStop(Color.Parse("#87d068"), 0), - new GradientStop(Color.Parse("#ffe58f"), 0.5), - new GradientStop(Color.Parse("#ffccc7"), 1) - } - }; - StepsChunkBrushes = new List() - { - new SolidColorBrush(Colors.Green), - new SolidColorBrush(Colors.Green), - new SolidColorBrush(Colors.Red) - }; + InnerStartPercentPosition = new PercentPosition + { + IsInner = true, + Alignment = LinePercentAlignment.Start + }; + InnerCenterPercentPosition = new PercentPosition + { + IsInner = true, + Alignment = LinePercentAlignment.Center + }; + InnerEndPercentPosition = new PercentPosition + { + IsInner = true, + Alignment = LinePercentAlignment.End + }; - InnerStartPercentPosition = new PercentPosition() - { - IsInner = true, - Alignment = LinePercentAlignment.Start - }; - InnerCenterPercentPosition = new PercentPosition() - { - IsInner = true, - Alignment = LinePercentAlignment.Center - }; - InnerEndPercentPosition = new PercentPosition() - { - IsInner = true, - Alignment = LinePercentAlignment.End - }; - - OutterStartPercentPosition = new PercentPosition() - { - IsInner = false, - Alignment = LinePercentAlignment.Start - }; - OutterCenterPercentPosition = new PercentPosition() - { - IsInner = false, - Alignment = LinePercentAlignment.Center - }; - OutterEndPercentPosition = new PercentPosition() - { - IsInner = false, - Alignment = LinePercentAlignment.End - }; - } + OutterStartPercentPosition = new PercentPosition + { + IsInner = false, + Alignment = LinePercentAlignment.Start + }; + OutterCenterPercentPosition = new PercentPosition + { + IsInner = false, + Alignment = LinePercentAlignment.Center + }; + OutterEndPercentPosition = new PercentPosition + { + IsInner = false, + Alignment = LinePercentAlignment.End + }; + } - public void AddProgressValue() - { - var value = ProgressValue; - value += 10; - ProgressValue = Math.Min(value, 100); - } + public LinearGradientBrush TwoStopsGradientStrokeColor { get; set; } - public void SubProgressValue() - { - var value = ProgressValue; - value -= 10; - ProgressValue = Math.Max(value, 0); - } + public LinearGradientBrush ThreeStopsGradientStrokeColor { get; set; } - public void ToggleEnabledStatus() - { - ToggleStatus = !ToggleStatus; - if (ToggleStatus) { - ToggleDisabledText = "Disable"; - } else { - ToggleDisabledText = "Enable"; - } - } + public List StepsChunkBrushes { get; set; } + + public PercentPosition InnerStartPercentPosition { get; set; } + public PercentPosition InnerCenterPercentPosition { get; set; } + public PercentPosition InnerEndPercentPosition { get; set; } + + public PercentPosition OutterStartPercentPosition { get; set; } + public PercentPosition OutterCenterPercentPosition { get; set; } + public PercentPosition OutterEndPercentPosition { get; set; } + + public double ProgressValue + { + get => GetValue(ProgressValueProperty); + set => SetValue(ProgressValueProperty, value); + } + + public string ToggleDisabledText + { + get => GetValue(ToggleDisabledTextProperty); + set => SetValue(ToggleDisabledTextProperty, value); + } + + public bool ToggleStatus + { + get => GetValue(ToggleStatusProperty); + set => SetValue(ToggleStatusProperty, value); + } + + public void AddProgressValue() + { + var value = ProgressValue; + value += 10; + ProgressValue = Math.Min(value, 100); + } + + public void SubProgressValue() + { + var value = ProgressValue; + value -= 10; + ProgressValue = Math.Max(value, 0); + } + + public void ToggleEnabledStatus() + { + ToggleStatus = !ToggleStatus; + if (ToggleStatus) + ToggleDisabledText = "Disable"; + else + ToggleDisabledText = "Enable"; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml index e993078..1eb0b32 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml @@ -140,7 +140,8 @@ - + Hangzhou diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs index cc773b1..65db973 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs @@ -4,30 +4,26 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class RadioButtonShowCase : UserControl { - protected List CheckRadios { get; set; } + public RadioButtonShowCase() + { + CheckRadios = new List + { + "ToggleDisabledRadioUnChecked", + "ToggleDisabledRadioChecked" + }; + InitializeComponent(); + } - public RadioButtonShowCase() - { - CheckRadios = new List() - { - "ToggleDisabledRadioUnChecked", - "ToggleDisabledRadioChecked" - }; - InitializeComponent(); - } - - public static void ToggleDisabledStatus(object arg) - { - var btn = (arg as Button)!; - var stackPanel = btn.Parent as StackPanel; - var radioBtn1 = stackPanel?.FindControl("ToggleDisabledRadioUnChecked"); - var radioBtn2 = stackPanel?.FindControl("ToggleDisabledRadioChecked"); - if (radioBtn1 != null) { - radioBtn1.IsEnabled = !radioBtn1.IsEnabled; - } + protected List CheckRadios { get; set; } - if (radioBtn2 != null) { - radioBtn2.IsEnabled = !radioBtn2.IsEnabled; - } - } + public static void ToggleDisabledStatus(object arg) + { + var btn = (arg as Button)!; + var stackPanel = btn.Parent as StackPanel; + var radioBtn1 = stackPanel?.FindControl("ToggleDisabledRadioUnChecked"); + var radioBtn2 = stackPanel?.FindControl("ToggleDisabledRadioChecked"); + if (radioBtn1 != null) radioBtn1.IsEnabled = !radioBtn1.IsEnabled; + + if (radioBtn2 != null) radioBtn2.IsEnabled = !radioBtn2.IsEnabled; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml index 346cef2..fdcb800 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -22,7 +21,8 @@ - + 123 @@ -51,7 +51,8 @@ - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs index dcff03f..6033ca1 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class SegmentedShowCase : UserControl { - public SegmentedShowCase() - { - InitializeComponent(); - } - + public SegmentedShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml index e9b7ca9..34c1380 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. @@ -24,7 +24,8 @@ - + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. @@ -65,7 +66,8 @@ - + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs index 8e16e19..ae05067 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class SeparatorShowCase : UserControl { - public SeparatorShowCase() - { - InitializeComponent(); - } - + public SeparatorShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml index b58a59c..4fd242a 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + - + - + included=true ?> SliderMarksProperty = - AvaloniaProperty.Register?>(nameof(SliderMarks)); - - public static readonly StyledProperty NormalDisabledProperty = - AvaloniaProperty.Register(nameof(NormalEnabled), true); - - public AvaloniaList? SliderMarks { - get => GetValue(SliderMarksProperty); - set => SetValue(SliderMarksProperty, value); - } - - public bool NormalEnabled { - get => GetValue(NormalDisabledProperty); - set => SetValue(NormalDisabledProperty, value); - } - - public SliderShowCase() - { - InitializeComponent(); - SliderMarks = new AvaloniaList(); - SliderMarks.Add(new SliderMark("0°C", 0)); - SliderMarks.Add(new SliderMark("26°C", 26)); - SliderMarks.Add(new SliderMark("37°C", 37)); - SliderMarks.Add(new SliderMark("100°C", 100) - { - LabelFontWeight = FontWeight.Bold, - LabelBrush = new SolidColorBrush(Colors.Red) - }); - DataContext = this; - } - + public static readonly StyledProperty?> SliderMarksProperty = + AvaloniaProperty.Register?>(nameof(SliderMarks)); + + public static readonly StyledProperty NormalDisabledProperty = + AvaloniaProperty.Register(nameof(NormalEnabled), true); + + public SliderShowCase() + { + InitializeComponent(); + SliderMarks = new AvaloniaList(); + SliderMarks.Add(new SliderMark("0°C", 0)); + SliderMarks.Add(new SliderMark("26°C", 26)); + SliderMarks.Add(new SliderMark("37°C", 37)); + SliderMarks.Add(new SliderMark("100°C", 100) + { + LabelFontWeight = FontWeight.Bold, + LabelBrush = new SolidColorBrush(Colors.Red) + }); + DataContext = this; + } + + public AvaloniaList? SliderMarks + { + get => GetValue(SliderMarksProperty); + set => SetValue(SliderMarksProperty, value); + } + + public bool NormalEnabled + { + get => GetValue(NormalDisabledProperty); + set => SetValue(NormalDisabledProperty, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml index 5af0aa4..88f5739 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -27,7 +26,8 @@ - + - + Tag 1 Link @@ -27,7 +27,8 @@ - + - + - + diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs index 1c32713..a0cec81 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class TagShowCase : UserControl { - public TagShowCase() - { - InitializeComponent(); - } - + public TagShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml index a8daf4d..9c90f12 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml @@ -5,14 +5,15 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> - + - + - + - + - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs index 7076620..dd76f87 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs @@ -4,9 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class TimelineShowCase : UserControl { - public TimelineShowCase() - { - InitializeComponent(); - } - + public TimelineShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml index a403f23..a3920f3 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs index 1358878..533f12a 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class TitleBarShowCase : UserControl { - public TitleBarShowCase() - { - InitializeComponent(); - } + public TitleBarShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml index 5edbf0d..141cb8a 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs index a404a30..4771d92 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs +++ b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs @@ -4,8 +4,8 @@ namespace AtomUI.Demo.Desktop.ShowCase; public partial class ToolBarShowCase : UserControl { - public ToolBarShowCase() - { - InitializeComponent(); - } + public ToolBarShowCase() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml index 0eba683..8e5e641 100644 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml +++ b/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml @@ -5,7 +5,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:showcase="clr-namespace:AtomUI.Demo.Desktop.ShowCase" mc:Ignorable="d"> @@ -256,7 +255,8 @@ - + - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml b/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml index b6cd640..96805b5 100644 --- a/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml +++ b/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml @@ -22,4 +22,4 @@ - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs b/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs index 96393e4..65750e4 100644 --- a/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs +++ b/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs @@ -1,28 +1,26 @@ using Avalonia.Markup.Xaml; -namespace AtomUI.Demo.Desktop.Utils +namespace AtomUI.Demo.Desktop.Utils; + +/// +/// Xaml markup to get the enum values. +/// +/// TODO 优化性能时可以考虑缓存类型和列表 +public class EnumExtension : MarkupExtension { - /// - /// Xaml markup to get the enum values. - /// - /// TODO 优化性能时可以考虑缓存类型和列表 - public class EnumExtension : MarkupExtension + public EnumExtension(Type type) { - [ConstructorArgument(nameof(Type))] - public Type Type { get; set; } - - public EnumExtension(Type type) - { - Type = type; - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - // Issue I7: - // Array can not perform well for Items of ListBox. - // Version : 11.0.0-preview4 - // By nlb at 2023.3.28. - return Enum.GetValues(Type).OfType().ToList(); - } + Type = type; } -} + + [ConstructorArgument(nameof(Type))] public Type Type { get; set; } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + // Issue I7: + // Array can not perform well for Items of ListBox. + // Version : 11.0.0-preview4 + // By nlb at 2023.3.28. + return Enum.GetValues(Type).OfType().ToList(); + } +} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs index c06b37f..2bf33e8 100644 --- a/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs +++ b/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs @@ -4,161 +4,169 @@ namespace AtomUI.Demo.Desktop.ViewModels; public class CheckBoxShowCaseModel : ObservableObject { - public bool? _controlledCheckBoxCheckedStatus; - public bool? ControlledCheckBoxCheckedStatus - { - get => _controlledCheckBoxCheckedStatus; - set => SetProperty(ref _controlledCheckBoxCheckedStatus, value); - } - - public bool _controlledCheckBoxEnabledStatus; - public bool ControlledCheckBoxEnabledStatus - { - get => _controlledCheckBoxEnabledStatus; - set => SetProperty(ref _controlledCheckBoxEnabledStatus, value); - } - - private string? _checkStatusBtnText; - public string? CheckStatusBtnText - { - get => _checkStatusBtnText; - set => SetProperty(ref _checkStatusBtnText, value); - } - - private string? _enableStatusBtnText; - public string? EnableStatusBtnText - { - get => _enableStatusBtnText; - set => SetProperty(ref _enableStatusBtnText, value); - } - - private string? _controlledCheckBoxText; - public string? ControlledCheckBoxText - { - get => _controlledCheckBoxText; - set => SetProperty(ref _controlledCheckBoxText, value); - } - - // CheckAll 例子 - private bool? _checkedAllStatus; - public bool? CheckedAllStatus - { - get => _checkedAllStatus; - set => SetProperty(ref _checkedAllStatus, value); - } - - private bool _appleCheckedStatus; - public bool AppleCheckedStatus - { - get => _appleCheckedStatus; - set => SetProperty(ref _appleCheckedStatus, value); - } - - private bool _pearCheckedStatus; - public bool PearCheckedStatus - { - get => _pearCheckedStatus; - set => SetProperty(ref _pearCheckedStatus, value); - } - - private bool _orangeCheckedStatus; - public bool OrangeCheckedStatus - { - get => _orangeCheckedStatus; - set => SetProperty(ref _orangeCheckedStatus, value); - } + private bool _appleCheckedStatus; - public CheckBoxShowCaseModel() - { - CheckStatusBtnText = "UnCheck"; - EnableStatusBtnText = "Disable"; - ControlledCheckBoxCheckedStatus = true; - ControlledCheckBoxEnabledStatus = true; - SetupControlledCheckBoxText(); + // CheckAll 例子 + private bool? _checkedAllStatus; - AppleCheckedStatus = false; - PearCheckedStatus = true; - OrangeCheckedStatus = true; - CheckedAllStatus = null; - } - - public void CheckStatusHandler(object arg) - { - ControlledCheckBoxCheckedStatus = !ControlledCheckBoxCheckedStatus; - SetupCheckBtnText(); - SetupControlledCheckBoxText(); - } + private string? _checkStatusBtnText; + public bool? _controlledCheckBoxCheckedStatus; - public void EnableStatusHandler(object arg) - { - ControlledCheckBoxEnabledStatus = !ControlledCheckBoxEnabledStatus; - SetupEnabledBtnText(); - SetupControlledCheckBoxText(); - } + public bool _controlledCheckBoxEnabledStatus; - public void CheckBoxHandler(object arg) - { - SetupCheckBtnText(); - SetupControlledCheckBoxText(); - } + private string? _controlledCheckBoxText; - private void SetupCheckBtnText() - { - if (ControlledCheckBoxCheckedStatus.HasValue) { - if (ControlledCheckBoxCheckedStatus.Value) { - CheckStatusBtnText = "UnCheck"; - } else { + private string? _enableStatusBtnText; + + private bool _orangeCheckedStatus; + + private bool _pearCheckedStatus; + + public CheckBoxShowCaseModel() + { + CheckStatusBtnText = "UnCheck"; + EnableStatusBtnText = "Disable"; + ControlledCheckBoxCheckedStatus = true; + ControlledCheckBoxEnabledStatus = true; + SetupControlledCheckBoxText(); + + AppleCheckedStatus = false; + PearCheckedStatus = true; + OrangeCheckedStatus = true; + CheckedAllStatus = null; + } + + public bool? ControlledCheckBoxCheckedStatus + { + get => _controlledCheckBoxCheckedStatus; + set => SetProperty(ref _controlledCheckBoxCheckedStatus, value); + } + + public bool ControlledCheckBoxEnabledStatus + { + get => _controlledCheckBoxEnabledStatus; + set => SetProperty(ref _controlledCheckBoxEnabledStatus, value); + } + + public string? CheckStatusBtnText + { + get => _checkStatusBtnText; + set => SetProperty(ref _checkStatusBtnText, value); + } + + public string? EnableStatusBtnText + { + get => _enableStatusBtnText; + set => SetProperty(ref _enableStatusBtnText, value); + } + + public string? ControlledCheckBoxText + { + get => _controlledCheckBoxText; + set => SetProperty(ref _controlledCheckBoxText, value); + } + + public bool? CheckedAllStatus + { + get => _checkedAllStatus; + set => SetProperty(ref _checkedAllStatus, value); + } + + public bool AppleCheckedStatus + { + get => _appleCheckedStatus; + set => SetProperty(ref _appleCheckedStatus, value); + } + + public bool PearCheckedStatus + { + get => _pearCheckedStatus; + set => SetProperty(ref _pearCheckedStatus, value); + } + + public bool OrangeCheckedStatus + { + get => _orangeCheckedStatus; + set => SetProperty(ref _orangeCheckedStatus, value); + } + + public void CheckStatusHandler(object arg) + { + ControlledCheckBoxCheckedStatus = !ControlledCheckBoxCheckedStatus; + SetupCheckBtnText(); + SetupControlledCheckBoxText(); + } + + public void EnableStatusHandler(object arg) + { + ControlledCheckBoxEnabledStatus = !ControlledCheckBoxEnabledStatus; + SetupEnabledBtnText(); + SetupControlledCheckBoxText(); + } + + public void CheckBoxHandler(object arg) + { + SetupCheckBtnText(); + SetupControlledCheckBoxText(); + } + + private void SetupCheckBtnText() + { + if (ControlledCheckBoxCheckedStatus.HasValue) + { + if (ControlledCheckBoxCheckedStatus.Value) + CheckStatusBtnText = "UnCheck"; + else + CheckStatusBtnText = "Check"; + } + else + { CheckStatusBtnText = "Check"; - } - } else { - CheckStatusBtnText = "Check"; - } - } + } + } - private void SetupEnabledBtnText() - { - if (ControlledCheckBoxEnabledStatus) { - EnableStatusBtnText = "Disable"; - } else { - EnableStatusBtnText = "Enable"; - } - } + private void SetupEnabledBtnText() + { + if (ControlledCheckBoxEnabledStatus) + EnableStatusBtnText = "Disable"; + else + EnableStatusBtnText = "Enable"; + } - private void SetupControlledCheckBoxText() - { - var checkedText = "UnChecked"; - if (ControlledCheckBoxCheckedStatus.HasValue && ControlledCheckBoxCheckedStatus.Value) { - checkedText = "Checked"; - } + private void SetupControlledCheckBoxText() + { + var checkedText = "UnChecked"; + if (ControlledCheckBoxCheckedStatus.HasValue && ControlledCheckBoxCheckedStatus.Value) checkedText = "Checked"; - var enabledText = "Disabled"; - if (ControlledCheckBoxEnabledStatus) { - enabledText = "Enabled"; - } - ControlledCheckBoxText = $"{checkedText}-{enabledText}"; - } - - public void CheckedAllStatusHandler() - { - if (!CheckedAllStatus.HasValue || !CheckedAllStatus.Value) { - AppleCheckedStatus = false; - PearCheckedStatus = false; - OrangeCheckedStatus = false; - } else { - AppleCheckedStatus = true; - PearCheckedStatus = true; - OrangeCheckedStatus = true; - } - } - - public void CheckedItemStatusHandler(object arg) - { - if (OrangeCheckedStatus && PearCheckedStatus && AppleCheckedStatus) { - CheckedAllStatus = true; - } else if (!OrangeCheckedStatus && !PearCheckedStatus && !AppleCheckedStatus) { - CheckedAllStatus = false; - } else { - CheckedAllStatus = null; - } - } + var enabledText = "Disabled"; + if (ControlledCheckBoxEnabledStatus) enabledText = "Enabled"; + + ControlledCheckBoxText = $"{checkedText}-{enabledText}"; + } + + public void CheckedAllStatusHandler() + { + if (!CheckedAllStatus.HasValue || !CheckedAllStatus.Value) + { + AppleCheckedStatus = false; + PearCheckedStatus = false; + OrangeCheckedStatus = false; + } + else + { + AppleCheckedStatus = true; + PearCheckedStatus = true; + OrangeCheckedStatus = true; + } + } + + public void CheckedItemStatusHandler(object arg) + { + if (OrangeCheckedStatus && PearCheckedStatus && AppleCheckedStatus) + CheckedAllStatus = true; + else if (!OrangeCheckedStatus && !PearCheckedStatus && !AppleCheckedStatus) + CheckedAllStatus = false; + else + CheckedAllStatus = null; + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs index b678d43..2817908 100644 --- a/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs +++ b/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs @@ -5,40 +5,51 @@ using CommunityToolkit.Mvvm.Input; namespace AtomUI.Demo.Desktop.ViewModels; -public class DataGridDemoViewModel: ObservableObject +public class DataGridDemoViewModel : ObservableObject { - public ObservableCollection GridData1 { get; set; } - - public DataGridCollectionView GridData2 { get; set; } - - public ObservableCollection GridData3 { get; set; } - - public RelayCommand AddCommand { get; set; } - public DataGridDemoViewModel() { GridData1 = new ObservableCollection(Song.Songs); GridData2 = new DataGridCollectionView(Song.Songs); GridData2.GroupDescriptions.Add(new DataGridPathGroupDescription("Album")); - GridData3 = new ObservableCollection(Song.Songs.Take(10).Select(a=>new SongViewModel() + GridData3 = new ObservableCollection(Song.Songs.Take(10).Select(a => new SongViewModel { - Title = a.Title, - Artist = a.Artist, - Album = a.Album, + Title = a.Title, + Artist = a.Artist, + Album = a.Album, CountOfComment = a.CountOfComment, - IsSelected = false + IsSelected = false })); AddCommand = new RelayCommand(Add); } + public ObservableCollection GridData1 { get; set; } + + public DataGridCollectionView GridData2 { get; set; } + + public ObservableCollection GridData3 { get; set; } + + public RelayCommand AddCommand { get; set; } + private void Add() { GridData3.Add(new SongViewModel()); } } + public class Song { + public Song(string title, string artist, int m, int s, string album, int countOfComment, int netEaseId) + { + Title = title; + Artist = artist; + Duration = new TimeSpan(0, m, s); + Album = album; + CountOfComment = countOfComment; + Url = $"https://music.163.com/song?id={netEaseId}"; + } + public string? Title { get; set; } public string? Artist { get; set; } public TimeSpan? Duration { get; set; } @@ -46,18 +57,7 @@ public class Song public int CountOfComment { get; set; } public string Url { get; set; } - public Song(string title, string artist, int m, int s, string album, int countOfComment, int netEaseId) - { - Title = title; - Artist = artist; - Duration = new TimeSpan(0, m, s); - Album = album; - CountOfComment = countOfComment; - Url = $"https://music.163.com/song?id={netEaseId}"; - - } - - public static List Songs { get; set; } = new List() + public static List Songs { get; set; } = new() { new("好肚有肚(feat.李玲玉)", "熊猫堂ProducePandas", 2, 50, "A.S.I.A", 730, 1487039339), new("荒诞秀", "熊猫堂ProducePandas", 3, 15, "A.S.I.A", 639, 1487037601), @@ -119,41 +119,46 @@ public class Song new("热带季风Remix", "熊猫堂ProducePandas", 3, 22, "W.O.R.L.D.", 23, 2063173319), new("加州梦境", "熊猫堂ProducePandas", 2, 56, "W.O.R.L.D.", 1662, 2063173324), new("渐近自由", "熊猫堂ProducePandas", 4, 19, "W.O.R.L.D.", 124, 2063173321), - new("世界所有的烂漫", "熊猫堂ProducePandas", 3, 30, "W.O.R.L.D.", 335, 2053388775), + new("世界所有的烂漫", "熊猫堂ProducePandas", 3, 30, "W.O.R.L.D.", 335, 2053388775) }; } -public class SongViewModel: ObservableObject + +public class SongViewModel : ObservableObject { - private string? _title; - private string? _artist; private string? _album; + private string? _artist; private int _countOfComment; private bool? _isSelected; + private string? _title; + public string? Title { get => _title; set => SetProperty(ref _title, value); } + public string? Artist { get => _artist; set => SetProperty(ref _artist, value); } + public string? Album { get => _album; set => SetProperty(ref _album, value); } + public int CountOfComment { get => _countOfComment; set => SetProperty(ref _countOfComment, value); } + public bool? IsSelected { get => _isSelected; set => SetProperty(ref _isSelected, value); } - } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs index 6763292..5fb27ee 100644 --- a/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs +++ b/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs @@ -9,226 +9,236 @@ namespace AtomUI.Demo.Desktop.ViewModels; public class PaletteMetaItem { - public string Title; - public string Desc; - public PresetPrimaryColor PresetPrimaryColor; + public string Desc; + public PresetPrimaryColor PresetPrimaryColor; + public string Title; - public PaletteMetaItem(string title, string desc, PresetPrimaryColor presetPrimaryColor) - { - Title = title; - Desc = desc; - PresetPrimaryColor = presetPrimaryColor; - } + public PaletteMetaItem(string title, string desc, PresetPrimaryColor presetPrimaryColor) + { + Title = title; + Desc = desc; + PresetPrimaryColor = presetPrimaryColor; + } } + public class PaletteDemoViewModel : ObservableObject { - private readonly PaletteMetaItem[] _presetPaletteInfos = - { - new PaletteMetaItem("Dust Red / 薄暮", "斗志、奔放", PresetPrimaryColor.Red), - new PaletteMetaItem("Volcano / 火山", "醒目、澎湃", PresetPrimaryColor.Volcano), - new PaletteMetaItem("Sunset Orange / 日暮", "温暖、欢快", PresetPrimaryColor.Orange), - new PaletteMetaItem("Calendula Gold / 金盏花", "活力、积极", PresetPrimaryColor.Gold), - new PaletteMetaItem("Sunrise Yellow / 日出", "出生、阳光", PresetPrimaryColor.Yellow), - new PaletteMetaItem("Lime / 青柠", "自然、生机", PresetPrimaryColor.Lime), - new PaletteMetaItem("Polar Green / 极光绿", "健康、创新", PresetPrimaryColor.Green), - new PaletteMetaItem("Cyan / 明青", "希望、坚强", PresetPrimaryColor.Cyan), - new PaletteMetaItem("Daybreak Blue / 拂晓蓝", "包容、科技、普惠", PresetPrimaryColor.Blue), - new PaletteMetaItem("Geek Blue / 极客蓝", "探索、钻研", PresetPrimaryColor.GeekBlue), - new PaletteMetaItem("Golden Purple / 酱紫", "优雅、浪漫", PresetPrimaryColor.Purple), - new PaletteMetaItem("Magenta / 法式洋红", "明快、感性", PresetPrimaryColor.Magenta), - }; + private readonly PaletteMetaItem[] _presetPaletteInfos = + { + new("Dust Red / 薄暮", "斗志、奔放", PresetPrimaryColor.Red), + new("Volcano / 火山", "醒目、澎湃", PresetPrimaryColor.Volcano), + new("Sunset Orange / 日暮", "温暖、欢快", PresetPrimaryColor.Orange), + new("Calendula Gold / 金盏花", "活力、积极", PresetPrimaryColor.Gold), + new("Sunrise Yellow / 日出", "出生、阳光", PresetPrimaryColor.Yellow), + new("Lime / 青柠", "自然、生机", PresetPrimaryColor.Lime), + new("Polar Green / 极光绿", "健康、创新", PresetPrimaryColor.Green), + new("Cyan / 明青", "希望、坚强", PresetPrimaryColor.Cyan), + new("Daybreak Blue / 拂晓蓝", "包容、科技、普惠", PresetPrimaryColor.Blue), + new("Geek Blue / 极客蓝", "探索、钻研", PresetPrimaryColor.GeekBlue), + new("Golden Purple / 酱紫", "优雅、浪漫", PresetPrimaryColor.Purple), + new("Magenta / 法式洋红", "明快、感性", PresetPrimaryColor.Magenta) + }; - private ColorItemViewModel _selectedColor = null!; + private ObservableCollection? _darkLists; - public ColorItemViewModel SelectedColor - { - get => _selectedColor; - set => SetProperty(ref _selectedColor, value); - } - - private ObservableCollection? _lightLists; + private ObservableCollection? _lightLists; - public ObservableCollection? LightLists - { - get => _lightLists; - set => SetProperty(ref _lightLists, value); - } + private ColorItemViewModel _selectedColor = null!; - private ObservableCollection? _darkLists; + public PaletteDemoViewModel() + { + WeakReferenceMessenger.Default.Register(this, OnClickColorItem); + } - public ObservableCollection? DarkLists - { - get => _darkLists; - set => SetProperty(ref _darkLists, value); - } + public ColorItemViewModel SelectedColor + { + get => _selectedColor; + set => SetProperty(ref _selectedColor, value); + } - public PaletteDemoViewModel() - { - WeakReferenceMessenger.Default.Register(this, OnClickColorItem); - } + public ObservableCollection? LightLists + { + get => _lightLists; + set => SetProperty(ref _lightLists, value); + } - public void InitializeResources() - { - InitializePalette(); - } + public ObservableCollection? DarkLists + { + get => _darkLists; + set => SetProperty(ref _darkLists, value); + } - private void InitializePalette() - { - LightLists = new ObservableCollection(); - var cycleColorList = new ObservableCollection(); - int cycleCount = 0; - for (int i = 0; i < _presetPaletteInfos.Length; ++i) { - var metaInfo = _presetPaletteInfos[i]; - ColorListViewModel colorListViewModel = new ColorListViewModel(); - colorListViewModel.Title = metaInfo.Title; - colorListViewModel.Desc = metaInfo.Desc; - var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor); - var colorItemViewModels = new ObservableCollection(); - var presetColorName = metaInfo.PresetPrimaryColor.Name(); - - for (int j = 0; j < paletteInfo.ColorSequence.Count; j++) { - var color = paletteInfo.ColorSequence[j]; - var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", - new SolidColorBrush(color), - true, - j); - colorItemViewModels.Add(colorItem); - } + public void InitializeResources() + { + InitializePalette(); + } - colorListViewModel.Colors = colorItemViewModels; - cycleColorList.Add(colorListViewModel); - ++cycleCount; - - if (cycleCount == 3) { - var colorGroupModel = new ColorGroupViewModel(); - colorGroupModel.ColorList = cycleColorList; - LightLists.Add(colorGroupModel); - cycleColorList = new ObservableCollection(); - cycleCount = 0; - } - } - - DarkLists = new ObservableCollection(); - - for (int i = 0; i < _presetPaletteInfos.Length; ++i) { - var metaInfo = _presetPaletteInfos[i]; - ColorListViewModel colorListViewModel = new ColorListViewModel(); - colorListViewModel.Title = metaInfo.Title; - colorListViewModel.Desc = metaInfo.Desc; - var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor, true); - var colorItemViewModels = new ObservableCollection(); - var presetColorName = metaInfo.PresetPrimaryColor.Name(); - - for (int j = 0; j < paletteInfo.ColorSequence.Count; j++) { - var color = paletteInfo.ColorSequence[j]; - var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", - new SolidColorBrush(color), - false, - j); - colorItemViewModels.Add(colorItem); - } + private void InitializePalette() + { + LightLists = new ObservableCollection(); + var cycleColorList = new ObservableCollection(); + var cycleCount = 0; + for (var i = 0; i < _presetPaletteInfos.Length; ++i) + { + var metaInfo = _presetPaletteInfos[i]; + var colorListViewModel = new ColorListViewModel(); + colorListViewModel.Title = metaInfo.Title; + colorListViewModel.Desc = metaInfo.Desc; + var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor); + var colorItemViewModels = new ObservableCollection(); + var presetColorName = metaInfo.PresetPrimaryColor.Name(); - colorListViewModel.Colors = colorItemViewModels; - cycleColorList.Add(colorListViewModel); - ++cycleCount; - - if (cycleCount == 3) { - var colorGroupModel = new ColorGroupViewModel(); - colorGroupModel.ColorList = cycleColorList; - DarkLists.Add(colorGroupModel); - cycleColorList = new ObservableCollection(); - cycleCount = 0; - } - } - } + for (var j = 0; j < paletteInfo.ColorSequence.Count; j++) + { + var color = paletteInfo.ColorSequence[j]; + var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", + new SolidColorBrush(color), + true, + j); + colorItemViewModels.Add(colorItem); + } - private void OnClickColorItem(PaletteDemoViewModel vm, ColorItemViewModel item) - { - SelectedColor = item; - } + colorListViewModel.Colors = colorItemViewModels; + cycleColorList.Add(colorListViewModel); + ++cycleCount; + + if (cycleCount == 3) + { + var colorGroupModel = new ColorGroupViewModel(); + colorGroupModel.ColorList = cycleColorList; + LightLists.Add(colorGroupModel); + cycleColorList = new ObservableCollection(); + cycleCount = 0; + } + } + + DarkLists = new ObservableCollection(); + + for (var i = 0; i < _presetPaletteInfos.Length; ++i) + { + var metaInfo = _presetPaletteInfos[i]; + var colorListViewModel = new ColorListViewModel(); + colorListViewModel.Title = metaInfo.Title; + colorListViewModel.Desc = metaInfo.Desc; + var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor, true); + var colorItemViewModels = new ObservableCollection(); + var presetColorName = metaInfo.PresetPrimaryColor.Name(); + + for (var j = 0; j < paletteInfo.ColorSequence.Count; j++) + { + var color = paletteInfo.ColorSequence[j]; + var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", + new SolidColorBrush(color), + false, + j); + colorItemViewModels.Add(colorItem); + } + + colorListViewModel.Colors = colorItemViewModels; + cycleColorList.Add(colorListViewModel); + ++cycleCount; + + if (cycleCount == 3) + { + var colorGroupModel = new ColorGroupViewModel(); + colorGroupModel.ColorList = cycleColorList; + DarkLists.Add(colorGroupModel); + cycleColorList = new ObservableCollection(); + cycleCount = 0; + } + } + } + + private void OnClickColorItem(PaletteDemoViewModel vm, ColorItemViewModel item) + { + SelectedColor = item; + } } + public class ColorGroupViewModel : ObservableObject { - private ObservableCollection? _colorList; - - public ObservableCollection? ColorList - { - get => _colorList; - set => SetProperty(ref _colorList, value); - } + private ObservableCollection? _colorList; + + public ObservableCollection? ColorList + { + get => _colorList; + set => SetProperty(ref _colorList, value); + } } + public class ColorListViewModel : ObservableObject { - private ObservableCollection? _colors; + private ObservableCollection? _colors; - public ObservableCollection? Colors - { - get => _colors; - set => SetProperty(ref _colors, value); - } + private string? _desc; - private string? _title; + private string? _title; - public string? Title - { - get => _title; - set => SetProperty(ref _title, value); - } + public ObservableCollection? Colors + { + get => _colors; + set => SetProperty(ref _colors, value); + } - private string? _desc; - public string? Desc - { - get => _desc; - set => SetProperty(ref _desc, value); - } + public string? Title + { + get => _title; + set => SetProperty(ref _title, value); + } + + public string? Desc + { + get => _desc; + set => SetProperty(ref _desc, value); + } } + public class ColorItemViewModel : ObservableObject { - private IBrush _brush = null!; + private IBrush _brush = null!; - public IBrush Brush - { - get => _brush; - set => SetProperty(ref _brush, value); - } + private string _colorDisplayName = null!; - private IBrush _textBrush = null!; + private string _hex = null!; - public IBrush TextBrush - { - get => _textBrush; - set => SetProperty(ref _textBrush, value); - } + private IBrush _textBrush = null!; - private string _colorDisplayName = null!; + public ColorItemViewModel(string colorDisplayName, ISolidColorBrush brush, bool light, int index) + { + ColorDisplayName = colorDisplayName; + Brush = brush; + Hex = brush.ToString()!.ToUpperInvariant(); + if ((light && index < 5) || (!light && index >= 5)) + TextBrush = Brushes.Black; + else + TextBrush = Brushes.White; + } - public string ColorDisplayName - { - get => _colorDisplayName; - set => SetProperty(ref _colorDisplayName, value); - } + public IBrush Brush + { + get => _brush; + set => SetProperty(ref _brush, value); + } - private string _hex = null!; + public IBrush TextBrush + { + get => _textBrush; + set => SetProperty(ref _textBrush, value); + } - public string Hex - { - get => _hex; - set => SetProperty(ref _hex, value); - } + public string ColorDisplayName + { + get => _colorDisplayName; + set => SetProperty(ref _colorDisplayName, value); + } - public ColorItemViewModel(string colorDisplayName, ISolidColorBrush brush, bool light, int index) - { - ColorDisplayName = colorDisplayName; - Brush = brush; - Hex = brush.ToString()!.ToUpperInvariant(); - if ((light && index < 5) || (!light && index >= 5)) { - TextBrush = Brushes.Black; - } else { - TextBrush = Brushes.White; - } - } + public string Hex + { + get => _hex; + set => SetProperty(ref _hex, value); + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs index 38b7be6..b3d6831 100644 --- a/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs +++ b/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs @@ -7,60 +7,58 @@ namespace AtomUI.Demo.Desktop.ViewModels; public class IconInfoItemModel : ObservableObject { - private string _iconName = null!; + private string _iconKind = null!; + private string _iconName = null!; - public string IconName - { - get => _iconName; - set => SetProperty(ref _iconName, value); - } - - private string _iconKind = null!; + public IconInfoItemModel(string iconName, string iconKind) + { + IconName = iconName; + IconKind = iconKind; + } - public string IconKind - { - get => _iconKind; - set => SetProperty(ref _iconKind, value); - } - - public IconInfoItemModel(string iconName, string iconKind) - { - IconName = iconName; - IconKind = iconKind; - } + public string IconName + { + get => _iconName; + set => SetProperty(ref _iconName, value); + } + + public string IconKind + { + get => _iconKind; + set => SetProperty(ref _iconKind, value); + } } + public class IconGalleryModel : ObservableObject { - private IconThemeType? _iconThemeType; - - private ObservableCollection? _iconInfos; - public ObservableCollection? IconInfos - { - get => _iconInfos; - set => SetProperty(ref _iconInfos, value); - } - - public IconGalleryModel(IconThemeType? iconThemeType = null) - { - _iconThemeType = iconThemeType; - if (_iconThemeType.HasValue) { - LoadThemeIcons(_iconThemeType.Value); - } - } + private readonly IconThemeType? _iconThemeType; - public void LoadThemeIcons(IconThemeType iconThemeType) - { - var iconPackage = IconManager.Current.GetIconProvider(); - if (iconPackage is null) { - return; - } + private ObservableCollection? _iconInfos; - IconInfos = new ObservableCollection(); - var iconInfos = iconPackage.GetIconInfos(iconThemeType); - foreach (var iconInfo in iconInfos) { - var iconInfoModel = new IconInfoItemModel(iconInfo.Name, iconInfo.Name); - IconInfos.Add(iconInfoModel); - } - } + public IconGalleryModel(IconThemeType? iconThemeType = null) + { + _iconThemeType = iconThemeType; + if (_iconThemeType.HasValue) LoadThemeIcons(_iconThemeType.Value); + } + + public ObservableCollection? IconInfos + { + get => _iconInfos; + set => SetProperty(ref _iconInfos, value); + } + + public void LoadThemeIcons(IconThemeType iconThemeType) + { + var iconPackage = IconManager.Current.GetIconProvider(); + if (iconPackage is null) return; + + IconInfos = new ObservableCollection(); + var iconInfos = iconPackage.GetIconInfos(iconThemeType); + foreach (var iconInfo in iconInfos) + { + var iconInfoModel = new IconInfoItemModel(iconInfo.Name, iconInfo.Name); + IconInfos.Add(iconInfoModel); + } + } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs index a314341..6fb751a 100644 --- a/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs +++ b/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs @@ -3,12 +3,12 @@ using CommunityToolkit.Mvvm.ComponentModel; namespace AtomUI.Demo.Desktop.ViewModels; -public class TabControlDemoViewModel: ObservableObject +public class TabControlDemoViewModel : ObservableObject { - public ObservableCollection Items { get; set; } - public TabControlDemoViewModel() { Items = new ObservableCollection(Enumerable.Range(1, 200).Select(a => "Tab " + a)); } + + public ObservableCollection Items { get; set; } } \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml b/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml index d8cda35..9cfd635 100644 --- a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml +++ b/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml @@ -12,4 +12,4 @@ Icon="/Assets/avalonia-logo.ico" mc:Ignorable="d"> - + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/app.manifest b/samples/AtomUI.Demo.Desktop/app.manifest index a2dde19..207806b 100644 --- a/samples/AtomUI.Demo.Desktop/app.manifest +++ b/samples/AtomUI.Demo.Desktop/app.manifest @@ -1,18 +1,18 @@  - - + + - - - + + + - - - - + + + + diff --git a/src/AtomUI.Base/AtomUI.Base.csproj b/src/AtomUI.Base/AtomUI.Base.csproj index 3c71fc7..479b625 100644 --- a/src/AtomUI.Base/AtomUI.Base.csproj +++ b/src/AtomUI.Base/AtomUI.Base.csproj @@ -1,20 +1,20 @@  - + AtomUI True - + - + - - + + diff --git a/src/AtomUI.Base/Common.cs b/src/AtomUI.Base/Common.cs index ad3d7ff..62a98dc 100644 --- a/src/AtomUI.Base/Common.cs +++ b/src/AtomUI.Base/Common.cs @@ -5,58 +5,64 @@ namespace AtomUI; public enum TextDecorationLine { - None, - Underline, - Overline, - LineThrough + None, + Underline, + Overline, + LineThrough } + public enum LineStyle { - Solid, - Double, - Dotted, - Dashed, - Wavy, + Solid, + Double, + Dotted, + Dashed, + Wavy } + public enum Direction { - Left, - Top, - Right, - Bottom + Left, + Top, + Right, + Bottom } + public enum Corner { - None = 0x00, - TopLeft = 0x01, - TopRight = 0x02, - BottomLeft = 0x04, - BottomRight = 0x08, - All = TopLeft | TopRight | BottomLeft | BottomRight + None = 0x00, + TopLeft = 0x01, + TopRight = 0x02, + BottomLeft = 0x04, + BottomRight = 0x08, + All = TopLeft | TopRight | BottomLeft | BottomRight } + public enum SizeType { - Large, - Middle, - Small + Large, + Middle, + Small } + // 文本修饰信息定义 // 类似 CSS text-decoration public class TextDecorationInfo { - public Color Color { get; set; } - public TextDecorationLine LineType { get; set; } = TextDecorationLine.None; - public LineStyle LineStyle { get; set; } = LineStyle.Solid; - public int Thickness { get; set; } = 1; + public Color Color { get; set; } + public TextDecorationLine LineType { get; set; } = TextDecorationLine.None; + public LineStyle LineStyle { get; set; } = LineStyle.Solid; + public int Thickness { get; set; } = 1; } + public enum ColorNameFormat { - HexRgb, - HexArgb + HexRgb, + HexArgb } \ No newline at end of file diff --git a/src/AtomUI.Base/Data/BindUtils.cs b/src/AtomUI.Base/Data/BindUtils.cs index 5e0dcd2..68ccbe1 100644 --- a/src/AtomUI.Base/Data/BindUtils.cs +++ b/src/AtomUI.Base/Data/BindUtils.cs @@ -6,47 +6,42 @@ namespace AtomUI.Data; public static class BindUtils { public static IDisposable RelayBind(AvaloniaObject source, AvaloniaProperty sourceProperty, AvaloniaObject target, - AvaloniaProperty? targetProperty = null, - BindingMode mode = BindingMode.Default) - { - targetProperty ??= sourceProperty; - var registry = AvaloniaPropertyRegistry.Instance; - if (!sourceProperty.IsAttached) { - if (!registry.IsRegistered(source.GetType(), sourceProperty)) { + AvaloniaProperty? targetProperty = null, + BindingMode mode = BindingMode.Default) + { + targetProperty ??= sourceProperty; + var registry = AvaloniaPropertyRegistry.Instance; + if (!sourceProperty.IsAttached) + if (!registry.IsRegistered(source.GetType(), sourceProperty)) + throw new ArgumentException($"Relay source property is not registered for: {source.GetType().Name}."); + + if (!targetProperty.IsAttached) + if (!registry.IsRegistered(target.GetType(), targetProperty)) + throw new ArgumentException($"Relay target property is not registered for: {target.GetType().Name}."); + + var descriptor = new IndexerDescriptor + { + Source = source, + Property = sourceProperty, + Priority = BindingPriority.Inherited, + Mode = mode + }; + return target.Bind(targetProperty, descriptor); + } + + public static IDisposable RelayBind(AvaloniaObject source, + AvaloniaProperty sourceProperty, + AvaloniaObject target, AvaloniaProperty targetProperty, + Func converter, + BindingPriority priority = BindingPriority.Template) + { + var registry = AvaloniaPropertyRegistry.Instance; + if (!registry.IsRegistered(source.GetType(), sourceProperty)) throw new ArgumentException($"Relay source property is not registered for: {source.GetType().Name}."); - } - } - if (!targetProperty.IsAttached) { - if (!registry.IsRegistered(target.GetType(), targetProperty)) { + if (!registry.IsRegistered(target.GetType(), targetProperty)) throw new ArgumentException($"Relay target property is not registered for: {target.GetType().Name}."); - } - } - - var descriptor = new IndexerDescriptor - { - Source = source, - Property = sourceProperty, - Priority = BindingPriority.Inherited, - Mode = mode - }; - return target.Bind(targetProperty, descriptor); - } - public static IDisposable RelayBind(AvaloniaObject source, AvaloniaProperty sourceProperty, - AvaloniaObject target, AvaloniaProperty targetProperty, - Func converter, - BindingPriority priority = BindingPriority.Template) - { - var registry = AvaloniaPropertyRegistry.Instance; - if (!registry.IsRegistered(source.GetType(), sourceProperty)) { - throw new ArgumentException($"Relay source property is not registered for: {source.GetType().Name}."); - } - - if (!registry.IsRegistered(target.GetType(), targetProperty)) { - throw new ArgumentException($"Relay target property is not registered for: {target.GetType().Name}."); - } - - return target.Bind(targetProperty, source.GetObservable(sourceProperty, converter), priority); - } + return target.Bind(targetProperty, source.GetObservable(sourceProperty, converter), priority); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Input/IsAllowedXYNavigationMode.cs b/src/AtomUI.Base/Input/IsAllowedXYNavigationMode.cs index 234ad68..83fa4e4 100644 --- a/src/AtomUI.Base/Input/IsAllowedXYNavigationMode.cs +++ b/src/AtomUI.Base/Input/IsAllowedXYNavigationMode.cs @@ -4,27 +4,28 @@ namespace AtomUI.Input; internal static class XYFocusHelpers { - internal static bool IsAllowedXYNavigationMode( - this InputElement visual, - KeyDeviceType? keyDeviceType) - { - return XYFocusHelpers.IsAllowedXYNavigationMode(XYFocus.GetNavigationModes(visual), keyDeviceType); - } + internal static bool IsAllowedXYNavigationMode( + this InputElement visual, + KeyDeviceType? keyDeviceType) + { + return IsAllowedXYNavigationMode(XYFocus.GetNavigationModes(visual), keyDeviceType); + } - private static bool IsAllowedXYNavigationMode( - XYFocusNavigationModes modes, - KeyDeviceType? keyDeviceType) - { - if (!keyDeviceType.HasValue) return true; - switch (keyDeviceType.GetValueOrDefault()) { - case KeyDeviceType.Keyboard: - return modes.HasFlag((Enum)XYFocusNavigationModes.Keyboard); - case KeyDeviceType.Gamepad: - return modes.HasFlag((Enum)XYFocusNavigationModes.Gamepad); - case KeyDeviceType.Remote: - return modes.HasFlag((Enum)XYFocusNavigationModes.Remote); - default: - throw new ArgumentOutOfRangeException(nameof(keyDeviceType), (object)keyDeviceType, (string?)null); - } - } + private static bool IsAllowedXYNavigationMode( + XYFocusNavigationModes modes, + KeyDeviceType? keyDeviceType) + { + if (!keyDeviceType.HasValue) return true; + switch (keyDeviceType.GetValueOrDefault()) + { + case KeyDeviceType.Keyboard: + return modes.HasFlag(XYFocusNavigationModes.Keyboard); + case KeyDeviceType.Gamepad: + return modes.HasFlag(XYFocusNavigationModes.Gamepad); + case KeyDeviceType.Remote: + return modes.HasFlag(XYFocusNavigationModes.Remote); + default: + throw new ArgumentOutOfRangeException(nameof(keyDeviceType), keyDeviceType, null); + } + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Input/TransformTrackingHelper.cs b/src/AtomUI.Base/Input/TransformTrackingHelper.cs index b0b3334..6340139 100644 --- a/src/AtomUI.Base/Input/TransformTrackingHelper.cs +++ b/src/AtomUI.Base/Input/TransformTrackingHelper.cs @@ -6,125 +6,123 @@ using Avalonia.VisualTree; namespace AtomUI.Input; -class TransformTrackingHelper : IDisposable +internal class TransformTrackingHelper : IDisposable { - private Visual? _visual; - private bool _queuedForUpdate; - private readonly EventHandler _propertyChangedHandler; - private readonly List _propertyChangedSubscriptions = new List(); - private static readonly FieldInfo AfterRenderFieldInfo; + private static readonly FieldInfo AfterRenderFieldInfo; + private readonly EventHandler _propertyChangedHandler; + private readonly List _propertyChangedSubscriptions = new(); + private bool _queuedForUpdate; + private Visual? _visual; - static TransformTrackingHelper() - { - AfterRenderFieldInfo = - typeof(DispatcherPriority).GetFieldInfoOrThrow("AfterRender", BindingFlags.Static | BindingFlags.NonPublic)!; - } + static TransformTrackingHelper() + { + AfterRenderFieldInfo = + typeof(DispatcherPriority).GetFieldInfoOrThrow("AfterRender", + BindingFlags.Static | BindingFlags.NonPublic)!; + } - public TransformTrackingHelper() - { - _propertyChangedHandler = PropertyChangedHandler; - } + public TransformTrackingHelper() + { + _propertyChangedHandler = PropertyChangedHandler; + } - public void SetVisual(Visual? visual) - { - Dispose(); - _visual = visual; - if (visual != null) { - visual.AttachedToVisualTree += OnAttachedToVisualTree; - visual.DetachedFromVisualTree -= OnDetachedFromVisualTree; - if (visual.GetVisualRoot() is not null) { - SubscribeToParents(); - } + public Matrix? Matrix { get; private set; } - UpdateMatrix(); - } - } + public void Dispose() + { + if (_visual == null) return; - public Matrix? Matrix { get; private set; } - public event Action? MatrixChanged; + UnsubscribeFromParents(); + _visual.AttachedToVisualTree -= OnAttachedToVisualTree; + _visual.DetachedFromVisualTree -= OnDetachedFromVisualTree; + _visual = null; + } - public void Dispose() - { - if (_visual == null) { - return; - } + public void SetVisual(Visual? visual) + { + Dispose(); + _visual = visual; + if (visual != null) + { + visual.AttachedToVisualTree += OnAttachedToVisualTree; + visual.DetachedFromVisualTree -= OnDetachedFromVisualTree; + if (visual.GetVisualRoot() is not null) SubscribeToParents(); - UnsubscribeFromParents(); - _visual.AttachedToVisualTree -= OnAttachedToVisualTree; - _visual.DetachedFromVisualTree -= OnDetachedFromVisualTree; - _visual = null; - } + UpdateMatrix(); + } + } - private void SubscribeToParents() - { - var visual = _visual; - // ReSharper disable once ConditionIsAlwaysTrueOrFalse - // false positive - while (visual != null) { - if (visual is Visual v) { - v.PropertyChanged += _propertyChangedHandler; - _propertyChangedSubscriptions.Add(v); - } + public event Action? MatrixChanged; - visual = visual.GetVisualParent(); - } - } + private void SubscribeToParents() + { + var visual = _visual; - private void UnsubscribeFromParents() - { - foreach (var v in _propertyChangedSubscriptions) v.PropertyChanged -= _propertyChangedHandler; - _propertyChangedSubscriptions.Clear(); - } + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + // false positive + while (visual != null) + { + if (visual is Visual v) + { + v.PropertyChanged += _propertyChangedHandler; + _propertyChangedSubscriptions.Add(v); + } - void UpdateMatrix() - { - Matrix? matrix = null; - if (_visual != null && _visual.GetVisualRoot() != null) { - matrix = _visual.TransformToVisual((Visual)_visual.GetVisualRoot()!); - } + visual = visual.GetVisualParent(); + } + } - if (Matrix != matrix) { - Matrix = matrix; - MatrixChanged?.Invoke(); - } - } + private void UnsubscribeFromParents() + { + foreach (var v in _propertyChangedSubscriptions) v.PropertyChanged -= _propertyChangedHandler; + _propertyChangedSubscriptions.Clear(); + } - private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs visualTreeAttachmentEventArgs) - { - SubscribeToParents(); - UpdateMatrix(); - } + private void UpdateMatrix() + { + Matrix? matrix = null; + if (_visual != null && _visual.GetVisualRoot() != null) + matrix = _visual.TransformToVisual((Visual)_visual.GetVisualRoot()!); - private void EnqueueForUpdate() - { - if (_queuedForUpdate) { - return; - } + if (Matrix != matrix) + { + Matrix = matrix; + MatrixChanged?.Invoke(); + } + } - _queuedForUpdate = true; - var priority = (DispatcherPriority)AfterRenderFieldInfo.GetValue(null)!; - Dispatcher.UIThread.Post(UpdateMatrix, priority); - } + private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs visualTreeAttachmentEventArgs) + { + SubscribeToParents(); + UpdateMatrix(); + } - private void PropertyChangedHandler(object? sender, AvaloniaPropertyChangedEventArgs e) - { - e.TryGetProperty("IsEffectiveValueChange", out var isEffectiveValueChange); - if (isEffectiveValueChange && e.Property == Visual.BoundsProperty) { - EnqueueForUpdate(); - } - } + private void EnqueueForUpdate() + { + if (_queuedForUpdate) return; - private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs visualTreeAttachmentEventArgs) - { - UnsubscribeFromParents(); - UpdateMatrix(); - } + _queuedForUpdate = true; + var priority = (DispatcherPriority)AfterRenderFieldInfo.GetValue(null)!; + Dispatcher.UIThread.Post(UpdateMatrix, priority); + } - public static IDisposable Track(Visual visual, Action cb) - { - var rv = new TransformTrackingHelper(); - rv.MatrixChanged += () => cb(visual, rv.Matrix); - rv.SetVisual(visual); - return rv; - } + private void PropertyChangedHandler(object? sender, AvaloniaPropertyChangedEventArgs e) + { + e.TryGetProperty("IsEffectiveValueChange", out var isEffectiveValueChange); + if (isEffectiveValueChange && e.Property == Visual.BoundsProperty) EnqueueForUpdate(); + } + + private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs visualTreeAttachmentEventArgs) + { + UnsubscribeFromParents(); + UpdateMatrix(); + } + + public static IDisposable Track(Visual visual, Action cb) + { + var rv = new TransformTrackingHelper(); + rv.MatrixChanged += () => cb(visual, rv.Matrix); + rv.SetVisual(visual); + return rv; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/BoxShadowExtensions.cs b/src/AtomUI.Base/Media/BoxShadowExtensions.cs index e4f7566..313d722 100644 --- a/src/AtomUI.Base/Media/BoxShadowExtensions.cs +++ b/src/AtomUI.Base/Media/BoxShadowExtensions.cs @@ -5,35 +5,36 @@ namespace AtomUI.Media; public static class BoxShadowExtensions { - public static Thickness Thickness(this BoxShadow boxShadow) - { - var offsetX = boxShadow.OffsetX; - var offsetY = boxShadow.OffsetY; - var blurRadius = boxShadow.Blur; - var spreadRadius = boxShadow.Spread; - - var value = Math.Max(blurRadius + spreadRadius, 0.0); // 可以正负抵消 - var left = Math.Max(value - offsetX, 0.0); - var right = Math.Max(value + offsetX, 0.0); - var top = Math.Max(value - offsetY, 0.0); - var bottom = Math.Max(value + offsetY, 0.0); - return new Thickness(left, top, right, bottom); - } + public static Thickness Thickness(this BoxShadow boxShadow) + { + var offsetX = boxShadow.OffsetX; + var offsetY = boxShadow.OffsetY; + var blurRadius = boxShadow.Blur; + var spreadRadius = boxShadow.Spread; - public static Thickness Thickness(this BoxShadows boxShadows) - { - double leftThickness = 0; - double topThickness = 0; - double rightThickness = 0; - double bottomThickness = 0; - foreach (var shadow in boxShadows) { - var thickness = shadow.Thickness(); - leftThickness = Math.Max(leftThickness, thickness.Left); - topThickness = Math.Max(topThickness, thickness.Top); - rightThickness = Math.Max(rightThickness, thickness.Right); - bottomThickness = Math.Max(bottomThickness, thickness.Bottom); - } - - return new Thickness(leftThickness, topThickness, rightThickness, bottomThickness); - } + var value = Math.Max(blurRadius + spreadRadius, 0.0); // 可以正负抵消 + var left = Math.Max(value - offsetX, 0.0); + var right = Math.Max(value + offsetX, 0.0); + var top = Math.Max(value - offsetY, 0.0); + var bottom = Math.Max(value + offsetY, 0.0); + return new Thickness(left, top, right, bottom); + } + + public static Thickness Thickness(this BoxShadows boxShadows) + { + double leftThickness = 0; + double topThickness = 0; + double rightThickness = 0; + double bottomThickness = 0; + foreach (var shadow in boxShadows) + { + var thickness = shadow.Thickness(); + leftThickness = Math.Max(leftThickness, thickness.Left); + topThickness = Math.Max(topThickness, thickness.Top); + rightThickness = Math.Max(rightThickness, thickness.Right); + bottomThickness = Math.Max(bottomThickness, thickness.Bottom); + } + + return new Thickness(leftThickness, topThickness, rightThickness, bottomThickness); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/ColorExtensions.cs b/src/AtomUI.Base/Media/ColorExtensions.cs index 34570a3..03dc8e8 100644 --- a/src/AtomUI.Base/Media/ColorExtensions.cs +++ b/src/AtomUI.Base/Media/ColorExtensions.cs @@ -6,148 +6,150 @@ namespace AtomUI.Media; public static class ColorExtensions { - public static double GetRedF(this Color color) - { - return color.R / 255d; - } + public static double GetRedF(this Color color) + { + return color.R / 255d; + } - public static double GetGreenF(this Color color) - { - return color.G / 255d; - } - - public static double GetBlueF(this Color color) - { - return color.B / 255d; - } + public static double GetGreenF(this Color color) + { + return color.G / 255d; + } - public static double GetAlphaF(this Color color) - { - return color.A / 255d; - } + public static double GetBlueF(this Color color) + { + return color.B / 255d; + } - public static string HexName(this Color color, ColorNameFormat format = ColorNameFormat.HexRgb) - { - uint rgb = color.ToUInt32(); - string formatStr = "x8"; - if (format == ColorNameFormat.HexRgb) { - formatStr = "x6"; - rgb &= 0xFFFFFF; - } - return $"#{rgb.ToString(formatStr, CultureInfo.InvariantCulture)}"; - } - - public static Color Desaturate(this Color color, int amount = 10) - { - amount = Math.Clamp(amount, 0, 100); - HslColor hslColor = color.ToHsl(); - double s = hslColor.S; - s -= amount / 100d; - s = Math.Clamp(s, 0d, 1d); - return HslColor.FromHsl(hslColor.H, s, hslColor.L).ToRgb(); - } - - public static Color Saturate(this Color color, int amount = 10) - { - amount = Math.Clamp(amount, 0, 100); - HslColor hslColor = color.ToHsl(); - double s = hslColor.S; - s += amount / 100d; - s = Math.Clamp(s, 0d, 1d); - return HslColor.FromHsl(hslColor.H, s, hslColor.L).ToRgb(); - } - - public static Color Greyscale(this Color color) - { - return color.Desaturate(100); - } - - public static Color Lighten(this Color color, int amount = 10) - { - amount = Math.Clamp(amount, 0, 100); - HslColor hslColor = color.ToHsl(); - double l = hslColor.L; - l += amount / 100d; - l = Math.Clamp(l, 0d, 1d); - Console.WriteLine(hslColor.H); - return HslColor.FromHsl(hslColor.H, hslColor.S, l).ToRgb(); - } - - public static Color Brighten(this Color color, int amount = 10) - { - amount = Math.Clamp(amount, 0, 100); - int r = color.R; - int g = color.G; - int b = color.B; - int delta = (int)Math.Round(255d * -(amount / 100d)); - r = Math.Max(0, Math.Min(255, r - delta)); - g = Math.Max(0, Math.Min(255, g - delta)); - b = Math.Max(0, Math.Min(255, b - delta)); - return Color.FromRgb((byte)r, (byte)g, (byte)b); - } - - public static Color Darken(this Color color, int amount = 10) - { - amount = Math.Clamp(amount, 0, 100); - HslColor hslColor = color.ToHsl(); - double l = hslColor.L; - l -= amount / 100d; - l = Math.Clamp(l, 0d, 1d); - return HslColor.FromHsl(hslColor.H, hslColor.S, l).ToRgb(); - } - - public static Color Spin(this Color color, int amount = 10) - { - HslColor hslColor = color.ToHsl(); - double h = hslColor.H; - h = (h + amount) % 360; - h = h < 0 ? 360 + h : h; - return HslColor.FromHsl(h, hslColor.S, hslColor.L).ToRgb(); - } - - /// - /// Returns the perceived brightness of the color, from 0-255. - /// - /// - /// - public static int GetBrightness(this Color color) - { - return (color.R * 299 + color.G * 587 + color.B * 114) / 1000; - } + public static double GetAlphaF(this Color color) + { + return color.A / 255d; + } - /// - /// Returns the perceived luminance of a color, from 0-1. - /// - /// - public static double GetLuminance(this Color color) - { - // http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - var rsRGB = color.R / 255; - var gsRGB = color.G / 255; - var bsRGB = color.B / 255; - double r = 0; - double g = 0; - double b = 0; - if (MathUtils.LessThanOrClose(rsRGB, 0.03928)) { - r = rsRGB / 12.92; - } else { - // eslint-disable-next-line prefer-exponentiation-operator - r = Math.Pow((rsRGB + 0.055) / 1.055, 2.4); - } - if (gsRGB <= 0.03928) { - g = gsRGB / 12.92; - } else { - // eslint-disable-next-line prefer-exponentiation-operator - g = Math.Pow((gsRGB + 0.055) / 1.055, 2.4); - } + public static string HexName(this Color color, ColorNameFormat format = ColorNameFormat.HexRgb) + { + var rgb = color.ToUInt32(); + var formatStr = "x8"; + if (format == ColorNameFormat.HexRgb) + { + formatStr = "x6"; + rgb &= 0xFFFFFF; + } - if (bsRGB <= 0.03928) { - b = bsRGB / 12.92; - } else { - // eslint-disable-next-line prefer-exponentiation-operator - b = Math.Pow((bsRGB + 0.055) / 1.055, 2.4); - } + return $"#{rgb.ToString(formatStr, CultureInfo.InvariantCulture)}"; + } - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - } + public static Color Desaturate(this Color color, int amount = 10) + { + amount = Math.Clamp(amount, 0, 100); + var hslColor = color.ToHsl(); + var s = hslColor.S; + s -= amount / 100d; + s = Math.Clamp(s, 0d, 1d); + return HslColor.FromHsl(hslColor.H, s, hslColor.L).ToRgb(); + } + + public static Color Saturate(this Color color, int amount = 10) + { + amount = Math.Clamp(amount, 0, 100); + var hslColor = color.ToHsl(); + var s = hslColor.S; + s += amount / 100d; + s = Math.Clamp(s, 0d, 1d); + return HslColor.FromHsl(hslColor.H, s, hslColor.L).ToRgb(); + } + + public static Color Greyscale(this Color color) + { + return color.Desaturate(100); + } + + public static Color Lighten(this Color color, int amount = 10) + { + amount = Math.Clamp(amount, 0, 100); + var hslColor = color.ToHsl(); + var l = hslColor.L; + l += amount / 100d; + l = Math.Clamp(l, 0d, 1d); + Console.WriteLine(hslColor.H); + return HslColor.FromHsl(hslColor.H, hslColor.S, l).ToRgb(); + } + + public static Color Brighten(this Color color, int amount = 10) + { + amount = Math.Clamp(amount, 0, 100); + int r = color.R; + int g = color.G; + int b = color.B; + var delta = (int)Math.Round(255d * -(amount / 100d)); + r = Math.Max(0, Math.Min(255, r - delta)); + g = Math.Max(0, Math.Min(255, g - delta)); + b = Math.Max(0, Math.Min(255, b - delta)); + return Color.FromRgb((byte)r, (byte)g, (byte)b); + } + + public static Color Darken(this Color color, int amount = 10) + { + amount = Math.Clamp(amount, 0, 100); + var hslColor = color.ToHsl(); + var l = hslColor.L; + l -= amount / 100d; + l = Math.Clamp(l, 0d, 1d); + return HslColor.FromHsl(hslColor.H, hslColor.S, l).ToRgb(); + } + + public static Color Spin(this Color color, int amount = 10) + { + var hslColor = color.ToHsl(); + var h = hslColor.H; + h = (h + amount) % 360; + h = h < 0 ? 360 + h : h; + return HslColor.FromHsl(h, hslColor.S, hslColor.L).ToRgb(); + } + + /// + /// Returns the perceived brightness of the color, from 0-255. + /// + /// + /// + public static int GetBrightness(this Color color) + { + return (color.R * 299 + color.G * 587 + color.B * 114) / 1000; + } + + /// + /// Returns the perceived luminance of a color, from 0-1. + /// + /// + public static double GetLuminance(this Color color) + { + // http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + var rsRGB = color.R / 255; + var gsRGB = color.G / 255; + var bsRGB = color.B / 255; + double r = 0; + double g = 0; + double b = 0; + if (MathUtils.LessThanOrClose(rsRGB, 0.03928)) + r = rsRGB / 12.92; + else + + // eslint-disable-next-line prefer-exponentiation-operator + r = Math.Pow((rsRGB + 0.055) / 1.055, 2.4); + if (gsRGB <= 0.03928) + g = gsRGB / 12.92; + else + + // eslint-disable-next-line prefer-exponentiation-operator + g = Math.Pow((gsRGB + 0.055) / 1.055, 2.4); + + if (bsRGB <= 0.03928) + b = bsRGB / 12.92; + else + + // eslint-disable-next-line prefer-exponentiation-operator + b = Math.Pow((bsRGB + 0.055) / 1.055, 2.4); + + return 0.2126 * r + 0.7152 * g + 0.0722 * b; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/ColorTransition.cs b/src/AtomUI.Base/Media/ColorTransition.cs index 62f8f46..adaf23c 100644 --- a/src/AtomUI.Base/Media/ColorTransition.cs +++ b/src/AtomUI.Base/Media/ColorTransition.cs @@ -5,8 +5,8 @@ namespace AtomUI.Media; public class ColorTransition : InterpolatingTransitionBase { - protected override Color Interpolate(double progress, Color from, Color to) - { - return InterpolateUtils.ColorInterpolate(from, to, progress); - } + protected override Color Interpolate(double progress, Color from, Color to) + { + return InterpolateUtils.ColorInterpolate(from, to, progress); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/ColorUtils.cs b/src/AtomUI.Base/Media/ColorUtils.cs index 83d2240..61774bb 100644 --- a/src/AtomUI.Base/Media/ColorUtils.cs +++ b/src/AtomUI.Base/Media/ColorUtils.cs @@ -5,291 +5,280 @@ namespace AtomUI.Media; public enum WCAG2Level { - AA, - AAA + AA, + AAA } + public enum WCAG2Size { - Large, - Small + Large, + Small } + public class WCAG2Parms { - public WCAG2Level Level { get; set; } = WCAG2Level.AA; - public WCAG2Size Size { get; set; } = WCAG2Size.Small; + public WCAG2Level Level { get; set; } = WCAG2Level.AA; + public WCAG2Size Size { get; set; } = WCAG2Size.Small; } + public class WCAG2FallbackParms : WCAG2Parms { - public bool IncludeFallbackColors { get; set; } + public bool IncludeFallbackColors { get; set; } } + public static class ColorUtils { - public static Color FromRgbF(double alpha, double red, double green, double blue) - { - return Color.FromArgb((byte)Math.Round(alpha * 255d), - (byte)Math.Round(red * 255d), - (byte)Math.Round(green * 255d), - (byte)Math.Round(blue * 255d)); - } + public static Color FromRgbF(double alpha, double red, double green, double blue) + { + return Color.FromArgb((byte)Math.Round(alpha * 255d), + (byte)Math.Round(red * 255d), + (byte)Math.Round(green * 255d), + (byte)Math.Round(blue * 255d)); + } - public static Color FromRgbF(double red, double green, double blue) - { - return FromRgbF(1d, red, green, blue); - } + public static Color FromRgbF(double red, double green, double blue) + { + return FromRgbF(1d, red, green, blue); + } - public static Color TransparentColor() - { - return Color.FromArgb(0, 255, 255, 255); - } + public static Color TransparentColor() + { + return Color.FromArgb(0, 255, 255, 255); + } - public static Color Desaturate(string color, int amount = 10) - { - return Color.Parse(color).Desaturate(amount); - } + public static Color Desaturate(string color, int amount = 10) + { + return Color.Parse(color).Desaturate(amount); + } - public static Color Saturate(string color, int amount = 10) - { - return Color.Parse(color).Saturate(amount); - } + public static Color Saturate(string color, int amount = 10) + { + return Color.Parse(color).Saturate(amount); + } - public static Color Lighten(string color, int amount = 10) - { - return Color.Parse(color).Lighten(amount); - } + public static Color Lighten(string color, int amount = 10) + { + return Color.Parse(color).Lighten(amount); + } - public static Color Brighten(string color, int amount = 10) - { - return Color.Parse(color).Brighten(amount); - } + public static Color Brighten(string color, int amount = 10) + { + return Color.Parse(color).Brighten(amount); + } - public static Color Darken(string color, int amount = 10) - { - return Color.Parse(color).Darken(amount); - } + public static Color Darken(string color, int amount = 10) + { + return Color.Parse(color).Darken(amount); + } - public static Color Spin(string color, int amount = 10) - { - return Color.Parse(color).Spin(amount); - } + public static Color Spin(string color, int amount = 10) + { + return Color.Parse(color).Spin(amount); + } - public static Color OnBackground(in Color frontColor, in Color backgroundColor) - { - double fr = frontColor.GetRedF(); - double fg = frontColor.GetGreenF(); - double fb = frontColor.GetBlueF(); - double fa = frontColor.GetAlphaF(); + public static Color OnBackground(in Color frontColor, in Color backgroundColor) + { + var fr = frontColor.GetRedF(); + var fg = frontColor.GetGreenF(); + var fb = frontColor.GetBlueF(); + var fa = frontColor.GetAlphaF(); - double br = backgroundColor.GetRedF(); - double bg = backgroundColor.GetGreenF(); - double bb = backgroundColor.GetBlueF(); - double ba = backgroundColor.GetAlphaF(); + var br = backgroundColor.GetRedF(); + var bg = backgroundColor.GetGreenF(); + var bb = backgroundColor.GetBlueF(); + var ba = backgroundColor.GetAlphaF(); - double alpha = fa + ba * (1 - fa); + var alpha = fa + ba * (1 - fa); - double nr = (fr * fa + br * ba * (1 - fa)) / alpha; - double ng = (fg * fa + bg * ba * (1 - fa)) / alpha; - double nb = (fb * fa + bb * ba * (1 - fa)) / alpha; - double na = alpha; + var nr = (fr * fa + br * ba * (1 - fa)) / alpha; + var ng = (fg * fa + bg * ba * (1 - fa)) / alpha; + var nb = (fb * fa + bb * ba * (1 - fa)) / alpha; + var na = alpha; - return ColorUtils.FromRgbF(na, nr, ng, nb); - } + return FromRgbF(na, nr, ng, nb); + } - public static bool IsStableColor(int color) - { - return color >= 0 && color <= 255; - } + public static bool IsStableColor(int color) + { + return color >= 0 && color <= 255; + } - public static bool IsStableColor(float color) - { - return color >= 0.0f && color <= 1.0f; - } + public static bool IsStableColor(float color) + { + return color >= 0.0f && color <= 1.0f; + } - public static bool IsStableColor(double color) - { - return color >= 0.0d && color <= 1.0d; - } + public static bool IsStableColor(double color) + { + return color >= 0.0d && color <= 1.0d; + } - public static Color AlphaColor(in Color frontColor, in Color backgroundColor) - { - double fR = frontColor.GetRedF(); - double fG = frontColor.GetGreenF(); - double fB = frontColor.GetBlueF(); - double originAlpha = frontColor.GetAlphaF(); - if (originAlpha < 1d) { - return frontColor; - } + public static Color AlphaColor(in Color frontColor, in Color backgroundColor) + { + var fR = frontColor.GetRedF(); + var fG = frontColor.GetGreenF(); + var fB = frontColor.GetBlueF(); + var originAlpha = frontColor.GetAlphaF(); + if (originAlpha < 1d) return frontColor; - double bR = backgroundColor.GetRedF(); - double bG = backgroundColor.GetGreenF(); - double bB = backgroundColor.GetBlueF(); + var bR = backgroundColor.GetRedF(); + var bG = backgroundColor.GetGreenF(); + var bB = backgroundColor.GetBlueF(); - for (var fA = 0.01d; fA <= 1.0d; fA += 0.01d) { - double r = Math.Round((fR - bR * (1d - fA)) / fA); - double g = Math.Round((fG - bG * (1d - fA)) / fA); - double b = Math.Round((fB - bB * (1d - fA)) / fA); - if (IsStableColor(r) && IsStableColor(g) && IsStableColor(b)) { - return ColorUtils.FromRgbF(Math.Round(fA * 100d) / 100d, r, g, b); - } - } + for (var fA = 0.01d; fA <= 1.0d; fA += 0.01d) + { + var r = Math.Round((fR - bR * (1d - fA)) / fA); + var g = Math.Round((fG - bG * (1d - fA)) / fA); + var b = Math.Round((fB - bB * (1d - fA)) / fA); + if (IsStableColor(r) && IsStableColor(g) && IsStableColor(b)) + return FromRgbF(Math.Round(fA * 100d) / 100d, r, g, b); + } - // fallback - /* istanbul ignore next */ - return ColorUtils.FromRgbF(1.0d, fR, fG, fB); - } + // fallback + /* istanbul ignore next */ + return FromRgbF(1.0d, fR, fG, fB); + } - public static Color ParseCssRgbColor(string colorExpr) - { - if (TryParseCssRgbColor(colorExpr, out Color color)) { - return color; - } + public static Color ParseCssRgbColor(string colorExpr) + { + if (TryParseCssRgbColor(colorExpr, out var color)) return color; - throw new FormatException($"Invalid color string: '{colorExpr.ToString()}'."); - } + throw new FormatException($"Invalid color string: '{colorExpr}'."); + } - public static bool TryParseCssRgbColor(string? colorExpr, out Color color) - { - color = default; - if (string.IsNullOrEmpty(colorExpr)) { - return false; - } + public static bool TryParseCssRgbColor(string? colorExpr, out Color color) + { + color = default; + if (string.IsNullOrEmpty(colorExpr)) return false; - if (colorExpr[0] == '#') { - return Color.TryParse(colorExpr, out color); - } + if (colorExpr[0] == '#') return Color.TryParse(colorExpr, out color); - bool isRgba = colorExpr.StartsWith("rgba", StringComparison.InvariantCultureIgnoreCase); - bool isRgb = false; - if (!isRgba) { - isRgb = colorExpr.StartsWith("rgb", StringComparison.InvariantCultureIgnoreCase); - } + var isRgba = colorExpr.StartsWith("rgba", StringComparison.InvariantCultureIgnoreCase); + var isRgb = false; + if (!isRgba) isRgb = colorExpr.StartsWith("rgb", StringComparison.InvariantCultureIgnoreCase); - if (isRgb || isRgba) { - int leftParen = colorExpr.IndexOf('('); - int rightParen = colorExpr.IndexOf(')'); - if (leftParen == -1 || rightParen == -1) { - return false; - } + if (isRgb || isRgba) + { + var leftParen = colorExpr.IndexOf('('); + var rightParen = colorExpr.IndexOf(')'); + if (leftParen == -1 || rightParen == -1) return false; - var parts = new List(colorExpr.Substring(leftParen + 1, rightParen - leftParen - 1) - .Split(',', StringSplitOptions.RemoveEmptyEntries)); - if (isRgb) { - if (parts.Count != 3) { - return false; + var parts = new List(colorExpr.Substring(leftParen + 1, rightParen - leftParen - 1) + .Split(',', StringSplitOptions.RemoveEmptyEntries)); + if (isRgb) + { + if (parts.Count != 3) return false; + + parts.Add("255"); + } + else + { + if (parts.Count != 4) return false; } - parts.Add("255"); - } else { - if (parts.Count != 4) { - return false; - } - } + var rgbaValues = new List(); + foreach (var part in parts) + if (int.TryParse(part, out var partValue)) + rgbaValues.Add(partValue); + else + return false; - List rgbaValues = new List(); - foreach (var part in parts) { - if (int.TryParse(part, out int partValue)) { - rgbaValues.Add(partValue); - } else { - return false; - } - } + color = Color.FromArgb((byte)rgbaValues[0], (byte)rgbaValues[1], (byte)rgbaValues[2], (byte)rgbaValues[3]); + return true; + } - color = Color.FromArgb((byte)rgbaValues[0], (byte)rgbaValues[1], (byte)rgbaValues[2], (byte)rgbaValues[3]); - return true; - } + return false; + } - return false; - } + /// Readability Functions + /// --------------------- + /// false + /// new Color().IsReadable('#000', '#111', { level: 'AA', size: 'large' }) => false + public static bool IsReadable(Color color1, Color color2, WCAG2Parms? wcag2 = null) + { + wcag2 ??= new WCAG2Parms(); + var readabilityLevel = Readability(color1, color2); + if (wcag2.Level == WCAG2Level.AA) + { + if (wcag2.Size == WCAG2Size.Large) return MathUtils.GreaterThanOrClose(readabilityLevel, 3); - /// - /// Ensure that foreground and background color combinations meet WCAG2 guidelines. - /// The third argument is an object. - /// the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA'; - /// the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'. - /// If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}. - /// - /// Example - /// new Color().IsReadable('#000', '#111') => false - /// new Color().IsReadable('#000', '#111', { level: 'AA', size: 'large' }) => false - public static bool IsReadable(Color color1, Color color2, WCAG2Parms? wcag2 = null) - { - wcag2 ??= new WCAG2Parms(); - var readabilityLevel = Readability(color1, color2); - if (wcag2.Level == WCAG2Level.AA) { - if (wcag2.Size == WCAG2Size.Large) { - return MathUtils.GreaterThanOrClose(readabilityLevel, 3); - } - - return MathUtils.GreaterThanOrClose(readabilityLevel, 4.5); - } else if (wcag2.Level == WCAG2Level.AAA) { - if (wcag2.Size == WCAG2Size.Large) { return MathUtils.GreaterThanOrClose(readabilityLevel, 4.5); - } + } - return MathUtils.GreaterThanOrClose(readabilityLevel, 7); - } + if (wcag2.Level == WCAG2Level.AAA) + { + if (wcag2.Size == WCAG2Size.Large) return MathUtils.GreaterThanOrClose(readabilityLevel, 4.5); - return false; - } + return MathUtils.GreaterThanOrClose(readabilityLevel, 7); + } - /// - /// Given a base color and a list of possible foreground or background - /// colors for that base, returns the most readable color. - /// Optionally returns Black or White if the most readable color is unreadable. - /// - /// @param baseColor - the base color. - /// @param colorList - array of colors to pick the most readable one from. - /// @param args - and object with extra arguments - /// - /// Example - /// new Color().mostReadable('#123', ['#124", "#125'], { includeFallbackColors: false }).toHexString(); // "#112255" - /// new Color().mostReadable('#123', ['#124", "#125'],{ includeFallbackColors: true }).toHexString(); // "#ffffff" - /// new Color().mostReadable('#a8015a', ["#faf3f3"], { includeFallbackColors:true, level: 'AAA', size: 'large' }).toHexString(); // "#faf3f3" - /// new Color().mostReadable('#a8015a', ["#faf3f3"], { includeFallbackColors:true, level: 'AAA', size: 'small' }).toHexString(); // "#ffffff" - /// - public static Color? MostReadable(Color baseColor, List colorList, WCAG2FallbackParms? args = null) - { - args ??= new WCAG2FallbackParms() - { - IncludeFallbackColors = false, - Level = WCAG2Level.AA, - Size = WCAG2Size.Small - }; - Color? bestColor = null; - double bestScore = 0d; - foreach (var color in colorList) { - var score = Readability(baseColor, color); - if (score > bestScore) { - bestScore = score; - bestColor = color; - } - } + return false; + } - if (IsReadable(baseColor, bestColor!.Value, new WCAG2Parms() { Level = args.Level, Size = args.Size }) || - !args.IncludeFallbackColors) { - return bestColor; - } + /// Given a base color and a list of possible foreground or background + /// colors for that base, returns the most readable color. + /// Optionally returns Black or White if the most readable color is unreadable. + /// + /// @param baseColor - the base color. + /// @param colorList - array of colors to pick the most readable one from. + /// @param args - and object with extra arguments + /// + /// Example + /// new Color().mostReadable('#123', ['#124", "#125'], { includeFallbackColors: false }).toHexString(); // "#112255" + /// new Color().mostReadable('#123', ['#124", "#125'],{ includeFallbackColors: true }).toHexString(); // "#ffffff" + /// new Color().mostReadable('#a8015a', ["#faf3f3"], { includeFallbackColors:true, level: 'AAA', size: 'large' }).toHexString(); // "#faf3f3" + /// new Color().mostReadable('#a8015a', ["#faf3f3"], { includeFallbackColors:true, level: 'AAA', size: 'small' }).toHexString(); // "#ffffff" + public static Color? MostReadable(Color baseColor, List colorList, WCAG2FallbackParms? args = null) + { + args ??= new WCAG2FallbackParms + { + IncludeFallbackColors = false, + Level = WCAG2Level.AA, + Size = WCAG2Size.Small + }; + Color? bestColor = null; + var bestScore = 0d; + foreach (var color in colorList) + { + var score = Readability(baseColor, color); + if (score > bestScore) + { + bestScore = score; + bestColor = color; + } + } - args.IncludeFallbackColors = false; - return MostReadable(baseColor, new List() - { - Color.Parse("#fff"), - Color.Parse("#000") - }, args); - } + if (IsReadable(baseColor, bestColor!.Value, new WCAG2Parms { Level = args.Level, Size = args.Size }) || + !args.IncludeFallbackColors) + return bestColor; + + args.IncludeFallbackColors = false; + return MostReadable(baseColor, new List + { + Color.Parse("#fff"), + Color.Parse("#000") + }, args); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/CommonShapeBuilder.cs b/src/AtomUI.Base/Media/CommonShapeBuilder.cs index 25e70a2..461d3e9 100644 --- a/src/AtomUI.Base/Media/CommonShapeBuilder.cs +++ b/src/AtomUI.Base/Media/CommonShapeBuilder.cs @@ -7,107 +7,118 @@ namespace AtomUI.Media; public static class CommonShapeBuilder { - public static Geometry BuildCheckMark(Size size) - { - var checkMark = new StreamGeometry(); - using var context = checkMark.Open(); + public static Geometry BuildCheckMark(Size size) + { + var checkMark = new StreamGeometry(); + using var context = checkMark.Open(); - var startPoint = new Point(size.Width * 0.25, size.Height * 0.5); - var midPoint = new Point(size.Width * 0.4, size.Height * 0.7); - var endPoint = new Point(size.Width * 0.7, size.Height * 0.3); + var startPoint = new Point(size.Width * 0.25, size.Height * 0.5); + var midPoint = new Point(size.Width * 0.4, size.Height * 0.7); + var endPoint = new Point(size.Width * 0.7, size.Height * 0.3); - context.BeginFigure(startPoint, true); - context.LineTo(midPoint); - context.LineTo(endPoint); - context.EndFigure(false); + context.BeginFigure(startPoint, true); + context.LineTo(midPoint); + context.LineTo(endPoint); + context.EndFigure(false); - return checkMark; - } - - /// - /// 生成一个以矩形中点为圆心,以宽和高最小的一半为半径的且指定角度的圆弧 - /// - /// - /// - /// - /// - public static Geometry BuildArc(Rect rect, double startAngle, double sweepAngle) - { - if (MathUtils.IsZero(sweepAngle)) { - return new StreamGeometry(); - } - - var angle1 = MathUtilities.Deg2Rad(startAngle); - var angle2 = angle1 + MathUtilities.Deg2Rad(sweepAngle); - - startAngle = Math.Min(angle1, angle2); - sweepAngle = Math.Max(angle1, angle2); + return checkMark; + } - var normStart = RadToNormRad(startAngle); - var normEnd = RadToNormRad(sweepAngle); + /// + /// 生成一个以矩形中点为圆心,以宽和高最小的一半为半径的且指定角度的圆弧 + /// + /// + /// + /// + /// + public static Geometry BuildArc(Rect rect, double startAngle, double sweepAngle) + { + if (MathUtils.IsZero(sweepAngle)) return new StreamGeometry(); - if (MathUtils.AreClose(normStart, normEnd) && !MathUtils.AreClose(startAngle, sweepAngle)) { - // Complete ring. - return new EllipseGeometry(rect); - } - - // Partial arc. - var deflatedRect = rect; + var angle1 = MathUtilities.Deg2Rad(startAngle); + var angle2 = angle1 + MathUtilities.Deg2Rad(sweepAngle); - var centerX = rect.Center.X; - var centerY = rect.Center.Y; + startAngle = Math.Min(angle1, angle2); + sweepAngle = Math.Max(angle1, angle2); - var radiusX = deflatedRect.Width / 2; - var radiusY = deflatedRect.Height / 2; + var normStart = RadToNormRad(startAngle); + var normEnd = RadToNormRad(sweepAngle); - var angleGap = RadToNormRad(sweepAngle - startAngle); + if (MathUtils.AreClose(normStart, normEnd) && !MathUtils.AreClose(startAngle, sweepAngle)) - var startPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, startAngle); - var endPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, sweepAngle); + // Complete ring. + return new EllipseGeometry(rect); - var arcGeometry = new StreamGeometry(); + // Partial arc. + var deflatedRect = rect; - using (StreamGeometryContext context = arcGeometry.Open()) { - context.BeginFigure(startPoint, false); - context.ArcTo( - endPoint, - new Size(radiusX, radiusY), - rotationAngle: angleGap, - isLargeArc: angleGap >= Math.PI, - SweepDirection.Clockwise); - context.EndFigure(false); - } + var centerX = rect.Center.X; + var centerY = rect.Center.Y; - return arcGeometry; - } + var radiusX = deflatedRect.Width / 2; + var radiusY = deflatedRect.Height / 2; - private static double RadToNormRad(double inAngle) => ((inAngle % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2); - private static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) => - new Point((radiusX * Math.Cos(angle)) + centerX, (radiusY * Math.Sin(angle)) + centerY); + var angleGap = RadToNormRad(sweepAngle - startAngle); - public static Geometry BuildArrow(double size, double radius) - { - var geometryStream = new StreamGeometry(); - using var context = geometryStream.Open(); - - // 假设 p1 是原始圆角顶点,p2 和 p3 是原始底边的顶点 - var p1 = new Point(size / 2.0, size / 2.0 + 1); - var p2 = new Point(0, size); - var p3 = new Point(size, size); - // 假设 r 是圆角的半径 - var controlPoint = new Point(p1.X, p1.Y - radius); - // 移动到调整后的底边左顶点 - context.BeginFigure(p2, true); - // 绘制左边的直线到圆角的起始点 - context.LineTo(new Point(p1.X - radius, p1.Y)); - // 绘制圆角 - context.QuadraticBezierTo(controlPoint, new Point(p1.X + radius, p1.Y)); - // 绘制右边的直线到调整后的底边右顶点 - context.LineTo(p3); - // 绘制底边,闭合路径 - context.LineTo(p2); - context.EndFigure(true); - - return geometryStream; - } + var startPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, startAngle); + var endPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, sweepAngle); + + var arcGeometry = new StreamGeometry(); + + using (var context = arcGeometry.Open()) + { + context.BeginFigure(startPoint, false); + context.ArcTo( + endPoint, + new Size(radiusX, radiusY), + angleGap, + angleGap >= Math.PI, + SweepDirection.Clockwise); + context.EndFigure(false); + } + + return arcGeometry; + } + + private static double RadToNormRad(double inAngle) + { + return (inAngle % (Math.PI * 2) + Math.PI * 2) % (Math.PI * 2); + } + + private static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) + { + return new Point(radiusX * Math.Cos(angle) + centerX, radiusY * Math.Sin(angle) + centerY); + } + + public static Geometry BuildArrow(double size, double radius) + { + var geometryStream = new StreamGeometry(); + using var context = geometryStream.Open(); + + // 假设 p1 是原始圆角顶点,p2 和 p3 是原始底边的顶点 + var p1 = new Point(size / 2.0, size / 2.0 + 1); + var p2 = new Point(0, size); + var p3 = new Point(size, size); + + // 假设 r 是圆角的半径 + var controlPoint = new Point(p1.X, p1.Y - radius); + + // 移动到调整后的底边左顶点 + context.BeginFigure(p2, true); + + // 绘制左边的直线到圆角的起始点 + context.LineTo(new Point(p1.X - radius, p1.Y)); + + // 绘制圆角 + context.QuadraticBezierTo(controlPoint, new Point(p1.X + radius, p1.Y)); + + // 绘制右边的直线到调整后的底边右顶点 + context.LineTo(p3); + + // 绘制底边,闭合路径 + context.LineTo(p2); + context.EndFigure(true); + + return geometryStream; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/DrawingContextExtensions.cs b/src/AtomUI.Base/Media/DrawingContextExtensions.cs index ce98db7..f929293 100644 --- a/src/AtomUI.Base/Media/DrawingContextExtensions.cs +++ b/src/AtomUI.Base/Media/DrawingContextExtensions.cs @@ -6,23 +6,22 @@ namespace AtomUI.Media; public static class DrawingContextExtensions { - public static void DrawPilledRect(this DrawingContext context, IBrush? brush, IPen? pen, Rect rect, - Orientation orientation = Orientation.Horizontal, - BoxShadows boxShadows = default) - { - double pillRadius; - if (orientation == Orientation.Horizontal) { - pillRadius = rect.Height / 2; - } else { - pillRadius = rect.Width / 2; - } - context.DrawRectangle(brush, pen, rect, pillRadius, pillRadius, boxShadows); - } + public static void DrawPilledRect(this DrawingContext context, IBrush? brush, IPen? pen, Rect rect, + Orientation orientation = Orientation.Horizontal, + BoxShadows boxShadows = default) + { + double pillRadius; + if (orientation == Orientation.Horizontal) + pillRadius = rect.Height / 2; + else + pillRadius = rect.Width / 2; + context.DrawRectangle(brush, pen, rect, pillRadius, pillRadius, boxShadows); + } - public static void DrawArc(this DrawingContext context, IPen? pen, - Rect rect, double startAngle, double sweepAngle) - { - var geometry = CommonShapeBuilder.BuildArc(rect, startAngle, sweepAngle); - context.DrawGeometry(null, pen, geometry); - } + public static void DrawArc(this DrawingContext context, IPen? pen, + Rect rect, double startAngle, double sweepAngle) + { + var geometry = CommonShapeBuilder.BuildArc(rect, startAngle, sweepAngle); + context.DrawGeometry(null, pen, geometry); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/FontUtils.cs b/src/AtomUI.Base/Media/FontUtils.cs index 2f2f62e..f9af9f3 100644 --- a/src/AtomUI.Base/Media/FontUtils.cs +++ b/src/AtomUI.Base/Media/FontUtils.cs @@ -3,15 +3,15 @@ public static class FontUtils { /// - /// 将 value 的值转换为像素 + /// 将 value 的值转换为像素 /// /// /// /// /// public static double ConvertEmToPixel(double value, double fontSize, double renderScaling = 1.0) - { - var fontSizePx = fontSize * value * renderScaling; - return fontSizePx * value; - } + { + var fontSizePx = fontSize * value * renderScaling; + return fontSizePx * value; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/GeometryUtils.cs b/src/AtomUI.Base/Media/GeometryUtils.cs index 4921ba4..5c849a3 100644 --- a/src/AtomUI.Base/Media/GeometryUtils.cs +++ b/src/AtomUI.Base/Media/GeometryUtils.cs @@ -4,39 +4,39 @@ namespace AtomUI.Media; public static class GeometryUtils { - public static Rect CalculateScaledRect(in Rect rect, double scaleFactorX, double scaleFactorY, in Point origin) - { - // 计算原点相对于矩形左上角的偏移量 - double originalOffsetX = origin.X - rect.X; - double originalOffsetY = origin.Y - rect.Y; - - // 计算缩放后的偏移量 - double scaledOffsetX = originalOffsetX * scaleFactorX; - double scaledOffsetY = originalOffsetY * scaleFactorY; + public static Rect CalculateScaledRect(in Rect rect, double scaleFactorX, double scaleFactorY, in Point origin) + { + // 计算原点相对于矩形左上角的偏移量 + var originalOffsetX = origin.X - rect.X; + var originalOffsetY = origin.Y - rect.Y; - // 计算偏移量的变化 - double offsetXChange = scaledOffsetX - originalOffsetX; - double offsetYChange = scaledOffsetY - originalOffsetY; - - // 计算新的矩形位置 - double newX = rect.X - offsetXChange; - double newY = rect.Y - offsetYChange; + // 计算缩放后的偏移量 + var scaledOffsetX = originalOffsetX * scaleFactorX; + var scaledOffsetY = originalOffsetY * scaleFactorY; - // 计算新的矩形宽度和高度 - double newWidth = rect.Width * scaleFactorX; - double newHeight = rect.Height * scaleFactorY; + // 计算偏移量的变化 + var offsetXChange = scaledOffsetX - originalOffsetX; + var offsetYChange = scaledOffsetY - originalOffsetY; - return new Rect(newX, newY, newWidth, newHeight); - } + // 计算新的矩形位置 + var newX = rect.X - offsetXChange; + var newY = rect.Y - offsetYChange; - public static double CornerRadiusScalarValue(CornerRadius cornerRadius, bool maxWhenNotUniform = true) - { - if (cornerRadius.IsUniform) { - return cornerRadius.TopLeft; - } + // 计算新的矩形宽度和高度 + var newWidth = rect.Width * scaleFactorX; + var newHeight = rect.Height * scaleFactorY; - return maxWhenNotUniform - ? Math.Max(cornerRadius.TopLeft, Math.Max(cornerRadius.TopRight, Math.Max(cornerRadius.BottomLeft, cornerRadius.BottomRight))) - : Math.Min(cornerRadius.TopLeft, Math.Min(cornerRadius.TopRight, Math.Min(cornerRadius.BottomLeft, cornerRadius.BottomRight))); - } + return new Rect(newX, newY, newWidth, newHeight); + } + + public static double CornerRadiusScalarValue(CornerRadius cornerRadius, bool maxWhenNotUniform = true) + { + if (cornerRadius.IsUniform) return cornerRadius.TopLeft; + + return maxWhenNotUniform + ? Math.Max(cornerRadius.TopLeft, + Math.Max(cornerRadius.TopRight, Math.Max(cornerRadius.BottomLeft, cornerRadius.BottomRight))) + : Math.Min(cornerRadius.TopLeft, + Math.Min(cornerRadius.TopRight, Math.Min(cornerRadius.BottomLeft, cornerRadius.BottomRight))); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/INotifyTransitionCompleted.cs b/src/AtomUI.Base/Media/INotifyTransitionCompleted.cs index 763721d..27c90af 100644 --- a/src/AtomUI.Base/Media/INotifyTransitionCompleted.cs +++ b/src/AtomUI.Base/Media/INotifyTransitionCompleted.cs @@ -2,17 +2,18 @@ public class TransitionCompletedEventArgs : EventArgs { - public bool Status { get; } - - public TransitionCompletedEventArgs(bool status) - { - Status = status; - } + public TransitionCompletedEventArgs(bool status) + { + Status = status; + } + + public bool Status { get; } } + internal interface INotifyTransitionCompleted { - public IObservable CompletedObservable { get; } - public event EventHandler? TransitionCompleted; - public void NotifyTransitionCompleted(bool status); + public IObservable CompletedObservable { get; } + public event EventHandler? TransitionCompleted; + public void NotifyTransitionCompleted(bool status); } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/InterpolateUtils.cs b/src/AtomUI.Base/Media/InterpolateUtils.cs index 0a7b30f..44f155f 100644 --- a/src/AtomUI.Base/Media/InterpolateUtils.cs +++ b/src/AtomUI.Base/Media/InterpolateUtils.cs @@ -4,47 +4,50 @@ namespace AtomUI.Media; public static class InterpolateUtils { - public static Color ColorInterpolate(Color fromColor, Color toColor, double progress) - { - double a1 = fromColor.GetAlphaF(); - double r1 = fromColor.GetRedF() * a1; - double g1 = fromColor.GetGreenF() * a1; - double b1 = fromColor.GetBlueF() * a1; - - double a2 = toColor.GetAlphaF(); - double r2 = toColor.GetRedF() * a2; - double g2 = toColor.GetGreenF() * a2; - double b2 = toColor.GetBlueF() * a2; + public static Color ColorInterpolate(Color fromColor, Color toColor, double progress) + { + var a1 = fromColor.GetAlphaF(); + var r1 = fromColor.GetRedF() * a1; + var g1 = fromColor.GetGreenF() * a1; + var b1 = fromColor.GetBlueF() * a1; - double r = DoubleInterpolate(r1, r2, progress); - double g = DoubleInterpolate(g1, g2, progress); - double b = DoubleInterpolate(b1, b2, progress); - double a = DoubleInterpolate(a1, a2, progress); - - // 处理接近完全透明的情况 - if (a < 1e-5) { - // 在这种情况下,我们可以选择直接使用目标颜色的RGB分量 - r = toColor.GetRedF(); - g = toColor.GetGreenF(); - b = toColor.GetBlueF(); - } else { - // 如果alpha不为零,反预乘alpha - r /= a; - g /= a; - b /= a; - } + var a2 = toColor.GetAlphaF(); + var r2 = toColor.GetRedF() * a2; + var g2 = toColor.GetGreenF() * a2; + var b2 = toColor.GetBlueF() * a2; - // 防止颜色分量超出范围 - r = Math.Clamp(r, 0.0f, 1.0f); - g = Math.Clamp(g, 0.0f, 1.0f); - b = Math.Clamp(b, 0.0f, 1.0f); - a = Math.Clamp(a, 0.0f, 1.0f); - - return ColorUtils.FromRgbF(a, r, g, b); - } - - public static double DoubleInterpolate(double oldValue, double newValue, double progress) - { - return ((newValue - oldValue) * progress) + oldValue; - } + var r = DoubleInterpolate(r1, r2, progress); + var g = DoubleInterpolate(g1, g2, progress); + var b = DoubleInterpolate(b1, b2, progress); + var a = DoubleInterpolate(a1, a2, progress); + + // 处理接近完全透明的情况 + if (a < 1e-5) + { + // 在这种情况下,我们可以选择直接使用目标颜色的RGB分量 + r = toColor.GetRedF(); + g = toColor.GetGreenF(); + b = toColor.GetBlueF(); + } + else + { + // 如果alpha不为零,反预乘alpha + r /= a; + g /= a; + b /= a; + } + + // 防止颜色分量超出范围 + r = Math.Clamp(r, 0.0f, 1.0f); + g = Math.Clamp(g, 0.0f, 1.0f); + b = Math.Clamp(b, 0.0f, 1.0f); + a = Math.Clamp(a, 0.0f, 1.0f); + + return ColorUtils.FromRgbF(a, r, g, b); + } + + public static double DoubleInterpolate(double oldValue, double newValue, double progress) + { + return (newValue - oldValue) * progress + oldValue; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/NotifiableDoubleTransition.cs b/src/AtomUI.Base/Media/NotifiableDoubleTransition.cs index cf220fd..3a8f0ca 100644 --- a/src/AtomUI.Base/Media/NotifiableDoubleTransition.cs +++ b/src/AtomUI.Base/Media/NotifiableDoubleTransition.cs @@ -5,20 +5,21 @@ namespace AtomUI.Media; public class NotifiableDoubleTransition : DoubleTransition, INotifyTransitionCompleted { - public event EventHandler? TransitionCompleted; - private Subject _subject; + private readonly Subject _subject; - public NotifiableDoubleTransition() - { - _subject = new Subject(); - } - - void INotifyTransitionCompleted.NotifyTransitionCompleted(bool status) - { - _subject.OnNext(status); - _subject.OnCompleted(); - TransitionCompleted?.Invoke(this, new TransitionCompletedEventArgs(status)); - } - - IObservable INotifyTransitionCompleted.CompletedObservable => _subject; + public NotifiableDoubleTransition() + { + _subject = new Subject(); + } + + public event EventHandler? TransitionCompleted; + + void INotifyTransitionCompleted.NotifyTransitionCompleted(bool status) + { + _subject.OnNext(status); + _subject.OnCompleted(); + TransitionCompleted?.Invoke(this, new TransitionCompletedEventArgs(status)); + } + + IObservable INotifyTransitionCompleted.CompletedObservable => _subject; } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/NotifiableTransformOperationsTransition.cs b/src/AtomUI.Base/Media/NotifiableTransformOperationsTransition.cs index c7e9a16..a265dc7 100644 --- a/src/AtomUI.Base/Media/NotifiableTransformOperationsTransition.cs +++ b/src/AtomUI.Base/Media/NotifiableTransformOperationsTransition.cs @@ -5,20 +5,21 @@ namespace AtomUI.Media; public class NotifiableTransformOperationsTransition : TransformOperationsTransition, INotifyTransitionCompleted { - public event EventHandler? TransitionCompleted; - private Subject _subject; - - public NotifiableTransformOperationsTransition() - { - _subject = new Subject(); - } - - void INotifyTransitionCompleted.NotifyTransitionCompleted(bool status) - { - _subject.OnNext(status); - _subject.OnCompleted(); - TransitionCompleted?.Invoke(this, new TransitionCompletedEventArgs(status)); - } - - IObservable INotifyTransitionCompleted.CompletedObservable => _subject; + private readonly Subject _subject; + + public NotifiableTransformOperationsTransition() + { + _subject = new Subject(); + } + + public event EventHandler? TransitionCompleted; + + void INotifyTransitionCompleted.NotifyTransitionCompleted(bool status) + { + _subject.OnNext(status); + _subject.OnCompleted(); + TransitionCompleted?.Invoke(this, new TransitionCompletedEventArgs(status)); + } + + IObservable INotifyTransitionCompleted.CompletedObservable => _subject; } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/PenUtils.cs b/src/AtomUI.Base/Media/PenUtils.cs index d72227e..166ece6 100644 --- a/src/AtomUI.Base/Media/PenUtils.cs +++ b/src/AtomUI.Base/Media/PenUtils.cs @@ -7,7 +7,7 @@ namespace AtomUI.Media; public static class PenUtils { /// - /// Smart reuse and update pen properties. + /// Smart reuse and update pen properties. /// /// Old pen to modify. /// The brush used to draw. @@ -19,50 +19,52 @@ public static class PenUtils /// The miter limit. /// If a new instance was created and visual invalidation required. internal static bool TryModifyOrCreate(ref IPen? pen, - IBrush? brush, - double thickness, - IList? strokeDashArray = null, - double strokeDaskOffset = default, - PenLineCap lineCap = PenLineCap.Flat, - PenLineJoin lineJoin = PenLineJoin.Miter, - double miterLimit = 10.0) - { - var previousPen = pen; - if (brush is null) { - pen = null; - return previousPen is not null; - } + IBrush? brush, + double thickness, + IList? strokeDashArray = null, + double strokeDaskOffset = default, + PenLineCap lineCap = PenLineCap.Flat, + PenLineJoin lineJoin = PenLineJoin.Miter, + double miterLimit = 10.0) + { + var previousPen = pen; + if (brush is null) + { + pen = null; + return previousPen is not null; + } - IDashStyle? dashStyle = null; - if (strokeDashArray is { Count: > 0 }) { - // strokeDashArray can be IList (instead of AvaloniaList) in future - // So, if it supports notification - create a mutable DashStyle - dashStyle = strokeDashArray is INotifyCollectionChanged - ? new DashStyle(strokeDashArray, strokeDaskOffset) - : new ImmutableDashStyle(strokeDashArray, strokeDaskOffset); - } + IDashStyle? dashStyle = null; + if (strokeDashArray is { Count: > 0 }) - if (brush is IImmutableBrush immutableBrush && dashStyle is null or ImmutableDashStyle) { - pen = new ImmutablePen( - immutableBrush, - thickness, - (ImmutableDashStyle?)dashStyle, - lineCap, - lineJoin, - miterLimit); + // strokeDashArray can be IList (instead of AvaloniaList) in future + // So, if it supports notification - create a mutable DashStyle + dashStyle = strokeDashArray is INotifyCollectionChanged + ? new DashStyle(strokeDashArray, strokeDaskOffset) + : new ImmutableDashStyle(strokeDashArray, strokeDaskOffset); - return true; - } + if (brush is IImmutableBrush immutableBrush && dashStyle is null or ImmutableDashStyle) + { + pen = new ImmutablePen( + immutableBrush, + thickness, + (ImmutableDashStyle?)dashStyle, + lineCap, + lineJoin, + miterLimit); - var mutablePen = previousPen as Pen ?? new Pen(); - mutablePen.Brush = brush; - mutablePen.Thickness = thickness; - mutablePen.LineCap = lineCap; - mutablePen.LineJoin = lineJoin; - mutablePen.DashStyle = dashStyle; - mutablePen.MiterLimit = miterLimit; + return true; + } - pen = mutablePen; - return !Equals(previousPen, pen); - } + var mutablePen = previousPen as Pen ?? new Pen(); + mutablePen.Brush = brush; + mutablePen.Thickness = thickness; + mutablePen.LineCap = lineCap; + mutablePen.LineJoin = lineJoin; + mutablePen.DashStyle = dashStyle; + mutablePen.MiterLimit = miterLimit; + + pen = mutablePen; + return !Equals(previousPen, pen); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/PixelPointTransition.cs b/src/AtomUI.Base/Media/PixelPointTransition.cs index 4730c60..4057af9 100644 --- a/src/AtomUI.Base/Media/PixelPointTransition.cs +++ b/src/AtomUI.Base/Media/PixelPointTransition.cs @@ -5,10 +5,10 @@ namespace AtomUI.Media; public class PixelPointTransition : InterpolatingTransitionBase { - protected override PixelPoint Interpolate(double progress, PixelPoint oldValue, PixelPoint newValue) - { - var delta = newValue - oldValue; - return new PixelPoint((int)Math.Round(delta.X * progress + oldValue.X), - (int)Math.Round(delta.Y * progress + oldValue.Y)); - } + protected override PixelPoint Interpolate(double progress, PixelPoint oldValue, PixelPoint newValue) + { + var delta = newValue - oldValue; + return new PixelPoint((int)Math.Round(delta.X * progress + oldValue.X), + (int)Math.Round(delta.Y * progress + oldValue.Y)); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/SolidColorBrushTransition.cs b/src/AtomUI.Base/Media/SolidColorBrushTransition.cs index 967f138..64f2af8 100644 --- a/src/AtomUI.Base/Media/SolidColorBrushTransition.cs +++ b/src/AtomUI.Base/Media/SolidColorBrushTransition.cs @@ -6,23 +6,21 @@ namespace AtomUI.Media; public class SolidColorBrushTransition : InterpolatingTransitionBase { - protected override IBrush? Interpolate(double progress, IBrush? from, IBrush? to) - { - if (from is null || to is null) { - return progress >= 0.5 ? to : from; - } - - if (from is ISolidColorBrush fromBrush && to is ISolidColorBrush toBrush) { - return new ImmutableSolidColorBrush( - InterpolateUtils.ColorInterpolate(fromBrush.Color, toBrush.Color, progress), - DoubleInterpolate(progress, from.Opacity, to.Opacity)); - } - // TODO 不知道这样返回是否合适 - return from; - } + protected override IBrush? Interpolate(double progress, IBrush? from, IBrush? to) + { + if (from is null || to is null) return progress >= 0.5 ? to : from; - private double DoubleInterpolate(double progress, double oldValue, double newValue) - { - return ((newValue - oldValue) * progress) + oldValue; - } + if (from is ISolidColorBrush fromBrush && to is ISolidColorBrush toBrush) + return new ImmutableSolidColorBrush( + InterpolateUtils.ColorInterpolate(fromBrush.Color, toBrush.Color, progress), + DoubleInterpolate(progress, from.Opacity, to.Opacity)); + + // TODO 不知道这样返回是否合适 + return from; + } + + private double DoubleInterpolate(double progress, double oldValue, double newValue) + { + return (newValue - oldValue) * progress + oldValue; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Media/TextUtils.cs b/src/AtomUI.Base/Media/TextUtils.cs index 6d1dbff..4c6872b 100644 --- a/src/AtomUI.Base/Media/TextUtils.cs +++ b/src/AtomUI.Base/Media/TextUtils.cs @@ -6,14 +6,14 @@ namespace AtomUI.Media; public static class TextUtils { - public static Size CalculateTextSize(string text, - double fontSize, - FontFamily fontFamily, - FontStyle fontStyle = FontStyle.Normal, - FontWeight fontWeight = FontWeight.Normal) - { - var typeface = new Typeface(fontFamily, fontStyle, fontWeight); - using var textLayout = new TextLayout(text, typeface, fontSize, null); - return new Size(textLayout.Width, textLayout.Height); - } + public static Size CalculateTextSize(string text, + double fontSize, + FontFamily fontFamily, + FontStyle fontStyle = FontStyle.Normal, + FontWeight fontWeight = FontWeight.Normal) + { + var typeface = new Typeface(fontFamily, fontStyle, fontWeight); + using var textLayout = new TextLayout(text, typeface, fontSize, null); + return new Size(textLayout.Width, textLayout.Height); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/AbstractMotion.cs b/src/AtomUI.Base/MotionScene/AbstractMotion.cs index c37a370..a935c38 100644 --- a/src/AtomUI.Base/MotionScene/AbstractMotion.cs +++ b/src/AtomUI.Base/MotionScene/AbstractMotion.cs @@ -13,216 +13,230 @@ namespace AtomUI.MotionScene; public enum TransitionKind { - Double, - TransformOperations, + Double, + TransformOperations } + public record class MotionConfig { - public AvaloniaProperty Property { get; set; } - public object? StartValue { get; set; } - public object? EndValue { get; set; } - public Easing MotionEasing { get; set; } = new LinearEasing(); - public TimeSpan MotionDuration { get; set; } = TimeSpan.FromMilliseconds(300); - public TransitionKind TransitionKind { get; set; } + public MotionConfig(AvaloniaProperty targetProperty, object? startValue = null, object? endValue = null) + { + Property = targetProperty; + StartValue = startValue; + EndValue = endValue; + } - public MotionConfig(AvaloniaProperty targetProperty, object? startValue = null, object? endValue = null) - { - Property = targetProperty; - StartValue = startValue; - EndValue = endValue; - } + public AvaloniaProperty Property { get; set; } + public object? StartValue { get; set; } + public object? EndValue { get; set; } + public Easing MotionEasing { get; set; } = new LinearEasing(); + public TimeSpan MotionDuration { get; set; } = TimeSpan.FromMilliseconds(300); + public TransitionKind TransitionKind { get; set; } } + public abstract class AbstractMotion : AvaloniaObject, IMotion { - private bool _isRunning = false; - public bool IsRunning => _isRunning; + // 定义我们目前支持的动效属性 + public static readonly StyledProperty MotionOpacityProperty = + Visual.OpacityProperty.AddOwner(); - private Dictionary _motionConfigs; - private List _transitions; - public IObservable? CompletedObservable { get; private set; } + public static readonly StyledProperty MotionWidthProperty = + Layoutable.WidthProperty.AddOwner(); - // 定义我们目前支持的动效属性 - public static readonly StyledProperty MotionOpacityProperty = - Visual.OpacityProperty.AddOwner(); - - public static readonly StyledProperty MotionWidthProperty = - Layoutable.WidthProperty.AddOwner(); - - public static readonly StyledProperty MotionHeightProperty = - Layoutable.HeightProperty.AddOwner(); + public static readonly StyledProperty MotionHeightProperty = + Layoutable.HeightProperty.AddOwner(); - public static readonly StyledProperty MotionRenderTransformOriginProperty = - Visual.RenderTransformOriginProperty.AddOwner(); + public static readonly StyledProperty MotionRenderTransformOriginProperty = + Visual.RenderTransformOriginProperty.AddOwner(); - public static readonly StyledProperty MotionRenderTransformProperty = - Visual.RenderTransformProperty.AddOwner(); + public static readonly StyledProperty MotionRenderTransformProperty = + Visual.RenderTransformProperty.AddOwner(); - protected double MotionOpacity - { - get => GetValue(MotionOpacityProperty); - set => SetValue(MotionOpacityProperty, value); - } - - protected double MotionWidth - { - get => GetValue(MotionWidthProperty); - set => SetValue(MotionWidthProperty, value); - } + private readonly Dictionary _motionConfigs; + private readonly List _transitions; - protected double MotionHeight - { - get => GetValue(MotionHeightProperty); - set => SetValue(MotionHeightProperty, value); - } + public AbstractMotion() + { + _motionConfigs = new Dictionary(); + _transitions = new List(); + } - internal RelativePoint MotionRenderTransformOrigin - { - get => GetValue(MotionRenderTransformOriginProperty); - set => SetValue(MotionRenderTransformOriginProperty, value); - } - - protected ITransform? MotionRenderTransform - { - get => GetValue(MotionRenderTransformProperty); - set => SetValue(MotionRenderTransformProperty, value); - } - - public AbstractMotion() - { - _motionConfigs = new Dictionary(); - _transitions = new List(); - } + protected double MotionOpacity + { + get => GetValue(MotionOpacityProperty); + set => SetValue(MotionOpacityProperty, value); + } - /// - /// 创建动效动画对象 - /// - /// - /// - internal List BuildTransitions(Control motionTarget) - { - foreach (var entry in _motionConfigs) { - var config = entry.Value; - NotifyPreBuildTransition(config, motionTarget); - var transition = NotifyBuildTransition(config); - _transitions.Add(transition); - - } - var completedObservables = new IObservable[_transitions.Count]; - for (int i = 0; i < _transitions.Count; ++i) { - var transition = _transitions[i]; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) { - completedObservables[i] = (notifyTransitionCompleted.CompletedObservable); - } - } - - CompletedObservable = Observable.CombineLatest(completedObservables).Select(list => - { - return list.All(v=> v); - }); - return _transitions; - } + protected double MotionWidth + { + get => GetValue(MotionWidthProperty); + set => SetValue(MotionWidthProperty, value); + } - // 生命周期接口 - internal virtual void NotifyPreStart() {} - internal virtual void NotifyStarted() {} - internal virtual void NotifyCompleted() {} + protected double MotionHeight + { + get => GetValue(MotionHeightProperty); + set => SetValue(MotionHeightProperty, value); + } - internal virtual void NotifyConfigMotionTarget(Control motionTarget) {} - internal virtual void NotifyRestoreMotionTarget(Control motionTarget) {} - - protected virtual void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) {} - protected virtual ITransition NotifyBuildTransition(MotionConfig config) - { - TransitionBase transition = default!; - if (config.TransitionKind == TransitionKind.Double) { - transition = new NotifiableDoubleTransition(); - } else if (config.TransitionKind == TransitionKind.TransformOperations) { - transition = new NotifiableTransformOperationsTransition(); - } + internal RelativePoint MotionRenderTransformOrigin + { + get => GetValue(MotionRenderTransformOriginProperty); + set => SetValue(MotionRenderTransformOriginProperty, value); + } - transition.Property = config.Property; - transition.Duration = config.MotionDuration; - transition.Easing = config.MotionEasing; - return transition; - } + protected ITransform? MotionRenderTransform + { + get => GetValue(MotionRenderTransformProperty); + set => SetValue(MotionRenderTransformProperty, value); + } - protected MotionConfig? GetMotionConfig(AvaloniaProperty property) - { - if (_motionConfigs.TryGetValue(property, out var motionConfig)) { - return motionConfig; - } - return null; - } + public bool IsRunning { get; } = false; - protected void AddMotionConfig(MotionConfig config) - { - Debug.Assert(!_motionConfigs.ContainsKey(config.Property)); - _motionConfigs.Add(config.Property, config); - } + public IObservable? CompletedObservable { get; private set; } - /// - /// 计算顶层动画渲染层的大小 - /// - /// - /// 动画目标控件的大小,如果动画直接调度到控件本身,则是控件本身的大小,如果是顶层动画渲染,那么就是 ghost - /// 的大小,如果有阴影这个大小包含阴影的 thickness - /// 目前的实现没有加一个固定的 Padding - /// - /// - internal virtual Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize; - } + public IList GetActivatedProperties() + { + return _motionConfigs.Keys.ToList(); + } - /// - /// 计算动画层的全局坐标 - /// - /// 动画目标控件的大小,包含阴影 - /// 动画目标控件的最终全局坐标位置 - /// - internal virtual Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition; - } + public IList GetMotionConfigs() + { + return _motionConfigs.Values.ToList(); + } - public IList GetActivatedProperties() - { - return _motionConfigs.Keys.ToList(); - } + /// + /// 创建动效动画对象 + /// + /// + /// + internal List BuildTransitions(Control motionTarget) + { + foreach (var entry in _motionConfigs) + { + var config = entry.Value; + NotifyPreBuildTransition(config, motionTarget); + var transition = NotifyBuildTransition(config); + _transitions.Add(transition); + } - public IList GetMotionConfigs() - { - return _motionConfigs.Values.ToList(); - } + var completedObservables = new IObservable[_transitions.Count]; + for (var i = 0; i < _transitions.Count; ++i) + { + var transition = _transitions[i]; + if (transition is INotifyTransitionCompleted notifyTransitionCompleted) + completedObservables[i] = notifyTransitionCompleted.CompletedObservable; + } - protected TransformOperations BuildScaleTransform(double scaleX, double scaleY) - { - var builder = new TransformOperations.Builder(1); - builder.AppendScale(scaleX, scaleY); - return builder.Build(); - } - - protected TransformOperations BuildScaleTransform(double scale) - { - return BuildScaleTransform(scale, scale); - } - - protected TransformOperations BuildScaleXTransform(double scale) - { - return BuildScaleTransform(scale, 1.0); - } - - protected TransformOperations BuildScaleYTransform(double scale) - { - return BuildScaleTransform(1.0, scale); - } + CompletedObservable = + Observable.CombineLatest(completedObservables).Select(list => { return list.All(v => v); }); + return _transitions; + } - protected TransformOperations BuildTranslateTransform(double offsetX, double offsetY) - { - var builder = new TransformOperations.Builder(1); - builder.AppendTranslate(offsetX, offsetY); - return builder.Build(); - } + // 生命周期接口 + internal virtual void NotifyPreStart() + { + } + + internal virtual void NotifyStarted() + { + } + + internal virtual void NotifyCompleted() + { + } + + internal virtual void NotifyConfigMotionTarget(Control motionTarget) + { + } + + internal virtual void NotifyRestoreMotionTarget(Control motionTarget) + { + } + + protected virtual void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + } + + protected virtual ITransition NotifyBuildTransition(MotionConfig config) + { + TransitionBase transition = default!; + if (config.TransitionKind == TransitionKind.Double) + transition = new NotifiableDoubleTransition(); + else if (config.TransitionKind == TransitionKind.TransformOperations) + transition = new NotifiableTransformOperationsTransition(); + + transition.Property = config.Property; + transition.Duration = config.MotionDuration; + transition.Easing = config.MotionEasing; + return transition; + } + + protected MotionConfig? GetMotionConfig(AvaloniaProperty property) + { + if (_motionConfigs.TryGetValue(property, out var motionConfig)) return motionConfig; + return null; + } + + protected void AddMotionConfig(MotionConfig config) + { + Debug.Assert(!_motionConfigs.ContainsKey(config.Property)); + _motionConfigs.Add(config.Property, config); + } + + /// + /// 计算顶层动画渲染层的大小 + /// + /// + /// 动画目标控件的大小,如果动画直接调度到控件本身,则是控件本身的大小,如果是顶层动画渲染,那么就是 ghost + /// 的大小,如果有阴影这个大小包含阴影的 thickness + /// 目前的实现没有加一个固定的 Padding + /// + /// + internal virtual Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize; + } + + /// + /// 计算动画层的全局坐标 + /// + /// 动画目标控件的大小,包含阴影 + /// 动画目标控件的最终全局坐标位置 + /// + internal virtual Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) + { + return motionTargetPosition; + } + + protected TransformOperations BuildScaleTransform(double scaleX, double scaleY) + { + var builder = new TransformOperations.Builder(1); + builder.AppendScale(scaleX, scaleY); + return builder.Build(); + } + + protected TransformOperations BuildScaleTransform(double scale) + { + return BuildScaleTransform(scale, scale); + } + + protected TransformOperations BuildScaleXTransform(double scale) + { + return BuildScaleTransform(scale, 1.0); + } + + protected TransformOperations BuildScaleYTransform(double scale) + { + return BuildScaleTransform(1.0, scale); + } + + protected TransformOperations BuildTranslateTransform(double offsetX, double offsetY) + { + var builder = new TransformOperations.Builder(1); + builder.AppendTranslate(offsetX, offsetY); + return builder.Build(); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/AnimationTargetPanel.cs b/src/AtomUI.Base/MotionScene/AnimationTargetPanel.cs index 353e0b3..bfbca73 100644 --- a/src/AtomUI.Base/MotionScene/AnimationTargetPanel.cs +++ b/src/AtomUI.Base/MotionScene/AnimationTargetPanel.cs @@ -5,16 +5,13 @@ namespace AtomUI.MotionScene; internal class AnimationTargetPanel : Panel { - public bool InAnimation { get; set; } + private Size _cacheMeasureSize; + public bool InAnimation { get; set; } - private Size _cacheMeasureSize = default; - - protected override Size MeasureOverride(Size availableSize) - { - if (InAnimation && _cacheMeasureSize != default) { - return _cacheMeasureSize; - } - _cacheMeasureSize = base.MeasureOverride(availableSize); - return _cacheMeasureSize; - } + protected override Size MeasureOverride(Size availableSize) + { + if (InAnimation && _cacheMeasureSize != default) return _cacheMeasureSize; + _cacheMeasureSize = base.MeasureOverride(availableSize); + return _cacheMeasureSize; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/CollapseMotion.cs b/src/AtomUI.Base/MotionScene/CollapseMotion.cs index ae840ca..3eeb50a 100644 --- a/src/AtomUI.Base/MotionScene/CollapseMotion.cs +++ b/src/AtomUI.Base/MotionScene/CollapseMotion.cs @@ -6,116 +6,119 @@ namespace AtomUI.MotionScene; public class CollapseMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); - - /// - /// 收起的方向,垂直还是水平方向 - /// - public Orientation Orientation { get; set; } = Orientation.Vertical; + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); - public void ConfigureHeight(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(Orientation == Orientation.Vertical - ? MotionHeightProperty - : MotionWidthProperty) - { - TransitionKind = TransitionKind.Double, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + /// + /// 收起的方向,垂直还是水平方向 + /// + public Orientation Orientation { get; set; } = Orientation.Vertical; - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureHeight(TimeSpan duration, Easing? easing = null) + { + easing ??= new CubicEaseInOut(); + var config = new MotionConfig(Orientation == Orientation.Vertical + ? MotionHeightProperty + : MotionWidthProperty) + { + TransitionKind = TransitionKind.Double, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionHeightProperty) { - if (!double.IsNaN(motionTarget.Height)) { - config.StartValue = Math.Ceiling(motionTarget.Height); - } else { - config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Height); - } - } else if (config.Property == MotionWidthProperty) { - if (!double.IsNaN(motionTarget.Width)) { - config.StartValue = Math.Ceiling(motionTarget.Width); - } else { - config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Width); - } - } - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CubicEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionHeightProperty) + { + if (!double.IsNaN(motionTarget.Height)) + config.StartValue = Math.Ceiling(motionTarget.Height); + else + config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Height); + } + else if (config.Property == MotionWidthProperty) + { + if (!double.IsNaN(motionTarget.Width)) + config.StartValue = Math.Ceiling(motionTarget.Width); + else + config.StartValue = Math.Ceiling(motionTarget.DesiredSize.Width); + } + } } + public class ExpandMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? HeightConfig => GetMotionConfig(MotionHeightProperty); - /// - /// 展开的方向,垂直还是水平方向 - /// - public Orientation Orientation { get; set; } = Orientation.Vertical; - - public void ConfigureHeight(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(Orientation == Orientation.Vertical - ? MotionHeightProperty - : MotionWidthProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + /// + /// 展开的方向,垂直还是水平方向 + /// + public Orientation Orientation { get; set; } = Orientation.Vertical; - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CubicEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionHeightProperty) { - if (!double.IsNaN(motionTarget.Height)) { - config.EndValue = Math.Ceiling(motionTarget.Height); - } else { - config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Height); - } - } else if (config.Property == MotionWidthProperty) { - if (!double.IsNaN(motionTarget.Width)) { - config.EndValue = Math.Ceiling(motionTarget.Width); - } else { - config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Width); - } - } - } + public void ConfigureHeight(TimeSpan duration, Easing? easing = null) + { + easing ??= new CubicEaseInOut(); + var config = new MotionConfig(Orientation == Orientation.Vertical + ? MotionHeightProperty + : MotionWidthProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CubicEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionHeightProperty) + { + if (!double.IsNaN(motionTarget.Height)) + config.EndValue = Math.Ceiling(motionTarget.Height); + else + config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Height); + } + else if (config.Property == MotionWidthProperty) + { + if (!double.IsNaN(motionTarget.Width)) + config.EndValue = Math.Ceiling(motionTarget.Width); + else + config.EndValue = Math.Ceiling(motionTarget.DesiredSize.Width); + } + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/Director.cs b/src/AtomUI.Base/MotionScene/Director.cs index ea2b82d..834b3a6 100644 --- a/src/AtomUI.Base/MotionScene/Director.cs +++ b/src/AtomUI.Base/MotionScene/Director.cs @@ -7,154 +7,151 @@ namespace AtomUI.Controls.MotionScene; public class Director : IDirector { - public event EventHandler? MotionPreStart; - public event EventHandler? MotionStarted; - public event EventHandler? MotionCompleted; - - public static IDirector? Instance => AvaloniaLocator.Current.GetService(); - private Dictionary _states; - private CompositeDisposable? _compositeDisposable; - - public Director() - { - _states = new Dictionary(); - } - - /// - /// 目前的实现暂时一个 Actor 只能投递一次,后面可以实现一个等待队列 - /// - /// - public void Schedule(MotionActor actor) - { - if (_states.ContainsKey(actor)) { - return; - } - actor.NotifyPostedToDirector(); - SceneLayer? sceneLayer = default; - if (actor.DispatchInSceneLayer) { - sceneLayer = PrepareSceneLayer(actor); - } - _compositeDisposable = new CompositeDisposable(); - _compositeDisposable.Add(Disposable.Create((sceneLayer), state => - { - if (sceneLayer is not null) { - Dispatcher.UIThread.InvokeAsync(async () => - { - await Task.Delay(300); - sceneLayer.Hide(); - sceneLayer.Dispose(); - }); - } - })); - var state = new MotionActorState(actor, _compositeDisposable); - _states.Add(actor, state); + private CompositeDisposable? _compositeDisposable; + private readonly Dictionary _states; - if (actor.DispatchInSceneLayer) { - state.SceneLayer = sceneLayer; - var ghost = actor.GetAnimatableGhost(); - sceneLayer!.SetMotionTarget(ghost); - actor.NotifyMotionTargetAddedToScene(ghost); - sceneLayer.Show(); - sceneLayer.Topmost = true; - actor.NotifySceneShowed(); - } - HandleMotionPreStart(actor); - ExecuteMotionAction(actor); - HandleMotionStarted(actor); - } + public Director() + { + _states = new Dictionary(); + } - private SceneLayer PrepareSceneLayer(MotionActor actor) - { - if (actor.SceneParent is null) { - throw new ArgumentException("When the DispatchInSceneLayer property is true, the SceneParent property cannot be null."); - } - // TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类 - // 暂时先处理 Popup 这种情况 - var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!); - actor.NotifySceneLayerCreated(sceneLayer); - return sceneLayer; - } + public static IDirector? Instance => AvaloniaLocator.Current.GetService(); - private void ExecuteMotionAction(MotionActor actor) - { - // 根据 Motion 配置的对 Actor 对象的属性赋值 - actor.EnableMotion(); - foreach (var motionConfig in actor.Motion.GetMotionConfigs()) { - var property = motionConfig.Property; - var endValue = motionConfig.EndValue; - actor.SetValue(property, endValue); - } - } + /// + /// 目前的实现暂时一个 Actor 只能投递一次,后面可以实现一个等待队列 + /// + /// + public void Schedule(MotionActor actor) + { + if (_states.ContainsKey(actor)) return; + actor.NotifyPostedToDirector(); + SceneLayer? sceneLayer = default; + if (actor.DispatchInSceneLayer) sceneLayer = PrepareSceneLayer(actor); + _compositeDisposable = new CompositeDisposable(); + _compositeDisposable.Add(Disposable.Create(sceneLayer, state => + { + if (sceneLayer is not null) + Dispatcher.UIThread.InvokeAsync(async () => + { + await Task.Delay(300); + sceneLayer.Hide(); + sceneLayer.Dispose(); + }); + })); + var state = new MotionActorState(actor, _compositeDisposable); + _states.Add(actor, state); - private class MotionActorState : IDisposable - { - private readonly IDisposable _cleanup; - - public IMotionActor MotionActor { get; } - public SceneLayer? SceneLayer; + if (actor.DispatchInSceneLayer) + { + state.SceneLayer = sceneLayer; + var ghost = actor.GetAnimatableGhost(); + sceneLayer!.SetMotionTarget(ghost); + actor.NotifyMotionTargetAddedToScene(ghost); + sceneLayer.Show(); + sceneLayer.Topmost = true; + actor.NotifySceneShowed(); + } - public MotionActorState(IMotionActor motionActor, IDisposable cleanup) - { - MotionActor = motionActor; - _cleanup = cleanup; - } - - public void Dispose() - { - _cleanup.Dispose(); - } - } + HandleMotionPreStart(actor); + ExecuteMotionAction(actor); + HandleMotionStarted(actor); + } - private void HandleMotionPreStart(MotionActor actor) - { - actor.NotifyMotionPreStart(); - MotionPreStart?.Invoke(this, new MotionEventArgs(actor)); - if (actor.Motion.CompletedObservable is null) { - throw new InvalidOperationException("The CompletedObservable property of the Motion is empty."); - } - // 设置相关的完成检测 - _compositeDisposable?.Add(actor.Motion.CompletedObservable.Subscribe(status => - { - actor.CompletedStatus = status; - }, onCompleted: () => - { - HandleMotionCompleted(actor); - })); - - // 设置动画对象初始值 - foreach (var motionConfig in actor.Motion.GetMotionConfigs()) { - var property = motionConfig.Property; - var startValue = motionConfig.StartValue; - actor.SetValue(property, startValue); - } - } + public event EventHandler? MotionPreStart; + public event EventHandler? MotionStarted; + public event EventHandler? MotionCompleted; - private void HandleMotionStarted(MotionActor actor) - { - actor.NotifyMotionStarted(); - MotionStarted?.Invoke(this, new MotionEventArgs(actor)); - } + private SceneLayer PrepareSceneLayer(MotionActor actor) + { + if (actor.SceneParent is null) + throw new ArgumentException( + "When the DispatchInSceneLayer property is true, the SceneParent property cannot be null."); - private void HandleMotionCompleted(MotionActor actor) - { - if (_states.TryGetValue(actor, out var state)) { - if (state.SceneLayer is not null) { - state.SceneLayer.Opacity = 0; - } - actor.NotifyMotionCompleted(); - MotionCompleted?.Invoke(this, new MotionEventArgs(actor)); - state.Dispose(); - _states.Remove(actor); - } - } + // TODO 这里除了 Popup 这种顶层元素以外,还会不会有其他的顶层元素种类 + // 暂时先处理 Popup 这种情况 + var sceneLayer = new SceneLayer(actor.SceneParent, actor.SceneParent.PlatformImpl!.CreatePopup()!); + actor.NotifySceneLayerCreated(sceneLayer); + return sceneLayer; + } + + private void ExecuteMotionAction(MotionActor actor) + { + // 根据 Motion 配置的对 Actor 对象的属性赋值 + actor.EnableMotion(); + foreach (var motionConfig in actor.Motion.GetMotionConfigs()) + { + var property = motionConfig.Property; + var endValue = motionConfig.EndValue; + actor.SetValue(property, endValue); + } + } + + private void HandleMotionPreStart(MotionActor actor) + { + actor.NotifyMotionPreStart(); + MotionPreStart?.Invoke(this, new MotionEventArgs(actor)); + if (actor.Motion.CompletedObservable is null) + throw new InvalidOperationException("The CompletedObservable property of the Motion is empty."); + + // 设置相关的完成检测 + _compositeDisposable?.Add(actor.Motion.CompletedObservable.Subscribe( + status => { actor.CompletedStatus = status; }, () => { HandleMotionCompleted(actor); })); + + // 设置动画对象初始值 + foreach (var motionConfig in actor.Motion.GetMotionConfigs()) + { + var property = motionConfig.Property; + var startValue = motionConfig.StartValue; + actor.SetValue(property, startValue); + } + } + + private void HandleMotionStarted(MotionActor actor) + { + actor.NotifyMotionStarted(); + MotionStarted?.Invoke(this, new MotionEventArgs(actor)); + } + + private void HandleMotionCompleted(MotionActor actor) + { + if (_states.TryGetValue(actor, out var state)) + { + if (state.SceneLayer is not null) state.SceneLayer.Opacity = 0; + actor.NotifyMotionCompleted(); + MotionCompleted?.Invoke(this, new MotionEventArgs(actor)); + state.Dispose(); + _states.Remove(actor); + } + } + + + private class MotionActorState : IDisposable + { + private readonly IDisposable _cleanup; + public SceneLayer? SceneLayer; + + public MotionActorState(IMotionActor motionActor, IDisposable cleanup) + { + MotionActor = motionActor; + _cleanup = cleanup; + } + + public IMotionActor MotionActor { get; } + + public void Dispose() + { + _cleanup.Dispose(); + } + } } + public class MotionEventArgs : EventArgs { - public MotionActor MotionActor; - - public MotionEventArgs(MotionActor motionActor) - { - MotionActor = motionActor; - } + public MotionActor MotionActor; + + public MotionEventArgs(MotionActor motionActor) + { + MotionActor = motionActor; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/FadeMotion.cs b/src/AtomUI.Base/MotionScene/FadeMotion.cs index 13b1db6..002e624 100644 --- a/src/AtomUI.Base/MotionScene/FadeMotion.cs +++ b/src/AtomUI.Base/MotionScene/FadeMotion.cs @@ -4,39 +4,41 @@ namespace AtomUI.MotionScene; public class FadeInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) - { - easing ??= new LinearEasing(); - originOpacity = Math.Clamp(originOpacity, 0d, 1d); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = originOpacity, - EndValue = 1.0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + + public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) + { + easing ??= new LinearEasing(); + originOpacity = Math.Clamp(originOpacity, 0d, 1d); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = originOpacity, + EndValue = 1.0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class FadeOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - - public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) - { - easing ??= new LinearEasing(); - originOpacity = Math.Clamp(originOpacity, 0d, 1d); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = originOpacity, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + + public void ConfigureOpacity(double originOpacity, TimeSpan duration, Easing? easing = null) + { + easing ??= new LinearEasing(); + originOpacity = Math.Clamp(originOpacity, 0d, 1d); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = originOpacity, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IDirector.cs b/src/AtomUI.Base/MotionScene/IDirector.cs index 1026bc2..001fcfe 100644 --- a/src/AtomUI.Base/MotionScene/IDirector.cs +++ b/src/AtomUI.Base/MotionScene/IDirector.cs @@ -2,5 +2,5 @@ public interface IDirector { - public void Schedule(MotionActor actor); + public void Schedule(MotionActor actor); } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IMotion.cs b/src/AtomUI.Base/MotionScene/IMotion.cs index bdddcf3..f2c99b9 100644 --- a/src/AtomUI.Base/MotionScene/IMotion.cs +++ b/src/AtomUI.Base/MotionScene/IMotion.cs @@ -4,13 +4,14 @@ namespace AtomUI.MotionScene; public interface IMotion { - public bool IsRunning { get; } + public bool IsRunning { get; } + public IObservable? CompletedObservable { get; } - /// - /// 获取当前动效激活的动画属性列表 - /// - /// - public IList GetActivatedProperties(); - public IList GetMotionConfigs(); - public IObservable? CompletedObservable { get; } + /// + /// 获取当前动效激活的动画属性列表 + /// + /// + public IList GetActivatedProperties(); + + public IList GetMotionConfigs(); } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/IMotionActor.cs b/src/AtomUI.Base/MotionScene/IMotionActor.cs index 6996e09..b8d4ccb 100644 --- a/src/AtomUI.Base/MotionScene/IMotionActor.cs +++ b/src/AtomUI.Base/MotionScene/IMotionActor.cs @@ -4,13 +4,12 @@ namespace AtomUI.MotionScene; internal interface IMotionActor { - public event EventHandler? PreStart; - public event EventHandler? Started; - public event EventHandler? Completed; - - public bool CompletedStatus { get; } - - public Control MotionTarget { get; set; } - public IMotion Motion { get; } - public bool DispatchInSceneLayer { get; set; } + public bool CompletedStatus { get; } + + public Control MotionTarget { get; set; } + public IMotion Motion { get; } + public bool DispatchInSceneLayer { get; set; } + public event EventHandler? PreStart; + public event EventHandler? Started; + public event EventHandler? Completed; } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs b/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs index 1be4f13..3477e1b 100644 --- a/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs +++ b/src/AtomUI.Base/MotionScene/INotifyCaptureGhostBitmap.cs @@ -2,5 +2,5 @@ internal interface INotifyCaptureGhostBitmap { - public void NotifyCaptureGhostBitmap(); + public void NotifyCaptureGhostBitmap(); } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionActor.cs b/src/AtomUI.Base/MotionScene/MotionActor.cs index 01dab88..e1b45b3 100644 --- a/src/AtomUI.Base/MotionScene/MotionActor.cs +++ b/src/AtomUI.Base/MotionScene/MotionActor.cs @@ -12,344 +12,361 @@ using Avalonia.VisualTree; namespace AtomUI.MotionScene; /// -/// 动效配置类,只要给 Director 提供动效相关信息 -/// 动效驱动 Actor 的属性,然后由 Actor 驱动动画控件,防止污染动画控件的 Transitions 配置 +/// 动效配置类,只要给 Director 提供动效相关信息 +/// 动效驱动 Actor 的属性,然后由 Actor 驱动动画控件,防止污染动画控件的 Transitions 配置 /// public class MotionActor : Animatable, IMotionActor { - public event EventHandler? PreStart; - public event EventHandler? Started; - public event EventHandler? Completed; - public event EventHandler? SceneShowed; - - public static readonly StyledProperty MotionOpacityProperty = - Visual.OpacityProperty.AddOwner(); - - public static readonly StyledProperty MotionWidthProperty = - Layoutable.WidthProperty.AddOwner(); - - public static readonly StyledProperty MotionHeightProperty = - Layoutable.HeightProperty.AddOwner(); + public static readonly StyledProperty MotionOpacityProperty = + Visual.OpacityProperty.AddOwner(); - public static readonly StyledProperty MotionRenderTransformProperty = - Visual.RenderTransformProperty.AddOwner(); + public static readonly StyledProperty MotionWidthProperty = + Layoutable.WidthProperty.AddOwner(); - private static readonly MethodInfo EnableTransitionsMethodInfo; - private static readonly MethodInfo DisableTransitionsMethodInfo; + public static readonly StyledProperty MotionHeightProperty = + Layoutable.HeightProperty.AddOwner(); - public bool CompletedStatus { get; internal set; } = true; - - protected double MotionOpacity - { - get => GetValue(MotionOpacityProperty); - set => SetValue(MotionOpacityProperty, value); - } - - protected double MotionWidth - { - get => GetValue(MotionWidthProperty); - set => SetValue(MotionWidthProperty, value); - } + public static readonly StyledProperty MotionRenderTransformProperty = + Visual.RenderTransformProperty.AddOwner(); - protected double MotionHeight - { - get => GetValue(MotionHeightProperty); - set => SetValue(MotionHeightProperty, value); - } + private static readonly MethodInfo EnableTransitionsMethodInfo; + private static readonly MethodInfo DisableTransitionsMethodInfo; - protected ITransform? MotionRenderTransform - { - get => GetValue(MotionRenderTransformProperty); - set => SetValue(MotionRenderTransformProperty, value); - } + protected Control? _ghost; + protected AbstractMotion _motion; + private double _originHeight; - private double _originOpacity; - private double _originWidth; - private double _originHeight; - private ITransform? _originRenderTransform; - private RelativePoint _originRenderTransformOrigin; - private Dictionary _transitionsMap; + private double _originOpacity; + private ITransform? _originRenderTransform; + private RelativePoint _originRenderTransformOrigin; + private double _originWidth; + private readonly Dictionary _transitionsMap; - private class AnimationState - { - public ITransition? Transition { get; set; } - public object? StartValue { get; set; } - public object? EndValue { get; set; } - } - - /// - /// 动画实体 - /// - public Control MotionTarget { get; set; } - - /// - /// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup - /// - public TopLevel? SceneParent { get; set; } + static MotionActor() + { + EnableTransitionsMethodInfo = + typeof(Animatable).GetMethod("EnableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!; + DisableTransitionsMethodInfo = + typeof(Animatable).GetMethod("DisableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!; + MotionWidthProperty.Changed.AddClassHandler(HandlePropertyChanged); + MotionHeightProperty.Changed.AddClassHandler(HandlePropertyChanged); + MotionOpacityProperty.Changed.AddClassHandler(HandlePropertyChanged); + MotionRenderTransformProperty.Changed.AddClassHandler(HandlePropertyChanged); + } - public IMotion Motion => _motion; - public bool DispatchInSceneLayer { get; set; } = true; - - protected Control? _ghost; - protected AbstractMotion _motion; + public MotionActor(Control motionTarget, AbstractMotion motion) + { + MotionTarget = motionTarget; + _motion = motion; + _transitionsMap = new Dictionary(); + } - static MotionActor() - { - EnableTransitionsMethodInfo = typeof(Animatable).GetMethod("EnableTransitions",BindingFlags.Instance | BindingFlags.NonPublic)!; - DisableTransitionsMethodInfo = - typeof(Animatable).GetMethod("DisableTransitions", BindingFlags.Instance | BindingFlags.NonPublic)!; - MotionWidthProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionHeightProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionOpacityProperty.Changed.AddClassHandler(HandlePropertyChanged); - MotionRenderTransformProperty.Changed.AddClassHandler(HandlePropertyChanged); - } + protected double MotionOpacity + { + get => GetValue(MotionOpacityProperty); + set => SetValue(MotionOpacityProperty, value); + } - private static void HandlePropertyChanged(MotionActor actor, AvaloniaPropertyChangedEventArgs args) - { - var property = args.Property; - var oldValue = args.OldValue; - var newValue = args.NewValue; - var priority = args.Priority; - if (!actor._transitionsMap.ContainsKey(property)) { - return; - } - var state = actor._transitionsMap[property]; - if (actor.IsAnimating(property) && priority == BindingPriority.Animation) { - // 判断新值是否相等 - if (property.PropertyType == typeof(double)) { - var currentValue = (double)newValue!; - var endValue = (double)state.EndValue!; - if (MathUtils.AreClose(currentValue, endValue)) { - var transition = state.Transition; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) { - notifyTransitionCompleted.NotifyTransitionCompleted(true); - } - } - } else if (property.PropertyType.IsAssignableTo(typeof(ITransform))) { - var currentValue = (ITransform)newValue!; - var endValue = (ITransform)state.EndValue!; - if (currentValue.Value == endValue.Value) { - var transition = state.Transition; - if (transition is INotifyTransitionCompleted notifyTransitionCompleted) { - notifyTransitionCompleted.NotifyTransitionCompleted(true); - } - } - } - } - } + protected double MotionWidth + { + get => GetValue(MotionWidthProperty); + set => SetValue(MotionWidthProperty, value); + } - public MotionActor(Control motionTarget, AbstractMotion motion) - { - MotionTarget = motionTarget; - _motion = motion; - _transitionsMap = new Dictionary(); - } - - public bool IsSupportMotionProperty(AvaloniaProperty property) - { - if (property == AbstractMotion.MotionOpacityProperty || - property == AbstractMotion.MotionWidthProperty || - property == AbstractMotion.MotionHeightProperty || - property == AbstractMotion.MotionRenderTransformProperty) { - return true; - } - return false; - } - - protected virtual void BuildGhost() {} - - public Control GetAnimatableGhost() - { - return _ghost ?? MotionTarget; - } + protected double MotionHeight + { + get => GetValue(MotionHeightProperty); + set => SetValue(MotionHeightProperty, value); + } - /// - /// 当在 DispatchInSceneLayer 渲染的时候,Ghost 的全局坐标 - /// - /// - public Point CalculateGhostPosition() - { - Point point = default; - if (!DispatchInSceneLayer) { - var visualParent = MotionTarget.GetVisualParent(); - if (visualParent is not null) { - var parentPoint = MotionTarget.TranslatePoint(new Point(0, 0), visualParent); - if (parentPoint.HasValue) { - point = parentPoint.Value; - } else { - point = MotionTarget.Bounds.Position; - } - } - } else { - point = CalculateTopLevelGhostPosition(); - } - return point; - } + protected ITransform? MotionRenderTransform + { + get => GetValue(MotionRenderTransformProperty); + set => SetValue(MotionRenderTransformProperty, value); + } - protected virtual Point CalculateTopLevelGhostPosition() - { - return default; - } + /// + /// 当 DispatchInSceneLayer 为 true 的时候,必须指定一个动画 SceneLayer 的父窗口,最好不要是 Popup + /// + public TopLevel? SceneParent { get; set; } - /// - /// 在这个接口中,Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小 - /// - /// - public virtual void NotifySceneLayerCreated(SceneLayer sceneLayer) - { - if (!DispatchInSceneLayer) { - return; - } + public event EventHandler? PreStart; + public event EventHandler? Started; + public event EventHandler? Completed; - var ghost = GetAnimatableGhost(); - - Size motionTargetSize; - // Popup.Child can't be null here, it was set in ShowAtCore. - if (ghost.DesiredSize == default) { - // Popup may not have been shown yet. Measure content - motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness()); - } else { - motionTargetSize = ghost.DesiredSize; - } + public bool CompletedStatus { get; internal set; } = true; - var sceneSize = _motion.CalculateSceneSize(motionTargetSize); - var scenePosition = _motion.CalculateScenePosition(motionTargetSize, CalculateGhostPosition()); - sceneLayer.MoveAndResize(scenePosition, sceneSize); - } + /// + /// 动画实体 + /// + public Control MotionTarget { get; set; } - public virtual void NotifyPostedToDirector() - { - DisableMotion(); - BuildGhost(); - RelayMotionProperties(); - var transitions = new Transitions(); - foreach (var transition in _motion.BuildTransitions(GetAnimatableGhost())) { - transitions.Add(transition); - } - Transitions = transitions; - } + public IMotion Motion => _motion; + public bool DispatchInSceneLayer { get; set; } = true; + public event EventHandler? SceneShowed; - protected void RelayMotionProperties() - { - // var ghost = GetAnimatableGhost(); - // // TODO 这个看是否需要管理起来 - // - // var motionProperties = Motion.GetActivatedProperties(); - // foreach (var property in motionProperties) { - // BindUtils.RelayBind(this, property, ghost, property); - // } - } - - /// - /// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小 - /// - /// - public virtual void NotifyMotionTargetAddedToScene(Control motionTarget) - { - Canvas.SetLeft(motionTarget, 0); - Canvas.SetTop(motionTarget, 0); - } - - public virtual void NotifySceneShowed() - { - SceneShowed?.Invoke(this, EventArgs.Empty); - } - - internal void EnableMotion() - { - EnableTransitionsMethodInfo.Invoke(this, new object[]{}); - } - - internal void DisableMotion() - { - DisableTransitionsMethodInfo.Invoke(this, new object[]{}); - } - - internal virtual void NotifyMotionPreStart() - { - if (Transitions is not null) { - foreach (var transition in Transitions) { - _transitionsMap.Add(transition.Property, new AnimationState() + private static void HandlePropertyChanged(MotionActor actor, AvaloniaPropertyChangedEventArgs args) + { + var property = args.Property; + var oldValue = args.OldValue; + var newValue = args.NewValue; + var priority = args.Priority; + if (!actor._transitionsMap.ContainsKey(property)) return; + var state = actor._transitionsMap[property]; + if (actor.IsAnimating(property) && priority == BindingPriority.Animation) + { + // 判断新值是否相等 + if (property.PropertyType == typeof(double)) { - Transition = transition - }); - } - } - - foreach (var motionConfig in _motion.GetMotionConfigs()) { - var property = motionConfig.Property; - var state = _transitionsMap[property]; - state.StartValue = motionConfig.StartValue; - state.EndValue = motionConfig.EndValue; - } - - SaveMotionTargetState(); - _motion.NotifyPreStart(); - _motion.NotifyConfigMotionTarget(GetAnimatableGhost()); - PreStart?.Invoke(this, EventArgs.Empty); - } - - internal virtual void NotifyMotionStarted() - { - _motion.NotifyStarted(); - Started?.Invoke(this, EventArgs.Empty); - } - - internal virtual void NotifyMotionCompleted() - { - RestoreMotionTargetState(); - Completed?.Invoke(this, EventArgs.Empty); - _motion.NotifyCompleted(); - _motion.NotifyRestoreMotionTarget(GetAnimatableGhost()); - _transitionsMap.Clear(); - } - - private void SaveMotionTargetState() - { - var target = GetAnimatableGhost(); - foreach (var motionConfig in _motion.GetMotionConfigs()) { - if (motionConfig.Property == MotionHeightProperty) { - _originHeight = target.Height; - } else if (motionConfig.Property == MotionWidthProperty) { - _originWidth = target.Width; - } else if (motionConfig.Property == MotionOpacityProperty) { - _originOpacity = target.Opacity; - } else if (motionConfig.Property == MotionRenderTransformProperty) { - _originRenderTransform = target.RenderTransform; - _originRenderTransformOrigin = target.RenderTransformOrigin; - } - } - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - if (change.Property == MotionWidthProperty || - change.Property == MotionHeightProperty || - change.Property == MotionOpacityProperty || - change.Property == MotionRenderTransformProperty) { - var ghost = GetAnimatableGhost(); - ghost.SetCurrentValue(change.Property, change.NewValue); - } - } - - private void RestoreMotionTargetState() - { - var target = GetAnimatableGhost(); - if (target == MotionTarget) { - foreach (var motionConfig in _motion.GetMotionConfigs()) { - if (motionConfig.Property == MotionHeightProperty) { - target.SetValue(MotionHeightProperty, _originHeight); - } else if (motionConfig.Property == MotionWidthProperty) { - target.SetValue(MotionWidthProperty, _originWidth); - } else if (motionConfig.Property == MotionOpacityProperty) { - target.SetValue(MotionOpacityProperty, _originOpacity); - } else if (motionConfig.Property == MotionRenderTransformProperty) { - target.SetValue(MotionRenderTransformProperty, _originRenderTransform); - target.SetValue(MotionRenderTransformProperty, _originRenderTransform); - target.SetValue(Visual.RenderTransformOriginProperty, _originRenderTransformOrigin); + var currentValue = (double)newValue!; + var endValue = (double)state.EndValue!; + if (MathUtils.AreClose(currentValue, endValue)) + { + var transition = state.Transition; + if (transition is INotifyTransitionCompleted notifyTransitionCompleted) + notifyTransitionCompleted.NotifyTransitionCompleted(true); + } } - } - } - } + else if (property.PropertyType.IsAssignableTo(typeof(ITransform))) + { + var currentValue = (ITransform)newValue!; + var endValue = (ITransform)state.EndValue!; + if (currentValue.Value == endValue.Value) + { + var transition = state.Transition; + if (transition is INotifyTransitionCompleted notifyTransitionCompleted) + notifyTransitionCompleted.NotifyTransitionCompleted(true); + } + } + } + } + + public bool IsSupportMotionProperty(AvaloniaProperty property) + { + if (property == AbstractMotion.MotionOpacityProperty || + property == AbstractMotion.MotionWidthProperty || + property == AbstractMotion.MotionHeightProperty || + property == AbstractMotion.MotionRenderTransformProperty) + return true; + return false; + } + + protected virtual void BuildGhost() + { + } + + public Control GetAnimatableGhost() + { + return _ghost ?? MotionTarget; + } + + /// + /// 当在 DispatchInSceneLayer 渲染的时候,Ghost 的全局坐标 + /// + /// + public Point CalculateGhostPosition() + { + Point point = default; + if (!DispatchInSceneLayer) + { + var visualParent = MotionTarget.GetVisualParent(); + if (visualParent is not null) + { + var parentPoint = MotionTarget.TranslatePoint(new Point(0, 0), visualParent); + if (parentPoint.HasValue) + point = parentPoint.Value; + else + point = MotionTarget.Bounds.Position; + } + } + else + { + point = CalculateTopLevelGhostPosition(); + } + + return point; + } + + protected virtual Point CalculateTopLevelGhostPosition() + { + return default; + } + + /// + /// 在这个接口中,Actor 根据自己的需求对 sceneLayer 进行设置,主要就是位置和大小 + /// + /// + public virtual void NotifySceneLayerCreated(SceneLayer sceneLayer) + { + if (!DispatchInSceneLayer) return; + + var ghost = GetAnimatableGhost(); + + Size motionTargetSize; + + // Popup.Child can't be null here, it was set in ShowAtCore. + if (ghost.DesiredSize == default) + + // Popup may not have been shown yet. Measure content + motionTargetSize = LayoutHelper.MeasureChild(ghost, Size.Infinity, new Thickness()); + else + motionTargetSize = ghost.DesiredSize; + + var sceneSize = _motion.CalculateSceneSize(motionTargetSize); + var scenePosition = _motion.CalculateScenePosition(motionTargetSize, CalculateGhostPosition()); + sceneLayer.MoveAndResize(scenePosition, sceneSize); + } + + public virtual void NotifyPostedToDirector() + { + DisableMotion(); + BuildGhost(); + RelayMotionProperties(); + var transitions = new Transitions(); + foreach (var transition in _motion.BuildTransitions(GetAnimatableGhost())) transitions.Add(transition); + Transitions = transitions; + } + + protected void RelayMotionProperties() + { + // var ghost = GetAnimatableGhost(); + // // TODO 这个看是否需要管理起来 + // + // var motionProperties = Motion.GetActivatedProperties(); + // foreach (var property in motionProperties) { + // BindUtils.RelayBind(this, property, ghost, property); + // } + } + + /// + /// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小 + /// + /// + public virtual void NotifyMotionTargetAddedToScene(Control motionTarget) + { + Canvas.SetLeft(motionTarget, 0); + Canvas.SetTop(motionTarget, 0); + } + + public virtual void NotifySceneShowed() + { + SceneShowed?.Invoke(this, EventArgs.Empty); + } + + internal void EnableMotion() + { + EnableTransitionsMethodInfo.Invoke(this, new object[] { }); + } + + internal void DisableMotion() + { + DisableTransitionsMethodInfo.Invoke(this, new object[] { }); + } + + internal virtual void NotifyMotionPreStart() + { + if (Transitions is not null) + foreach (var transition in Transitions) + _transitionsMap.Add(transition.Property, new AnimationState + { + Transition = transition + }); + + foreach (var motionConfig in _motion.GetMotionConfigs()) + { + var property = motionConfig.Property; + var state = _transitionsMap[property]; + state.StartValue = motionConfig.StartValue; + state.EndValue = motionConfig.EndValue; + } + + SaveMotionTargetState(); + _motion.NotifyPreStart(); + _motion.NotifyConfigMotionTarget(GetAnimatableGhost()); + PreStart?.Invoke(this, EventArgs.Empty); + } + + internal virtual void NotifyMotionStarted() + { + _motion.NotifyStarted(); + Started?.Invoke(this, EventArgs.Empty); + } + + internal virtual void NotifyMotionCompleted() + { + RestoreMotionTargetState(); + Completed?.Invoke(this, EventArgs.Empty); + _motion.NotifyCompleted(); + _motion.NotifyRestoreMotionTarget(GetAnimatableGhost()); + _transitionsMap.Clear(); + } + + private void SaveMotionTargetState() + { + var target = GetAnimatableGhost(); + foreach (var motionConfig in _motion.GetMotionConfigs()) + if (motionConfig.Property == MotionHeightProperty) + { + _originHeight = target.Height; + } + else if (motionConfig.Property == MotionWidthProperty) + { + _originWidth = target.Width; + } + else if (motionConfig.Property == MotionOpacityProperty) + { + _originOpacity = target.Opacity; + } + else if (motionConfig.Property == MotionRenderTransformProperty) + { + _originRenderTransform = target.RenderTransform; + _originRenderTransformOrigin = target.RenderTransformOrigin; + } + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property == MotionWidthProperty || + change.Property == MotionHeightProperty || + change.Property == MotionOpacityProperty || + change.Property == MotionRenderTransformProperty) + { + var ghost = GetAnimatableGhost(); + ghost.SetCurrentValue(change.Property, change.NewValue); + } + } + + private void RestoreMotionTargetState() + { + var target = GetAnimatableGhost(); + if (target == MotionTarget) + foreach (var motionConfig in _motion.GetMotionConfigs()) + if (motionConfig.Property == MotionHeightProperty) + { + target.SetValue(MotionHeightProperty, _originHeight); + } + else if (motionConfig.Property == MotionWidthProperty) + { + target.SetValue(MotionWidthProperty, _originWidth); + } + else if (motionConfig.Property == MotionOpacityProperty) + { + target.SetValue(MotionOpacityProperty, _originOpacity); + } + else if (motionConfig.Property == MotionRenderTransformProperty) + { + target.SetValue(MotionRenderTransformProperty, _originRenderTransform); + target.SetValue(MotionRenderTransformProperty, _originRenderTransform); + target.SetValue(Visual.RenderTransformOriginProperty, _originRenderTransformOrigin); + } + } + + + private class AnimationState + { + public ITransition? Transition { get; set; } + public object? StartValue { get; set; } + public object? EndValue { get; set; } + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MoveMotion.cs b/src/AtomUI.Base/MotionScene/MoveMotion.cs index 4ffa39a..38e2223 100644 --- a/src/AtomUI.Base/MotionScene/MoveMotion.cs +++ b/src/AtomUI.Base/MotionScene/MoveMotion.cs @@ -6,394 +6,393 @@ namespace AtomUI.MotionScene; public class MoveDownInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.StartValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); - } - } + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + EndValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); - } + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.StartValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Height * 2); + } + + internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) + { + return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); + } } + public class MoveDownOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.EndValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.EndValue = BuildTranslateTransform(0, -motionTarget.DesiredSize.Height); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Height * 2); + } + + internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) + { + return motionTargetPosition.WithY(motionTargetPosition.Y - motionTargetSize.Height); + } } + public class MoveLeftInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.StartValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); - } + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + EndValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.StartValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Width * 2); + } + + internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) + { + return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); + } } + public class MoveLeftOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.EndValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } - - internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) - { - return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.EndValue = BuildTranslateTransform(-motionTarget.DesiredSize.Width, 0); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Width * 2); + } + + internal override Point CalculateScenePosition(Size motionTargetSize, Point motionTargetPosition) + { + return motionTargetPosition.WithX(motionTargetPosition.X - motionTargetSize.Width); + } } + public class MoveRightInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.StartValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + EndValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.StartValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Width * 2); + } } + public class MoveRightOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.EndValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Width * 2); - } + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.EndValue = BuildTranslateTransform(motionTarget.DesiredSize.Width, 0); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Width * 2); + } } + public class MoveUpInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - EndValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + EndValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.StartValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); - } - } + AddMotionConfig(config); + } - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.StartValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Height * 2); + } } + public class MoveUpOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildTranslateTransform(0, 0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) - { - base.NotifyPreBuildTransition(config, motionTarget); - if (config.Property == MotionRenderTransformProperty) { - config.EndValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); - } - } - - internal override Size CalculateSceneSize(Size motionTargetSize) - { - return motionTargetSize.WithHeight(motionTargetSize.Height * 2); - } -} + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildTranslateTransform(0, 0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + protected override void NotifyPreBuildTransition(MotionConfig config, Control motionTarget) + { + base.NotifyPreBuildTransition(config, motionTarget); + if (config.Property == MotionRenderTransformProperty) + config.EndValue = BuildTranslateTransform(0, motionTarget.DesiredSize.Height); + } + + internal override Size CalculateSceneSize(Size motionTargetSize) + { + return motionTargetSize.WithHeight(motionTargetSize.Height * 2); + } +} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SceneLayer.cs b/src/AtomUI.Base/MotionScene/SceneLayer.cs index abf89fd..785ad23 100644 --- a/src/AtomUI.Base/MotionScene/SceneLayer.cs +++ b/src/AtomUI.Base/MotionScene/SceneLayer.cs @@ -11,137 +11,125 @@ namespace AtomUI.MotionScene; public class SceneLayer : WindowBase, IHostedVisualTreeRoot, IDisposable { - private IManagedPopupPositionerPopup? _managedPopupPositionerPopup; - private static readonly FieldInfo ManagedPopupPositionerPopupInfo; - private Canvas _layout; - - static SceneLayer() - { - BackgroundProperty.OverrideDefaultValue(typeof(SceneLayer), Brushes.Transparent); - ManagedPopupPositionerPopupInfo = typeof(ManagedPopupPositioner).GetField("_popup", - BindingFlags.Instance | BindingFlags.NonPublic)!; - - } + private static readonly FieldInfo ManagedPopupPositionerPopupInfo; + private readonly Canvas _layout; + private readonly IManagedPopupPositionerPopup? _managedPopupPositionerPopup; - public SceneLayer(TopLevel parent, IPopupImpl impl) - : this(parent, impl, null) { } - - /// - /// 初始化一个新的动画顶层窗口 - /// - /// - /// - /// The dependency resolver to use. If null the default dependency resolver will be used. - public SceneLayer(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver? dependencyResolver) - : base(impl, dependencyResolver) - { - ParentTopLevel = parent; - impl.SetWindowManagerAddShadowHint(false); - if (this is WindowBase window) { - window.SetTransparentForMouseEvents(true); - } - - if (PlatformImpl?.PopupPositioner is ManagedPopupPositioner managedPopupPositioner) { - _managedPopupPositionerPopup = - ManagedPopupPositionerPopupInfo.GetValue(managedPopupPositioner) as IManagedPopupPositionerPopup; - } + static SceneLayer() + { + BackgroundProperty.OverrideDefaultValue(typeof(SceneLayer), Brushes.Transparent); + ManagedPopupPositionerPopupInfo = typeof(ManagedPopupPositioner).GetField("_popup", + BindingFlags.Instance | BindingFlags.NonPublic)!; + } - _layout = new Canvas(); - Content = _layout; - Focusable = true; - } - - /// - /// Gets the platform-specific window implementation. - /// - public new IPopupImpl? PlatformImpl => (IPopupImpl?)base.PlatformImpl; + public SceneLayer(TopLevel parent, IPopupImpl impl) + : this(parent, impl, null) + { + } - /// - /// Gets the control that is hosting the popup root. - /// - Visual? IHostedVisualTreeRoot.Host - { - get - { - // If the parent is attached to a visual tree, then return that. However the parent - // will possibly be a standalone Popup (i.e. a Popup not attached to a visual tree, - // created by e.g. a ContextMenu): if this is the case, return the ParentTopLevel - // if set. This helps to allow the focus manager to restore the focus to the outer - // scope when the popup is closed. - var parentVisual = Parent as Visual; - if (parentVisual?.GetVisualRoot() != null) return parentVisual; - return ParentTopLevel ?? parentVisual; - } - } + /// + /// 初始化一个新的动画顶层窗口 + /// + /// + /// + /// The dependency resolver to use. If null the default dependency resolver will be used. + public SceneLayer(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver? dependencyResolver) + : base(impl, dependencyResolver) + { + ParentTopLevel = parent; + impl.SetWindowManagerAddShadowHint(false); + if (this is WindowBase window) window.SetTransparentForMouseEvents(true); - public TopLevel ParentTopLevel { get; } + if (PlatformImpl?.PopupPositioner is ManagedPopupPositioner managedPopupPositioner) + _managedPopupPositionerPopup = + ManagedPopupPositionerPopupInfo.GetValue(managedPopupPositioner) as IManagedPopupPositionerPopup; - public void Dispose() - { - PlatformImpl?.Dispose(); - } + _layout = new Canvas(); + Content = _layout; + Focusable = true; + } - public void SetMotionTarget(Control motionTarget) - { - _layout.Children.Add(motionTarget); - } + /// + /// Gets the platform-specific window implementation. + /// + public new IPopupImpl? PlatformImpl => (IPopupImpl?)base.PlatformImpl; - // 这个地方我们可以需要定制 - protected override Size MeasureOverride(Size availableSize) - { - var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity; - var constraint = availableSize; + public TopLevel ParentTopLevel { get; } - if (double.IsInfinity(constraint.Width)) { - constraint = constraint.WithWidth(maxAutoSize.Width); - } + public void Dispose() + { + PlatformImpl?.Dispose(); + } - if (double.IsInfinity(constraint.Height)) { - constraint = constraint.WithHeight(maxAutoSize.Height); - } + /// + /// Gets the control that is hosting the popup root. + /// + Visual? IHostedVisualTreeRoot.Host + { + get + { + // If the parent is attached to a visual tree, then return that. However the parent + // will possibly be a standalone Popup (i.e. a Popup not attached to a visual tree, + // created by e.g. a ContextMenu): if this is the case, return the ParentTopLevel + // if set. This helps to allow the focus manager to restore the focus to the outer + // scope when the popup is closed. + var parentVisual = Parent as Visual; + if (parentVisual?.GetVisualRoot() != null) return parentVisual; + return ParentTopLevel ?? parentVisual; + } + } - var measured = base.MeasureOverride(constraint); - var width = measured.Width; - var height = measured.Height; - var widthCache = Width; - var heightCache = Height; + public void SetMotionTarget(Control motionTarget) + { + _layout.Children.Add(motionTarget); + } - if (!double.IsNaN(widthCache)) { - width = widthCache; - } + // 这个地方我们可以需要定制 + protected override Size MeasureOverride(Size availableSize) + { + var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity; + var constraint = availableSize; - width = Math.Min(width, MaxWidth); - width = Math.Max(width, MinWidth); + if (double.IsInfinity(constraint.Width)) constraint = constraint.WithWidth(maxAutoSize.Width); - if (!double.IsNaN(heightCache)) { - height = heightCache; - } + if (double.IsInfinity(constraint.Height)) constraint = constraint.WithHeight(maxAutoSize.Height); - height = Math.Min(height, MaxHeight); - height = Math.Max(height, MinHeight); + var measured = base.MeasureOverride(constraint); + var width = measured.Width; + var height = measured.Height; + var widthCache = Width; + var heightCache = Height; - return new Size(width, height); - } + if (!double.IsNaN(widthCache)) width = widthCache; - protected override Size ArrangeSetBounds(Size size) - { - return ClientSize; - } + width = Math.Min(width, MaxWidth); + width = Math.Max(width, MinWidth); - public void MoveAndResize(Point point, Size size) - { - Width = size.Width; - Height = size.Height; - _managedPopupPositionerPopup?.MoveAndResize(new Point(Math.Round(point.X), Math.Floor(point.Y + 0.5)), size); - } + if (!double.IsNaN(heightCache)) height = heightCache; - protected override void OnOpened(EventArgs e) - { - base.OnOpened(e); - foreach (var child in _layout.Children) { - if (child is INotifyCaptureGhostBitmap captureGhost) { - captureGhost.NotifyCaptureGhostBitmap(); - } - } - } + height = Math.Min(height, MaxHeight); + height = Math.Max(height, MinHeight); + + return new Size(width, height); + } + + protected override Size ArrangeSetBounds(Size size) + { + return ClientSize; + } + + public void MoveAndResize(Point point, Size size) + { + Width = size.Width; + Height = size.Height; + _managedPopupPositionerPopup?.MoveAndResize(new Point(Math.Round(point.X), Math.Floor(point.Y + 0.5)), size); + } + + protected override void OnOpened(EventArgs e) + { + base.OnOpened(e); + foreach (var child in _layout.Children) + if (child is INotifyCaptureGhostBitmap captureGhost) + captureGhost.NotifyCaptureGhostBitmap(); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/SlideMotion.cs b/src/AtomUI.Base/MotionScene/SlideMotion.cs index 82c97b5..32986bb 100644 --- a/src/AtomUI.Base/MotionScene/SlideMotion.cs +++ b/src/AtomUI.Base/MotionScene/SlideMotion.cs @@ -6,327 +6,331 @@ namespace AtomUI.MotionScene; public class SlideUpInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(0.8), - EndValue = BuildScaleYTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleYTransform(0.8), + EndValue = BuildScaleYTransform(1.0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class SlideUpOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = BuildScaleYTransform(1.0), - EndValue = BuildScaleYTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = BuildScaleYTransform(1.0), + EndValue = BuildScaleYTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class SlideDownInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public SlideDownInMotion() + { + MotionRenderTransformOrigin = RelativePoint.BottomRight; + } - public SlideDownInMotion() - { - MotionRenderTransformOrigin = RelativePoint.BottomRight; - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(0.8), - EndValue = BuildScaleYTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleYTransform(0.8), + EndValue = BuildScaleYTransform(1.0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class SlideDownOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public SlideDownOutMotion() + { + MotionRenderTransformOrigin = RelativePoint.BottomRight; + } - public SlideDownOutMotion() - { - MotionRenderTransformOrigin = RelativePoint.BottomRight; - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleYTransform(1.0), - EndValue = BuildScaleYTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleYTransform(1.0), + EndValue = BuildScaleYTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class SlideLeftInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public SlideLeftInMotion() - {} - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(0.8), - EndValue = BuildScaleXTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleXTransform(0.8), + EndValue = BuildScaleXTransform(1.0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class SlideLeftOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = BuildScaleXTransform(1.0), - EndValue = BuildScaleXTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = BuildScaleXTransform(1.0), + EndValue = BuildScaleXTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class SlideRightInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public SlideRightInMotion() + { + MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); + } - public SlideRightInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(0.8), - EndValue = BuildScaleXTransform(1.0), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } - - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleXTransform(0.8), + EndValue = BuildScaleXTransform(1.0), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class SlideRightOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public SlideRightOutMotion() + { + MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); + } - public SlideRightOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new QuinticEaseIn(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleXTransform(1.0), - EndValue = BuildScaleXTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new QuinticEaseIn(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleXTransform(1.0), + EndValue = BuildScaleXTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/ZoomMotion.cs b/src/AtomUI.Base/MotionScene/ZoomMotion.cs index cfc6430..1a4202b 100644 --- a/src/AtomUI.Base/MotionScene/ZoomMotion.cs +++ b/src/AtomUI.Base/MotionScene/ZoomMotion.cs @@ -6,509 +6,520 @@ namespace AtomUI.MotionScene; public class ZoomInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.2), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.2), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class ZoomOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.2), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.2), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class ZoomBigInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - - AddMotionConfig(config); - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.8), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + + AddMotionConfig(config); + } } + public class ZoomBigOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } } + public class ZoomUpInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomUpInMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); + } - public ZoomUpInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.8), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomUpOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomUpOutMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); + } - public ZoomUpOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 0, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomLeftInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomLeftInMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); + } - public ZoomLeftInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.8), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomLeftOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomLeftOutMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); + } - public ZoomLeftOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomRightInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomRightInMotion() + { + MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); + } - public ZoomRightInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.8), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomRightOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomRightOutMotion() + { + MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); + } - public ZoomRightOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(1, 0.5, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomDownInMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomDownInMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); + } - public ZoomDownInMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 0d, - EndValue = 1d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(0.8), - EndValue = BuildScaleTransform(1), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 0d, + EndValue = 1d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(0.8), + EndValue = BuildScaleTransform(1), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } + public class ZoomDownOutMotion : AbstractMotion { - public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); - public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); + public ZoomDownOutMotion() + { + MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); + } - public ZoomDownOutMotion() - { - MotionRenderTransformOrigin = new RelativePoint(0.5, 1, RelativeUnit.Relative); - } - - public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - var config = new MotionConfig(MotionOpacityProperty) - { - TransitionKind = TransitionKind.Double, - StartValue = 1d, - EndValue = 0d, - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public MotionConfig? OpacityConfig => GetMotionConfig(MotionOpacityProperty); + public MotionConfig? RenderTransformConfig => GetMotionConfig(MotionRenderTransformProperty); - public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) - { - easing ??= new CircularEaseInOut(); - - var config = new MotionConfig(MotionRenderTransformProperty) - { - TransitionKind = TransitionKind.TransformOperations, - StartValue = BuildScaleTransform(1), - EndValue = BuildScaleTransform(0.8), - MotionDuration = duration, - MotionEasing = easing - }; - AddMotionConfig(config); - } + public void ConfigureOpacity(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + var config = new MotionConfig(MotionOpacityProperty) + { + TransitionKind = TransitionKind.Double, + StartValue = 1d, + EndValue = 0d, + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } - internal override void NotifyConfigMotionTarget(Control motionTarget) - { - base.NotifyConfigMotionTarget(motionTarget); - motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; - } + public void ConfigureRenderTransform(TimeSpan duration, Easing? easing = null) + { + easing ??= new CircularEaseInOut(); + + var config = new MotionConfig(MotionRenderTransformProperty) + { + TransitionKind = TransitionKind.TransformOperations, + StartValue = BuildScaleTransform(1), + EndValue = BuildScaleTransform(0.8), + MotionDuration = duration, + MotionEasing = easing + }; + AddMotionConfig(config); + } + + internal override void NotifyConfigMotionTarget(Control motionTarget) + { + base.NotifyConfigMotionTarget(motionTarget); + motionTarget.RenderTransformOrigin = MotionRenderTransformOrigin; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Platform/Windows/WindowExt.cs b/src/AtomUI.Base/Platform/Windows/WindowExt.cs index 533d270..608d1e9 100644 --- a/src/AtomUI.Base/Platform/Windows/WindowExt.cs +++ b/src/AtomUI.Base/Platform/Windows/WindowExt.cs @@ -6,61 +6,62 @@ namespace AtomUI.Platform.Windows; internal static class WindowExt { - public const uint WS_EX_TRANSPARENT = 32; // 0x00000020 - public const uint WS_EX_LAYERED = 0x00080000; - private static readonly Type WindowImplType; - private static readonly MethodInfo GetExtendedStyleInfo; - private static readonly MethodInfo SetExtendedStyleInfo; - - static WindowExt() - { - var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("Avalonia.Win32")); - WindowImplType = assembly.GetType("Avalonia.Win32.WindowImpl")!; - GetExtendedStyleInfo = WindowImplType.GetMethod("GetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; - SetExtendedStyleInfo = WindowImplType.GetMethod("SetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; - } - - public static void SetTransparentForMouseEvents(this WindowBase window, bool flag) - { - var impl = window.PlatformImpl!; - var currentStyles = GetExtendedStyle(impl); - // 不是确定这样处理是否合适 - if (flag) { - currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; - } else { - currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); - } - SetExtendedStyle(impl, currentStyles, false); - } - - - public static void SetTransparentForMouseEvents(this Window window, bool flag) - { - var impl = window.PlatformImpl!; - var currentStyles = GetExtendedStyle(impl); - // 不是确定这样处理是否合适 - if (flag) { - currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; - } else { - currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); - } - SetExtendedStyle(impl, currentStyles, false); - } + public const uint WS_EX_TRANSPARENT = 32; // 0x00000020 + public const uint WS_EX_LAYERED = 0x00080000; + private static readonly Type WindowImplType; + private static readonly MethodInfo GetExtendedStyleInfo; + private static readonly MethodInfo SetExtendedStyleInfo; - private static uint GetExtendedStyle(object instance) - { - return (uint)GetExtendedStyleInfo.Invoke(instance, new object[] {})!; - } - - private static void SetExtendedStyle(object instance, uint styles, bool save) - { - SetExtendedStyleInfo.Invoke(instance, new object[] { styles, save }); - } + static WindowExt() + { + var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("Avalonia.Win32")); + WindowImplType = assembly.GetType("Avalonia.Win32.WindowImpl")!; + GetExtendedStyleInfo = + WindowImplType.GetMethod("GetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; + SetExtendedStyleInfo = + WindowImplType.GetMethod("SetExtendedStyle", BindingFlags.Instance | BindingFlags.NonPublic)!; + } - public static bool IsTransparentForMouseEvents(this WindowBase window) - { - var impl = window.PlatformImpl!; - var styles = GetExtendedStyle(impl); - return (styles & WS_EX_TRANSPARENT) != 0; - } + public static void SetTransparentForMouseEvents(this WindowBase window, bool flag) + { + var impl = window.PlatformImpl!; + var currentStyles = GetExtendedStyle(impl); + + // 不是确定这样处理是否合适 + if (flag) + currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; + else + currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); + SetExtendedStyle(impl, currentStyles, false); + } + + public static void SetTransparentForMouseEvents(this Window window, bool flag) + { + var impl = window.PlatformImpl!; + var currentStyles = GetExtendedStyle(impl); + + // 不是确定这样处理是否合适 + if (flag) + currentStyles |= WS_EX_TRANSPARENT | WS_EX_LAYERED; + else + currentStyles &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); + SetExtendedStyle(impl, currentStyles, false); + } + + private static uint GetExtendedStyle(object instance) + { + return (uint)GetExtendedStyleInfo.Invoke(instance, new object[] { })!; + } + + private static void SetExtendedStyle(object instance, uint styles, bool save) + { + SetExtendedStyleInfo.Invoke(instance, new object[] { styles, save }); + } + + public static bool IsTransparentForMouseEvents(this WindowBase window) + { + var impl = window.PlatformImpl!; + var styles = GetExtendedStyle(impl); + return (styles & WS_EX_TRANSPARENT) != 0; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Reactive/DisposableMixin.cs b/src/AtomUI.Base/Reactive/DisposableMixin.cs index ab83232..8af7cf9 100644 --- a/src/AtomUI.Base/Reactive/DisposableMixin.cs +++ b/src/AtomUI.Base/Reactive/DisposableMixin.cs @@ -3,33 +3,31 @@ namespace AtomUI.Reactive; /// -/// Extension methods associated with the IDisposable interface. +/// Extension methods associated with the IDisposable interface. /// internal static class DisposableMixin { /// - /// Ensures the provided disposable is disposed with the specified . + /// Ensures the provided disposable is disposed with the specified . /// /// - /// The type of the disposable. + /// The type of the disposable. /// /// - /// The disposable we are going to want to be disposed by the CompositeDisposable. + /// The disposable we are going to want to be disposed by the CompositeDisposable. /// /// - /// The to which will be added. + /// The to which will be added. /// /// - /// The disposable. + /// The disposable. /// public static T DisposeWith(this T item, CompositeDisposable compositeDisposable) - where T : IDisposable - { - if (compositeDisposable is null) { - throw new ArgumentNullException(nameof(compositeDisposable)); - } + where T : IDisposable + { + if (compositeDisposable is null) throw new ArgumentNullException(nameof(compositeDisposable)); - compositeDisposable.Add(item); - return item; - } + compositeDisposable.Add(item); + return item; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Reflection/ObjectExtension.cs b/src/AtomUI.Base/Reflection/ObjectExtension.cs index b3c07a0..141ea0d 100644 --- a/src/AtomUI.Base/Reflection/ObjectExtension.cs +++ b/src/AtomUI.Base/Reflection/ObjectExtension.cs @@ -5,255 +5,252 @@ namespace AtomUI.Reflection; public static class ObjectExtension { - public static bool TryGetProperty( - this object source, - string name, - out T? result, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - PropertyInfo? property = source.GetType().GetProperty(name, flags); - if (property is not null && property.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetProperty( + this object source, + string name, + out T? result, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + var property = source.GetType().GetProperty(name, flags); + if (property is not null && property.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static bool TryGetProperty( - this object source, - Type declareType, - string name, - out T? result, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - { - PropertyInfo? property = declareType.GetProperty(name, flags); - if (property is not null && property.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetProperty( + this object source, + Type declareType, + string name, + out T? result, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + { + var property = declareType.GetProperty(name, flags); + if (property is not null && property.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static bool TryGetProperty(this object source, PropertyInfo info, out T? result) - { - if (info.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetProperty(this object source, PropertyInfo info, out T? result) + { + if (info.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static T? GetPropertyOrThrow(this object source, string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - object? obj = source.GetType().GetPropertyInfoOrThrow(name, flags).GetValue(source); - if (obj is T propertyOrThrow) { - return propertyOrThrow; - } - if (obj == null) { - if (typeof(T).IsValueType) { - throw new Exception(name + " is a value type but the value is null."); - } + public static T? GetPropertyOrThrow(this object source, string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + var obj = source.GetType().GetPropertyInfoOrThrow(name, flags).GetValue(source); + if (obj is T propertyOrThrow) return propertyOrThrow; + if (obj == null) + { + if (typeof(T).IsValueType) throw new Exception(name + " is a value type but the value is null."); - return default; - } + return default; + } - var stringBuilder = new StringBuilder(30); - stringBuilder.Append(name); - stringBuilder.Append("'s type is "); - stringBuilder.Append(source.GetType().Name); - stringBuilder.Append(" but the value is "); - stringBuilder.Append(obj.GetType().Name); - stringBuilder.Append("."); - throw new Exception(stringBuilder.ToString()); - } + var stringBuilder = new StringBuilder(30); + stringBuilder.Append(name); + stringBuilder.Append("'s type is "); + stringBuilder.Append(source.GetType().Name); + stringBuilder.Append(" but the value is "); + stringBuilder.Append(obj.GetType().Name); + stringBuilder.Append("."); + throw new Exception(stringBuilder.ToString()); + } - public static T? GetPropertyOrThrow( - this object source, - Type declareType, - string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - { - object? obj = declareType.GetPropertyInfoOrThrow(name, flags).GetValue(source); - if (obj is T propertyOrThrow) { - return propertyOrThrow; - } + public static T? GetPropertyOrThrow( + this object source, + Type declareType, + string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + { + var obj = declareType.GetPropertyInfoOrThrow(name, flags).GetValue(source); + if (obj is T propertyOrThrow) return propertyOrThrow; - if (obj == null) { - if (typeof(T).IsValueType) { - throw new Exception(name + " is a value type but the value is null."); - } + if (obj == null) + { + if (typeof(T).IsValueType) throw new Exception(name + " is a value type but the value is null."); - return default; - } + return default; + } - var stringHandler = new StringBuilder(30); - stringHandler.Append(name); - stringHandler.Append("'s type is "); - stringHandler.Append(declareType.Name); - stringHandler.Append(" but the value is "); - stringHandler.Append(obj.GetType().Name); - stringHandler.Append("."); - throw new Exception(stringHandler.ToString()); - } + var stringHandler = new StringBuilder(30); + stringHandler.Append(name); + stringHandler.Append("'s type is "); + stringHandler.Append(declareType.Name); + stringHandler.Append(" but the value is "); + stringHandler.Append(obj.GetType().Name); + stringHandler.Append("."); + throw new Exception(stringHandler.ToString()); + } - public static bool TrySetProperty( - this object source, - Type declareType, - string name, - T? value, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic) - { - PropertyInfo? property = declareType.GetProperty(name, flags); - if (property is null) { - return false; - } + public static bool TrySetProperty( + this object source, + Type declareType, + string name, + T? value, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic) + { + var property = declareType.GetProperty(name, flags); + if (property is null) return false; - property.SetValue(source, value); - return true; - } + property.SetValue(source, value); + return true; + } - public static bool TryGetField( - this object source, - string name, - out T? result, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - FieldInfo? field = source.GetType().GetField(name, flags); - if (field is not null && field.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetField( + this object source, + string name, + out T? result, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + var field = source.GetType().GetField(name, flags); + if (field is not null && field.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static bool TryGetField( - this object source, - Type declareType, - string name, - out T? result, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - { - FieldInfo? field = declareType.GetField(name, flags); - if (field is not null && field.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetField( + this object source, + Type declareType, + string name, + out T? result, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + { + var field = declareType.GetField(name, flags); + if (field is not null && field.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static bool TryGetField(this object source, FieldInfo info, out T? result) - { - if (info.GetValue(source) is T obj) { - result = obj; - return true; - } + public static bool TryGetField(this object source, FieldInfo info, out T? result) + { + if (info.GetValue(source) is T obj) + { + result = obj; + return true; + } - result = default; - return false; - } + result = default; + return false; + } - public static T? GetFieldOrThrow(this object source, string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - object? obj = source.GetType().GetFieldInfoOrThrow(name, flags).GetValue(source); - if (obj is T fieldOrThrow) { - return fieldOrThrow; - } + public static T? GetFieldOrThrow(this object source, string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + var obj = source.GetType().GetFieldInfoOrThrow(name, flags).GetValue(source); + if (obj is T fieldOrThrow) return fieldOrThrow; - if (obj == null) { - if (typeof(T).IsValueType) { - throw new Exception(name + " is a value type but the value is null."); - } + if (obj == null) + { + if (typeof(T).IsValueType) throw new Exception(name + " is a value type but the value is null."); - return default; - } + return default; + } - var stringBuilder = new StringBuilder(30); - stringBuilder.Append(name); - stringBuilder.Append("'s type is "); - stringBuilder.Append(source.GetType().Name); - stringBuilder.Append(" but the value is "); - stringBuilder.Append(obj.GetType().Name); - stringBuilder.Append("."); - throw new Exception(stringBuilder.ToString()); - } + var stringBuilder = new StringBuilder(30); + stringBuilder.Append(name); + stringBuilder.Append("'s type is "); + stringBuilder.Append(source.GetType().Name); + stringBuilder.Append(" but the value is "); + stringBuilder.Append(obj.GetType().Name); + stringBuilder.Append("."); + throw new Exception(stringBuilder.ToString()); + } - public static T? GetFieldOrThrow( - this object source, - Type declareType, - string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - { - object? obj = declareType.GetFieldInfoOrThrow(name, flags).GetValue(source); - if (obj is T fieldOrThrow) return fieldOrThrow; - if (obj == null) { - if (typeof(T).IsValueType) { - throw new Exception(name + " is a value type but the value is null."); - } + public static T? GetFieldOrThrow( + this object source, + Type declareType, + string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + { + var obj = declareType.GetFieldInfoOrThrow(name, flags).GetValue(source); + if (obj is T fieldOrThrow) return fieldOrThrow; + if (obj == null) + { + if (typeof(T).IsValueType) throw new Exception(name + " is a value type but the value is null."); - return default; - } + return default; + } - var stringBuilder = new StringBuilder(30); - stringBuilder.Append(name); - stringBuilder.Append("'s type is "); - stringBuilder.Append(declareType); - stringBuilder.Append(" but the value is "); - stringBuilder.Append(obj.GetType().Name); - stringBuilder.Append("."); - throw new Exception(stringBuilder.ToString()); - } + var stringBuilder = new StringBuilder(30); + stringBuilder.Append(name); + stringBuilder.Append("'s type is "); + stringBuilder.Append(declareType); + stringBuilder.Append(" but the value is "); + stringBuilder.Append(obj.GetType().Name); + stringBuilder.Append("."); + throw new Exception(stringBuilder.ToString()); + } - public static bool TrySetField( - this object source, - Type declareType, - string name, - T? value, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) - { - FieldInfo? field = declareType.GetField(name, flags); - if (field is null) { - return false; - } + public static bool TrySetField( + this object source, + Type declareType, + string name, + T? value, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) + { + var field = declareType.GetField(name, flags); + if (field is null) return false; - field.SetValue(source, value); - return true; - } + field.SetValue(source, value); + return true; + } - public static bool TryInvokeMethod( - this object source, - Type declareType, - string name, - out object? result, - params object[] parameters) - { - MethodInfo? method = declareType.GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - if (method is null) { - result = null; - return false; - } + public static bool TryInvokeMethod( + this object source, + Type declareType, + string name, + out object? result, + params object[] parameters) + { + var method = declareType.GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + if (method is null) + { + result = null; + return false; + } - result = method.Invoke(source, parameters); - return true; - } + result = method.Invoke(source, parameters); + return true; + } - public static object? InvokeMethodOrThrow( - this object source, - Type declareType, - string name, - params object[] parameters) - { - return declareType.GetMethodInfoOrThrow(name).Invoke(source, parameters); - } + public static object? InvokeMethodOrThrow( + this object source, + Type declareType, + string name, + params object[] parameters) + { + return declareType.GetMethodInfoOrThrow(name).Invoke(source, parameters); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Reflection/TypeExtension.cs b/src/AtomUI.Base/Reflection/TypeExtension.cs index 161dc96..3b5bbcf 100644 --- a/src/AtomUI.Base/Reflection/TypeExtension.cs +++ b/src/AtomUI.Base/Reflection/TypeExtension.cs @@ -5,70 +5,70 @@ namespace AtomUI.Reflection; public static class TypeExtension { - public static bool TryGetPropertyInfo( - this Type type, - string name, - [NotNullWhen(true)] out PropertyInfo? info, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) - { - info = type.GetProperty(name, flags); - return info is not null; - } + public static bool TryGetPropertyInfo( + this Type type, + string name, + [NotNullWhen(true)] out PropertyInfo? info, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) + { + info = type.GetProperty(name, flags); + return info is not null; + } - public static bool TryGetFieldInfo( - this Type type, - string name, - [NotNullWhen(true)] out FieldInfo? info, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) - { - info = type.GetField(name, flags); - return info is not null; - } + public static bool TryGetFieldInfo( + this Type type, + string name, + [NotNullWhen(true)] out FieldInfo? info, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) + { + info = type.GetField(name, flags); + return info is not null; + } - public static bool TryGetMethodInfo( - this Type type, - string name, - [NotNullWhen(true)] out MethodInfo? info, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - info = type.GetMethod(name, flags); - return info is not null; - } + public static bool TryGetMethodInfo( + this Type type, + string name, + [NotNullWhen(true)] out MethodInfo? info, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + info = type.GetMethod(name, flags); + return info is not null; + } - public static PropertyInfo GetPropertyInfoOrThrow( - this Type type, - string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - PropertyInfo? info; + public static PropertyInfo GetPropertyInfoOrThrow( + this Type type, + string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + PropertyInfo? info; - if (!type.TryGetPropertyInfo(name, out info, flags)) { - throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - } + if (!type.TryGetPropertyInfo(name, out info, flags)) + throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - return info; - } + return info; + } - public static FieldInfo GetFieldInfoOrThrow(this Type type, string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - FieldInfo? info; - if (!type.TryGetFieldInfo(name, out info, flags)) { - throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - } + public static FieldInfo GetFieldInfoOrThrow(this Type type, string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + FieldInfo? info; + if (!type.TryGetFieldInfo(name, out info, flags)) + throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - return info; - } + return info; + } - public static MethodInfo GetMethodInfoOrThrow(this Type type, string name, - BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy) - { - MethodInfo? info; - if (!type.TryGetMethodInfo(name, out info, flags)) { - throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - } + public static MethodInfo GetMethodInfoOrThrow(this Type type, string name, + BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | + BindingFlags.FlattenHierarchy) + { + MethodInfo? info; + if (!type.TryGetMethodInfo(name, out info, flags)) + throw new NotSupportedException($"Can not find the '{name}' from type '{type}'. We can not reflect it."); - return info; - } - + return info; + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Utils/EnumExtensions.cs b/src/AtomUI.Base/Utils/EnumExtensions.cs index 80ffbe9..bcb0583 100644 --- a/src/AtomUI.Base/Utils/EnumExtensions.cs +++ b/src/AtomUI.Base/Utils/EnumExtensions.cs @@ -3,55 +3,75 @@ namespace AtomUI.Utils; /// -/// Provides extension methods for enums. +/// Provides extension methods for enums. /// internal static class EnumExtensions { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool HasAllFlags(this T value, T flags) where T : unmanaged, Enum - { - if (sizeof(T) == 1) { - var byteValue = Unsafe.As(ref value); - var byteFlags = Unsafe.As(ref flags); - return (byteValue & byteFlags) == byteFlags; - } else if (sizeof(T) == 2) { - var shortValue = Unsafe.As(ref value); - var shortFlags = Unsafe.As(ref flags); - return (shortValue & shortFlags) == shortFlags; - } else if (sizeof(T) == 4) { - var intValue = Unsafe.As(ref value); - var intFlags = Unsafe.As(ref flags); - return (intValue & intFlags) == intFlags; - } else if (sizeof(T) == 8) { - var longValue = Unsafe.As(ref value); - var longFlags = Unsafe.As(ref flags); - return (longValue & longFlags) == longFlags; - } else { - throw new NotSupportedException("Enum with size of " + Unsafe.SizeOf() + " are not supported"); - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool HasAllFlags(this T value, T flags) where T : unmanaged, Enum + { + if (sizeof(T) == 1) + { + var byteValue = Unsafe.As(ref value); + var byteFlags = Unsafe.As(ref flags); + return (byteValue & byteFlags) == byteFlags; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool HasAnyFlag(this T value, T flags) where T : unmanaged, Enum - { - if (sizeof(T) == 1) { - var byteValue = Unsafe.As(ref value); - var byteFlags = Unsafe.As(ref flags); - return (byteValue & byteFlags) != 0; - } else if (sizeof(T) == 2) { - var shortValue = Unsafe.As(ref value); - var shortFlags = Unsafe.As(ref flags); - return (shortValue & shortFlags) != 0; - } else if (sizeof(T) == 4) { - var intValue = Unsafe.As(ref value); - var intFlags = Unsafe.As(ref flags); - return (intValue & intFlags) != 0; - } else if (sizeof(T) == 8) { - var longValue = Unsafe.As(ref value); - var longFlags = Unsafe.As(ref flags); - return (longValue & longFlags) != 0; - } else { - throw new NotSupportedException("Enum with size of " + Unsafe.SizeOf() + " are not supported"); - } - } + if (sizeof(T) == 2) + { + var shortValue = Unsafe.As(ref value); + var shortFlags = Unsafe.As(ref flags); + return (shortValue & shortFlags) == shortFlags; + } + + if (sizeof(T) == 4) + { + var intValue = Unsafe.As(ref value); + var intFlags = Unsafe.As(ref flags); + return (intValue & intFlags) == intFlags; + } + + if (sizeof(T) == 8) + { + var longValue = Unsafe.As(ref value); + var longFlags = Unsafe.As(ref flags); + return (longValue & longFlags) == longFlags; + } + + throw new NotSupportedException("Enum with size of " + Unsafe.SizeOf() + " are not supported"); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool HasAnyFlag(this T value, T flags) where T : unmanaged, Enum + { + if (sizeof(T) == 1) + { + var byteValue = Unsafe.As(ref value); + var byteFlags = Unsafe.As(ref flags); + return (byteValue & byteFlags) != 0; + } + + if (sizeof(T) == 2) + { + var shortValue = Unsafe.As(ref value); + var shortFlags = Unsafe.As(ref flags); + return (shortValue & shortFlags) != 0; + } + + if (sizeof(T) == 4) + { + var intValue = Unsafe.As(ref value); + var intFlags = Unsafe.As(ref flags); + return (intValue & intFlags) != 0; + } + + if (sizeof(T) == 8) + { + var longValue = Unsafe.As(ref value); + var longFlags = Unsafe.As(ref flags); + return (longValue & longFlags) != 0; + } + + throw new NotSupportedException("Enum with size of " + Unsafe.SizeOf() + " are not supported"); + } } \ No newline at end of file diff --git a/src/AtomUI.Base/Utils/IBootstrapInitializer.cs b/src/AtomUI.Base/Utils/IBootstrapInitializer.cs index deb0778..7609cd7 100644 --- a/src/AtomUI.Base/Utils/IBootstrapInitializer.cs +++ b/src/AtomUI.Base/Utils/IBootstrapInitializer.cs @@ -2,5 +2,5 @@ public interface IBootstrapInitializer { - public void Init(); + public void Init(); } \ No newline at end of file diff --git a/src/AtomUI.Base/Utils/LanguageCode.cs b/src/AtomUI.Base/Utils/LanguageCode.cs index 413681b..445b9b0 100644 --- a/src/AtomUI.Base/Utils/LanguageCode.cs +++ b/src/AtomUI.Base/Utils/LanguageCode.cs @@ -2,6 +2,6 @@ public static class LanguageCode { - public const string zh_CN = "zh-CN"; - public const string en_US = "en-US"; + public const string zh_CN = "zh-CN"; + public const string en_US = "en-US"; } \ No newline at end of file diff --git a/src/AtomUI.Base/Utils/MathUtils.cs b/src/AtomUI.Base/Utils/MathUtils.cs index ba79126..3d72081 100644 --- a/src/AtomUI.Base/Utils/MathUtils.cs +++ b/src/AtomUI.Base/Utils/MathUtils.cs @@ -4,243 +4,238 @@ namespace AtomUI.Utils; public static class MathUtils { - // smallest such that 1.0+DoubleEpsilon != 1.0 - internal const double DoubleEpsilon = 2.2204460492503131e-016; + // smallest such that 1.0+DoubleEpsilon != 1.0 + internal const double DoubleEpsilon = 2.2204460492503131e-016; - private const float FloatEpsilon = 1.192092896e-07F; + private const float FloatEpsilon = 1.192092896e-07F; - public static double RoundToFixedPoint(double value, int fixedCount) - { - var factor = Math.Pow(10, fixedCount); - return Math.Round(value * factor) / factor; - } + public static double RoundToFixedPoint(double value, int fixedCount) + { + var factor = Math.Pow(10, fixedCount); + return Math.Round(value * factor) / factor; + } - /// - /// AreClose - Returns whether or not two doubles are "close". That is, whether or - /// not they are within epsilon of each other. - /// - /// The first double to compare. - /// The second double to compare. - public static bool AreClose(double value1, double value2) - { - //in case they are Infinities (then epsilon check does not work) - if (value1 == value2) { - return true; - } - double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DoubleEpsilon; - double delta = value1 - value2; - return (-eps < delta) && (eps > delta); - } + /// + /// AreClose - Returns whether or not two doubles are "close". That is, whether or + /// not they are within epsilon of each other. + /// + /// The first double to compare. + /// The second double to compare. + public static bool AreClose(double value1, double value2) + { + //in case they are Infinities (then epsilon check does not work) + if (value1 == value2) return true; + var eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DoubleEpsilon; + var delta = value1 - value2; + return -eps < delta && eps > delta; + } - /// - /// AreClose - Returns whether or not two doubles are "close". That is, whether or - /// not they are within epsilon of each other. - /// - /// The first double to compare. - /// The second double to compare. - /// The fixed epsilon value used to compare. - public static bool AreClose(double value1, double value2, double eps) - { - //in case they are Infinities (then epsilon check does not work) - if (value1 == value2) { - return true; - } - double delta = value1 - value2; - return (-eps < delta) && (eps > delta); - } + /// + /// AreClose - Returns whether or not two doubles are "close". That is, whether or + /// not they are within epsilon of each other. + /// + /// The first double to compare. + /// The second double to compare. + /// The fixed epsilon value used to compare. + public static bool AreClose(double value1, double value2, double eps) + { + //in case they are Infinities (then epsilon check does not work) + if (value1 == value2) return true; + var delta = value1 - value2; + return -eps < delta && eps > delta; + } - /// - /// AreClose - Returns whether or not two floats are "close". That is, whether or - /// not they are within epsilon of each other. - /// - /// The first float to compare. - /// The second float to compare. - public static bool AreClose(float value1, float value2) - { - //in case they are Infinities (then epsilon check does not work) - if (value1 == value2) return true; - float eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0f) * FloatEpsilon; - float delta = value1 - value2; - return (-eps < delta) && (eps > delta); - } + /// + /// AreClose - Returns whether or not two floats are "close". That is, whether or + /// not they are within epsilon of each other. + /// + /// The first float to compare. + /// The second float to compare. + public static bool AreClose(float value1, float value2) + { + //in case they are Infinities (then epsilon check does not work) + if (value1 == value2) return true; + var eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0f) * FloatEpsilon; + var delta = value1 - value2; + return -eps < delta && eps > delta; + } - /// - /// LessThan - Returns whether or not the first double is less than the second double. - /// That is, whether or not the first is strictly less than *and* not within epsilon of - /// the other number. - /// - /// The first double to compare. - /// The second double to compare. - public static bool LessThan(double value1, double value2) - { - return (value1 < value2) && !AreClose(value1, value2); - } + /// + /// LessThan - Returns whether or not the first double is less than the second double. + /// That is, whether or not the first is strictly less than *and* not within epsilon of + /// the other number. + /// + /// The first double to compare. + /// The second double to compare. + public static bool LessThan(double value1, double value2) + { + return value1 < value2 && !AreClose(value1, value2); + } - /// - /// LessThan - Returns whether or not the first float is less than the second float. - /// That is, whether or not the first is strictly less than *and* not within epsilon of - /// the other number. - /// - /// The first single float to compare. - /// The second single float to compare. - public static bool LessThan(float value1, float value2) - { - return (value1 < value2) && !AreClose(value1, value2); - } + /// + /// LessThan - Returns whether or not the first float is less than the second float. + /// That is, whether or not the first is strictly less than *and* not within epsilon of + /// the other number. + /// + /// The first single float to compare. + /// The second single float to compare. + public static bool LessThan(float value1, float value2) + { + return value1 < value2 && !AreClose(value1, value2); + } - /// - /// GreaterThan - Returns whether or not the first double is greater than the second double. - /// That is, whether or not the first is strictly greater than *and* not within epsilon of - /// the other number. - /// - /// The first double to compare. - /// The second double to compare. - public static bool GreaterThan(double value1, double value2) - { - return (value1 > value2) && !AreClose(value1, value2); - } + /// + /// GreaterThan - Returns whether or not the first double is greater than the second double. + /// That is, whether or not the first is strictly greater than *and* not within epsilon of + /// the other number. + /// + /// The first double to compare. + /// The second double to compare. + public static bool GreaterThan(double value1, double value2) + { + return value1 > value2 && !AreClose(value1, value2); + } - /// - /// GreaterThan - Returns whether or not the first float is greater than the second float. - /// That is, whether or not the first is strictly greater than *and* not within epsilon of - /// the other number. - /// - /// The first float to compare. - /// The second float to compare. - public static bool GreaterThan(float value1, float value2) - { - return (value1 > value2) && !AreClose(value1, value2); - } + /// + /// GreaterThan - Returns whether or not the first float is greater than the second float. + /// That is, whether or not the first is strictly greater than *and* not within epsilon of + /// the other number. + /// + /// The first float to compare. + /// The second float to compare. + public static bool GreaterThan(float value1, float value2) + { + return value1 > value2 && !AreClose(value1, value2); + } - /// - /// LessThanOrClose - Returns whether or not the first double is less than or close to - /// the second double. That is, whether or not the first is strictly less than or within - /// epsilon of the other number. - /// - /// The first double to compare. - /// The second double to compare. - public static bool LessThanOrClose(double value1, double value2) - { - return (value1 < value2) || AreClose(value1, value2); - } + /// + /// LessThanOrClose - Returns whether or not the first double is less than or close to + /// the second double. That is, whether or not the first is strictly less than or within + /// epsilon of the other number. + /// + /// The first double to compare. + /// The second double to compare. + public static bool LessThanOrClose(double value1, double value2) + { + return value1 < value2 || AreClose(value1, value2); + } - /// - /// LessThanOrClose - Returns whether or not the first float is less than or close to - /// the second float. That is, whether or not the first is strictly less than or within - /// epsilon of the other number. - /// - /// The first float to compare. - /// The second float to compare. - public static bool LessThanOrClose(float value1, float value2) - { - return (value1 < value2) || AreClose(value1, value2); - } + /// + /// LessThanOrClose - Returns whether or not the first float is less than or close to + /// the second float. That is, whether or not the first is strictly less than or within + /// epsilon of the other number. + /// + /// The first float to compare. + /// The second float to compare. + public static bool LessThanOrClose(float value1, float value2) + { + return value1 < value2 || AreClose(value1, value2); + } - /// - /// GreaterThanOrClose - Returns whether or not the first double is greater than or close to - /// the second double. That is, whether or not the first is strictly greater than or within - /// epsilon of the other number. - /// - /// The first double to compare. - /// The second double to compare. - public static bool GreaterThanOrClose(double value1, double value2) - { - return (value1 > value2) || AreClose(value1, value2); - } + /// + /// GreaterThanOrClose - Returns whether or not the first double is greater than or close to + /// the second double. That is, whether or not the first is strictly greater than or within + /// epsilon of the other number. + /// + /// The first double to compare. + /// The second double to compare. + public static bool GreaterThanOrClose(double value1, double value2) + { + return value1 > value2 || AreClose(value1, value2); + } - /// - /// GreaterThanOrClose - Returns whether or not the first float is greater than or close to - /// the second float. That is, whether or not the first is strictly greater than or within - /// epsilon of the other number. - /// - /// The first float to compare. - /// The second float to compare. - public static bool GreaterThanOrClose(float value1, float value2) - { - return (value1 > value2) || AreClose(value1, value2); - } + /// + /// GreaterThanOrClose - Returns whether or not the first float is greater than or close to + /// the second float. That is, whether or not the first is strictly greater than or within + /// epsilon of the other number. + /// + /// The first float to compare. + /// The second float to compare. + public static bool GreaterThanOrClose(float value1, float value2) + { + return value1 > value2 || AreClose(value1, value2); + } - /// - /// IsOne - Returns whether or not the double is "close" to 1. Same as AreClose(double, 1), - /// but this is faster. - /// - /// The double to compare to 1. - public static bool IsOne(double value) - { - return Math.Abs(value - 1.0) < 10.0 * DoubleEpsilon; - } + /// + /// IsOne - Returns whether or not the double is "close" to 1. Same as AreClose(double, 1), + /// but this is faster. + /// + /// The double to compare to 1. + public static bool IsOne(double value) + { + return Math.Abs(value - 1.0) < 10.0 * DoubleEpsilon; + } - /// - /// IsOne - Returns whether or not the float is "close" to 1. Same as AreClose(float, 1), - /// but this is faster. - /// - /// The float to compare to 1. - public static bool IsOne(float value) - { - return Math.Abs(value - 1.0f) < 10.0f * FloatEpsilon; - } + /// + /// IsOne - Returns whether or not the float is "close" to 1. Same as AreClose(float, 1), + /// but this is faster. + /// + /// The float to compare to 1. + public static bool IsOne(float value) + { + return Math.Abs(value - 1.0f) < 10.0f * FloatEpsilon; + } - /// - /// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0), - /// but this is faster. - /// - /// The double to compare to 0. - public static bool IsZero(double value) - { - return Math.Abs(value) < 10.0 * DoubleEpsilon; - } + /// + /// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0), + /// but this is faster. + /// + /// The double to compare to 0. + public static bool IsZero(double value) + { + return Math.Abs(value) < 10.0 * DoubleEpsilon; + } - /// - /// IsZero - Returns whether or not the float is "close" to 0. Same as AreClose(float, 0), - /// but this is faster. - /// - /// The float to compare to 0. - public static bool IsZero(float value) - { - return Math.Abs(value) < 10.0f * FloatEpsilon; - } - - /// - /// Converts an angle in degrees to radians. - /// - /// The angle in degrees. - /// The angle in radians. - public static double Deg2Rad(double angle) - { - return angle * (Math.PI / 180d); - } + /// + /// IsZero - Returns whether or not the float is "close" to 0. Same as AreClose(float, 0), + /// but this is faster. + /// + /// The float to compare to 0. + public static bool IsZero(float value) + { + return Math.Abs(value) < 10.0f * FloatEpsilon; + } - /// - /// Converts an angle in gradians to radians. - /// - /// The angle in gradians. - /// The angle in radians. - public static double Grad2Rad(double angle) - { - return angle * (Math.PI / 200d); - } + /// + /// Converts an angle in degrees to radians. + /// + /// The angle in degrees. + /// The angle in radians. + public static double Deg2Rad(double angle) + { + return angle * (Math.PI / 180d); + } - /// - /// Converts an angle in turns to radians. - /// - /// The angle in turns. - /// The angle in radians. - public static double Turn2Rad(double angle) - { - return angle * 2 * Math.PI; - } + /// + /// Converts an angle in gradians to radians. + /// + /// The angle in gradians. + /// The angle in radians. + public static double Grad2Rad(double angle) + { + return angle * (Math.PI / 200d); + } - /// - /// Calculates the point of an angle on an ellipse. - /// - /// The centre point of the ellipse. - /// The x radius of the ellipse. - /// The y radius of the ellipse. - /// The angle in radians. - /// A point on the ellipse. - public static Point GetEllipsePoint(Point centre, double radiusX, double radiusY, double angle) - { - return new Point(radiusX * Math.Cos(angle) + centre.X, radiusY * Math.Sin(angle) + centre.Y); - } + /// + /// Converts an angle in turns to radians. + /// + /// The angle in turns. + /// The angle in radians. + public static double Turn2Rad(double angle) + { + return angle * 2 * Math.PI; + } + /// + /// Calculates the point of an angle on an ellipse. + /// + /// The centre point of the ellipse. + /// The x radius of the ellipse. + /// The y radius of the ellipse. + /// The angle in radians. + /// A point on the ellipse. + public static Point GetEllipsePoint(Point centre, double radiusX, double radiusY, double angle) + { + return new Point(radiusX * Math.Cos(angle) + centre.X, radiusY * Math.Sin(angle) + centre.Y); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs index 72e4c10..93f44c2 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBox.cs @@ -2,289 +2,301 @@ using AtomUI.Theme.Data; using AtomUI.Theme.Styling; using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; -using Avalonia.Controls; using Avalonia.Data; namespace AtomUI.Controls; public enum AddOnDecoratedVariant { - Outline, - Filled, - Borderless + Outline, + Filled, + Borderless } + public enum AddOnDecoratedStatus { - Default, - Warning, - Error + Default, + Warning, + Error } + [TemplatePart(AddOnDecoratedBoxTheme.LeftAddOnPart, typeof(ContentPresenter))] [TemplatePart(AddOnDecoratedBoxTheme.RightAddOnPart, typeof(ContentPresenter))] [TemplatePart(AddOnDecoratedBoxTheme.InnerBoxContentPart, typeof(ContentPresenter), IsRequired = true)] public class AddOnDecoratedBox : ContentControl { - public const string ErrorPC = ":error"; - public const string WarningPC = ":warning"; + public const string ErrorPC = ":error"; + public const string WarningPC = ":warning"; - #region 公共属性定义 + protected Control? _leftAddOnPresenter; + protected Control? _rightAddOnPresenter; - public static readonly StyledProperty LeftAddOnProperty = - AvaloniaProperty.Register(nameof(LeftAddOn)); + static AddOnDecoratedBox() + { + AffectsRender(BorderBrushProperty, BackgroundProperty); + AffectsMeasure(LeftAddOnProperty, RightAddOnProperty); + } - public static readonly StyledProperty RightAddOnProperty = - AvaloniaProperty.Register(nameof(RightAddOn)); + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); - public static readonly StyledProperty SizeTypeProperty = - AvaloniaProperty.Register(nameof(SizeType), SizeType.Middle); + if (VisualRoot is not null) + if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) + SetupInnerBoxCornerRadius(); - public static readonly StyledProperty StyleVariantProperty = - AvaloniaProperty.Register( - nameof(StyleVariant), AddOnDecoratedVariant.Outline); + if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) + SetupAddOnBorderInfo(); - public static readonly StyledProperty StatusProperty = - AvaloniaProperty.Register(nameof(Status), AddOnDecoratedStatus.Default); + if (change.Property == StatusProperty) UpdatePseudoClasses(); - public object? LeftAddOn - { - get => GetValue(LeftAddOnProperty); - set => SetValue(LeftAddOnProperty, value); - } + if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) + { + if (change.NewValue is PathIcon icon) SetupIconTypeAddOnSize(icon); + } + else if (change.Property == ContentProperty) + { + if (Content is AddOnDecoratedInnerBox innerBox) + { + BindUtils.RelayBind(this, InnerBoxCornerRadiusProperty, innerBox, CornerRadiusProperty); + BindUtils.RelayBind(this, BorderThicknessProperty, innerBox, BorderThicknessProperty); + } + } - public object? RightAddOn - { - get => GetValue(RightAddOnProperty); - set => SetValue(RightAddOnProperty, value); - } + if (change.Property == SizeTypeProperty) + { + if (LeftAddOn is PathIcon leftIconAddOn) SetupIconTypeAddOnSize(leftIconAddOn); - public SizeType SizeType - { - get => GetValue(SizeTypeProperty); - set => SetValue(SizeTypeProperty, value); - } + if (RightAddOn is PathIcon rightIconAddOn) SetupIconTypeAddOnSize(rightIconAddOn); + } + } - public AddOnDecoratedVariant StyleVariant - { - get => GetValue(StyleVariantProperty); - set => SetValue(StyleVariantProperty, value); - } + private void SetupIconTypeAddOnSize(PathIcon icon) + { + if (SizeType == SizeType.Large) + { + TokenResourceBinder.CreateGlobalTokenBinding(icon, WidthProperty, GlobalTokenResourceKey.IconSizeLG); + TokenResourceBinder.CreateGlobalTokenBinding(icon, HeightProperty, GlobalTokenResourceKey.IconSizeLG); + } + else if (SizeType == SizeType.Middle) + { + TokenResourceBinder.CreateGlobalTokenBinding(icon, WidthProperty, GlobalTokenResourceKey.IconSize); + TokenResourceBinder.CreateGlobalTokenBinding(icon, HeightProperty, GlobalTokenResourceKey.IconSize); + } + else + { + TokenResourceBinder.CreateGlobalTokenBinding(icon, WidthProperty, GlobalTokenResourceKey.IconSizeSM); + TokenResourceBinder.CreateGlobalTokenBinding(icon, HeightProperty, GlobalTokenResourceKey.IconSizeSM); + } + } - public AddOnDecoratedStatus Status - { - get => GetValue(StatusProperty); - set => SetValue(StatusProperty, value); - } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + _leftAddOnPresenter = e.NameScope.Find(AddOnDecoratedBoxTheme.LeftAddOnPart); + _rightAddOnPresenter = e.NameScope.Find(AddOnDecoratedBoxTheme.RightAddOnPart); + SetupInnerBoxCornerRadius(); + } - #endregion + private void SetupAddOnBorderInfo() + { + var topLeftRadius = CornerRadius.TopLeft; + var topRightRadius = CornerRadius.TopRight; + var bottomLeftRadius = CornerRadius.BottomLeft; + var bottomRightRadius = CornerRadius.BottomRight; - #region 内部属性定义 + var topThickness = BorderThickness.Top; + var rightThickness = BorderThickness.Right; + var bottomThickness = BorderThickness.Bottom; + var leftThickness = BorderThickness.Left; - internal static readonly DirectProperty InnerBoxCornerRadiusProperty = - AvaloniaProperty.RegisterDirect(nameof(InnerBoxCornerRadius), - o => o.InnerBoxCornerRadius, - (o, v) => o.InnerBoxCornerRadius = v); + LeftAddOnCornerRadius = new CornerRadius(topLeftRadius, + 0, + bottomLeft: bottomLeftRadius, + bottomRight: 0); + RightAddOnCornerRadius = new CornerRadius(0, + topRightRadius, + bottomLeft: 0, + bottomRight: bottomRightRadius); - internal static readonly DirectProperty LeftAddOnCornerRadiusProperty = - AvaloniaProperty.RegisterDirect(nameof(LeftAddOnCornerRadius), - o => o.LeftAddOnCornerRadius, - (o, v) => o.LeftAddOnCornerRadius = v); + LeftAddOnBorderThickness = + new Thickness(top: topThickness, right: 0, bottom: bottomThickness, left: leftThickness); + RightAddOnBorderThickness = + new Thickness(top: topThickness, right: rightThickness, bottom: bottomThickness, left: 0); - internal static readonly DirectProperty RightAddOnCornerRadiusProperty = - AvaloniaProperty.RegisterDirect(nameof(RightAddOnCornerRadius), - o => o.RightAddOnCornerRadius, - (o, v) => o.RightAddOnCornerRadius = v); + NotifyAddOnBorderInfoCalculated(); + } - internal static readonly DirectProperty LeftAddOnBorderThicknessProperty = - AvaloniaProperty.RegisterDirect(nameof(LeftAddOnBorderThickness), - o => o.LeftAddOnBorderThickness, - (o, v) => o.LeftAddOnBorderThickness = v); + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, + GlobalTokenResourceKey.BorderThickness, + BindingPriority.Template, + new RenderScaleAwareThicknessConfigure(this)); + } - internal static readonly DirectProperty RightAddOnBorderThicknessProperty = - AvaloniaProperty.RegisterDirect(nameof(RightAddOnBorderThickness), - o => o.RightAddOnBorderThickness, - (o, v) => o.RightAddOnBorderThickness = v); - private CornerRadius _innerBoxCornerRadius; + protected virtual void NotifyAddOnBorderInfoCalculated() + { + } - internal CornerRadius InnerBoxCornerRadius - { - get => _innerBoxCornerRadius; - set => SetAndRaise(InnerBoxCornerRadiusProperty, ref _innerBoxCornerRadius, value); - } + private void SetupInnerBoxCornerRadius() + { + var topLeftRadius = CornerRadius.TopLeft; + var topRightRadius = CornerRadius.TopRight; + var bottomLeftRadius = CornerRadius.BottomLeft; + var bottomRightRadius = CornerRadius.BottomRight; - private CornerRadius _leftAddOnCornerRadius; + if (_leftAddOnPresenter is not null && _leftAddOnPresenter.IsVisible) + { + topLeftRadius = 0; + bottomLeftRadius = 0; + } - internal CornerRadius LeftAddOnCornerRadius - { - get => _leftAddOnCornerRadius; - set => SetAndRaise(LeftAddOnCornerRadiusProperty, ref _leftAddOnCornerRadius, value); - } + if (_rightAddOnPresenter is not null && _rightAddOnPresenter.IsVisible) + { + topRightRadius = 0; + bottomRightRadius = 0; + } - private CornerRadius _rightAddOnCornerRadius; + InnerBoxCornerRadius = new CornerRadius(topLeftRadius, + topRightRadius, + bottomLeft: bottomLeftRadius, + bottomRight: bottomRightRadius); + } - internal CornerRadius RightAddOnCornerRadius - { - get => _rightAddOnCornerRadius; - set => SetAndRaise(RightAddOnCornerRadiusProperty, ref _rightAddOnCornerRadius, value); - } + protected virtual void UpdatePseudoClasses() + { + PseudoClasses.Set(ErrorPC, Status == AddOnDecoratedStatus.Error); + PseudoClasses.Set(WarningPC, Status == AddOnDecoratedStatus.Warning); + } - private Thickness _leftAddOnBorderThickness; - internal Thickness LeftAddOnBorderThickness - { - get => _leftAddOnBorderThickness; - set => SetAndRaise(LeftAddOnBorderThicknessProperty, ref _leftAddOnBorderThickness, value); - } - private Thickness _rightAddOnBorderThickness; + #region 公共属性定义 - internal Thickness RightAddOnBorderThickness - { - get => _rightAddOnBorderThickness; - set => SetAndRaise(RightAddOnBorderThicknessProperty, ref _rightAddOnBorderThickness, value); - } - #endregion + public static readonly StyledProperty LeftAddOnProperty = + AvaloniaProperty.Register(nameof(LeftAddOn)); - protected Control? _leftAddOnPresenter; - protected Control? _rightAddOnPresenter; + public static readonly StyledProperty RightAddOnProperty = + AvaloniaProperty.Register(nameof(RightAddOn)); - static AddOnDecoratedBox() - { - AffectsRender(BorderBrushProperty, BackgroundProperty); - AffectsMeasure(LeftAddOnProperty, RightAddOnProperty); - } + public static readonly StyledProperty SizeTypeProperty = + AvaloniaProperty.Register(nameof(SizeType), SizeType.Middle); - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); + public static readonly StyledProperty StyleVariantProperty = + AvaloniaProperty.Register( + nameof(StyleVariant)); - if (VisualRoot is not null) { - if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) { - SetupInnerBoxCornerRadius(); - } - } + public static readonly StyledProperty StatusProperty = + AvaloniaProperty.Register(nameof(Status)); - if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) { - SetupAddOnBorderInfo(); - } - - if (change.Property == StatusProperty) { - UpdatePseudoClasses(); - } + public object? LeftAddOn + { + get => GetValue(LeftAddOnProperty); + set => SetValue(LeftAddOnProperty, value); + } - if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) { - if (change.NewValue is PathIcon icon) { - SetupIconTypeAddOnSize(icon); - } - } else if (change.Property == ContentProperty) { - if (Content is AddOnDecoratedInnerBox innerBox) { - BindUtils.RelayBind(this, InnerBoxCornerRadiusProperty, innerBox, AddOnDecoratedInnerBox.CornerRadiusProperty); - BindUtils.RelayBind(this, BorderThicknessProperty, innerBox, AddOnDecoratedInnerBox.BorderThicknessProperty); - } - } + public object? RightAddOn + { + get => GetValue(RightAddOnProperty); + set => SetValue(RightAddOnProperty, value); + } - if (change.Property == SizeTypeProperty) { - if (LeftAddOn is PathIcon leftIconAddOn) { - SetupIconTypeAddOnSize(leftIconAddOn); - } + public SizeType SizeType + { + get => GetValue(SizeTypeProperty); + set => SetValue(SizeTypeProperty, value); + } - if (RightAddOn is PathIcon rightIconAddOn) { - SetupIconTypeAddOnSize(rightIconAddOn); - } - } - } + public AddOnDecoratedVariant StyleVariant + { + get => GetValue(StyleVariantProperty); + set => SetValue(StyleVariantProperty, value); + } - private void SetupIconTypeAddOnSize(PathIcon icon) - { - if (SizeType == SizeType.Large) { - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.WidthProperty, GlobalTokenResourceKey.IconSizeLG); - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.HeightProperty, GlobalTokenResourceKey.IconSizeLG); - } else if (SizeType == SizeType.Middle) { - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.WidthProperty, GlobalTokenResourceKey.IconSize); - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.HeightProperty, GlobalTokenResourceKey.IconSize); - } else { - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.WidthProperty, GlobalTokenResourceKey.IconSizeSM); - TokenResourceBinder.CreateGlobalTokenBinding(icon, PathIcon.HeightProperty, GlobalTokenResourceKey.IconSizeSM); - } - } - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - _leftAddOnPresenter = e.NameScope.Find(AddOnDecoratedBoxTheme.LeftAddOnPart); - _rightAddOnPresenter = e.NameScope.Find(AddOnDecoratedBoxTheme.RightAddOnPart); - SetupInnerBoxCornerRadius(); - } - - private void SetupAddOnBorderInfo() - { - var topLeftRadius = CornerRadius.TopLeft; - var topRightRadius = CornerRadius.TopRight; - var bottomLeftRadius = CornerRadius.BottomLeft; - var bottomRightRadius = CornerRadius.BottomRight; - - var topThickness = BorderThickness.Top; - var rightThickness = BorderThickness.Right; - var bottomThickness = BorderThickness.Bottom; - var leftThickness = BorderThickness.Left; + public AddOnDecoratedStatus Status + { + get => GetValue(StatusProperty); + set => SetValue(StatusProperty, value); + } - LeftAddOnCornerRadius = new CornerRadius(topLeft: topLeftRadius, - topRight: 0, - bottomLeft:bottomLeftRadius, - bottomRight:0); - RightAddOnCornerRadius = new CornerRadius(topLeft: 0, - topRight: topRightRadius, - bottomLeft:0, - bottomRight:bottomRightRadius); + #endregion - LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness); - RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0); - NotifyAddOnBorderInfoCalculated(); - } - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, GlobalTokenResourceKey.BorderThickness, - BindingPriority.Template, - new RenderScaleAwareThicknessConfigure(this)); - } + #region 内部属性定义 - protected virtual void NotifyAddOnBorderInfoCalculated() - { - } + internal static readonly DirectProperty InnerBoxCornerRadiusProperty = + AvaloniaProperty.RegisterDirect(nameof(InnerBoxCornerRadius), + o => o.InnerBoxCornerRadius, + (o, v) => o.InnerBoxCornerRadius = v); - private void SetupInnerBoxCornerRadius() - { - var topLeftRadius = CornerRadius.TopLeft; - var topRightRadius = CornerRadius.TopRight; - var bottomLeftRadius = CornerRadius.BottomLeft; - var bottomRightRadius = CornerRadius.BottomRight; + internal static readonly DirectProperty LeftAddOnCornerRadiusProperty = + AvaloniaProperty.RegisterDirect(nameof(LeftAddOnCornerRadius), + o => o.LeftAddOnCornerRadius, + (o, v) => o.LeftAddOnCornerRadius = v); - if (_leftAddOnPresenter is not null && _leftAddOnPresenter.IsVisible) { - topLeftRadius = 0; - bottomLeftRadius = 0; - } + internal static readonly DirectProperty RightAddOnCornerRadiusProperty = + AvaloniaProperty.RegisterDirect(nameof(RightAddOnCornerRadius), + o => o.RightAddOnCornerRadius, + (o, v) => o.RightAddOnCornerRadius = v); - if (_rightAddOnPresenter is not null && _rightAddOnPresenter.IsVisible) { - topRightRadius = 0; - bottomRightRadius = 0; - } + internal static readonly DirectProperty LeftAddOnBorderThicknessProperty = + AvaloniaProperty.RegisterDirect(nameof(LeftAddOnBorderThickness), + o => o.LeftAddOnBorderThickness, + (o, v) => o.LeftAddOnBorderThickness = v); - InnerBoxCornerRadius = new CornerRadius(topLeft: topLeftRadius, - topRight: topRightRadius, - bottomLeft: bottomLeftRadius, - bottomRight: bottomRightRadius); - } - - protected virtual void UpdatePseudoClasses() - { - PseudoClasses.Set(ErrorPC, Status == AddOnDecoratedStatus.Error); - PseudoClasses.Set(WarningPC, Status == AddOnDecoratedStatus.Warning); - } + internal static readonly DirectProperty RightAddOnBorderThicknessProperty = + AvaloniaProperty.RegisterDirect(nameof(RightAddOnBorderThickness), + o => o.RightAddOnBorderThickness, + (o, v) => o.RightAddOnBorderThickness = v); + + private CornerRadius _innerBoxCornerRadius; + + internal CornerRadius InnerBoxCornerRadius + { + get => _innerBoxCornerRadius; + set => SetAndRaise(InnerBoxCornerRadiusProperty, ref _innerBoxCornerRadius, value); + } + + private CornerRadius _leftAddOnCornerRadius; + + internal CornerRadius LeftAddOnCornerRadius + { + get => _leftAddOnCornerRadius; + set => SetAndRaise(LeftAddOnCornerRadiusProperty, ref _leftAddOnCornerRadius, value); + } + + private CornerRadius _rightAddOnCornerRadius; + + internal CornerRadius RightAddOnCornerRadius + { + get => _rightAddOnCornerRadius; + set => SetAndRaise(RightAddOnCornerRadiusProperty, ref _rightAddOnCornerRadius, value); + } + + private Thickness _leftAddOnBorderThickness; + + internal Thickness LeftAddOnBorderThickness + { + get => _leftAddOnBorderThickness; + set => SetAndRaise(LeftAddOnBorderThicknessProperty, ref _leftAddOnBorderThickness, value); + } + + private Thickness _rightAddOnBorderThickness; + + internal Thickness RightAddOnBorderThickness + { + get => _rightAddOnBorderThickness; + set => SetAndRaise(RightAddOnBorderThicknessProperty, ref _rightAddOnBorderThickness, value); + } + + #endregion } \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs index 00c4a48..d780395 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxTheme.cs @@ -1,8 +1,10 @@ using AtomUI.Theme; using AtomUI.Theme.Data; using AtomUI.Theme.Styling; +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Presenters; +using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Data.Converters; @@ -14,185 +16,194 @@ namespace AtomUI.Controls; [ControlThemeProvider] internal class AddOnDecoratedBoxTheme : BaseControlTheme { - public const string MainLayoutPart = "PART_MainLayout"; - public const string LeftAddOnPart = "PART_LeftAddOn"; - public const string RightAddOnPart = "PART_RightAddOn"; - public const string InnerBoxContentPart = "PART_InnerBoxContent"; + public const string MainLayoutPart = "PART_MainLayout"; + public const string LeftAddOnPart = "PART_LeftAddOn"; + public const string RightAddOnPart = "PART_RightAddOn"; + public const string InnerBoxContentPart = "PART_InnerBoxContent"; - public const int NormalZIndex = 1000; - public const int ActivatedZIndex = 2000; + public const int NormalZIndex = 1000; + public const int ActivatedZIndex = 2000; - public AddOnDecoratedBoxTheme() : base(typeof(AddOnDecoratedBox)) { } - protected AddOnDecoratedBoxTheme(Type targetType) : base(targetType) { } + public AddOnDecoratedBoxTheme() : base(typeof(AddOnDecoratedBox)) + { + } - protected override IControlTemplate BuildControlTemplate() - { - return new FuncControlTemplate((decoratedBox, scope) => - { - var mainLayout = new Grid() - { - Name = MainLayoutPart, - ColumnDefinitions = new ColumnDefinitions() + protected AddOnDecoratedBoxTheme(Type targetType) : base(targetType) + { + } + + protected override IControlTemplate BuildControlTemplate() + { + return new FuncControlTemplate((decoratedBox, scope) => + { + var mainLayout = new Grid { - new ColumnDefinition(GridLength.Auto), - new ColumnDefinition(GridLength.Star), - new ColumnDefinition(GridLength.Auto) - } - }; - BuildGridChildren(decoratedBox, mainLayout, scope); - return mainLayout; - }); - } + Name = MainLayoutPart, + ColumnDefinitions = new ColumnDefinitions + { + new(GridLength.Auto), + new(GridLength.Star), + new(GridLength.Auto) + } + }; + BuildGridChildren(decoratedBox, mainLayout, scope); + return mainLayout; + }); + } - protected override void BuildStyles() - { - BuildFixedStyle(); - BuildCommonStyle(); - BuildDisabledStyle(); - } + protected override void BuildStyles() + { + BuildFixedStyle(); + BuildCommonStyle(); + BuildDisabledStyle(); + } - protected virtual void BuildGridChildren(AddOnDecoratedBox decoratedBox, Grid mainLayout, INameScope scope) - { - BuildLeftAddOn(mainLayout, scope); - BuildInnerBox(decoratedBox, mainLayout, scope); - BuildRightAddOn(mainLayout, scope); - } + protected virtual void BuildGridChildren(AddOnDecoratedBox decoratedBox, Grid mainLayout, INameScope scope) + { + BuildLeftAddOn(mainLayout, scope); + BuildInnerBox(decoratedBox, mainLayout, scope); + BuildRightAddOn(mainLayout, scope); + } - protected virtual void BuildLeftAddOn(Grid layout, INameScope scope) - { - var leftAddOnContentPresenter = new ContentPresenter() - { - Name = LeftAddOnPart, - VerticalAlignment = VerticalAlignment.Stretch, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Left, - Focusable = false - }; + protected virtual void BuildLeftAddOn(Grid layout, INameScope scope) + { + var leftAddOnContentPresenter = new ContentPresenter + { + Name = LeftAddOnPart, + VerticalAlignment = VerticalAlignment.Stretch, + VerticalContentAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Left, + Focusable = false + }; - CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty, - AddOnDecoratedBox.LeftAddOnProperty); - CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.BorderThicknessProperty, - AddOnDecoratedBox.LeftAddOnBorderThicknessProperty); - CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.CornerRadiusProperty, - AddOnDecoratedBox.LeftAddOnCornerRadiusProperty); - CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.IsVisibleProperty, - AddOnDecoratedBox.LeftAddOnProperty, - BindingMode.Default, ObjectConverters.IsNotNull); - leftAddOnContentPresenter.RegisterInNameScope(scope); + CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty, + AddOnDecoratedBox.LeftAddOnProperty); + CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.BorderThicknessProperty, + AddOnDecoratedBox.LeftAddOnBorderThicknessProperty); + CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.CornerRadiusProperty, + AddOnDecoratedBox.LeftAddOnCornerRadiusProperty); + CreateTemplateParentBinding(leftAddOnContentPresenter, Visual.IsVisibleProperty, + AddOnDecoratedBox.LeftAddOnProperty, + BindingMode.Default, ObjectConverters.IsNotNull); + leftAddOnContentPresenter.RegisterInNameScope(scope); - TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BackgroundProperty, - AddOnDecoratedBoxTokenResourceKey.AddonBg); - TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BorderBrushProperty, - GlobalTokenResourceKey.ColorBorder); + TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BackgroundProperty, + AddOnDecoratedBoxTokenResourceKey.AddonBg); + TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BorderBrushProperty, + GlobalTokenResourceKey.ColorBorder); - Grid.SetColumn(leftAddOnContentPresenter, 0); - layout.Children.Add(leftAddOnContentPresenter); - } + Grid.SetColumn(leftAddOnContentPresenter, 0); + layout.Children.Add(leftAddOnContentPresenter); + } - protected virtual void BuildInnerBox(AddOnDecoratedBox decoratedBox, Grid layout, INameScope scope) - { - var innerBox = new ContentPresenter() - { - Name = InnerBoxContentPart, - }; - - CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, AddOnDecoratedBox.ContentProperty); - - layout.Children.Add(innerBox); - Grid.SetColumn(innerBox, 1); - } + protected virtual void BuildInnerBox(AddOnDecoratedBox decoratedBox, Grid layout, INameScope scope) + { + var innerBox = new ContentPresenter + { + Name = InnerBoxContentPart + }; - protected virtual void BuildRightAddOn(Grid layout, INameScope scope) - { - var rightAddOnContentPresenter = new ContentPresenter() - { - Name = RightAddOnPart, - VerticalAlignment = VerticalAlignment.Stretch, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Right, - Focusable = false - }; - CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty, - AddOnDecoratedBox.RightAddOnProperty); - CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.BorderThicknessProperty, - AddOnDecoratedBox.RightAddOnBorderThicknessProperty); - CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.CornerRadiusProperty, - AddOnDecoratedBox.RightAddOnCornerRadiusProperty); - CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.IsVisibleProperty, - AddOnDecoratedBox.RightAddOnProperty, - BindingMode.Default, ObjectConverters.IsNotNull); + CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, ContentControl.ContentProperty); - TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BackgroundProperty, - AddOnDecoratedBoxTokenResourceKey.AddonBg); - TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BorderBrushProperty, - GlobalTokenResourceKey.ColorBorder); + layout.Children.Add(innerBox); + Grid.SetColumn(innerBox, 1); + } + + protected virtual void BuildRightAddOn(Grid layout, INameScope scope) + { + var rightAddOnContentPresenter = new ContentPresenter + { + Name = RightAddOnPart, + VerticalAlignment = VerticalAlignment.Stretch, + VerticalContentAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Right, + Focusable = false + }; + CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty, + AddOnDecoratedBox.RightAddOnProperty); + CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.BorderThicknessProperty, + AddOnDecoratedBox.RightAddOnBorderThicknessProperty); + CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.CornerRadiusProperty, + AddOnDecoratedBox.RightAddOnCornerRadiusProperty); + CreateTemplateParentBinding(rightAddOnContentPresenter, Visual.IsVisibleProperty, + AddOnDecoratedBox.RightAddOnProperty, + BindingMode.Default, ObjectConverters.IsNotNull); + + TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BackgroundProperty, + AddOnDecoratedBoxTokenResourceKey.AddonBg); + TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BorderBrushProperty, + GlobalTokenResourceKey.ColorBorder); + + rightAddOnContentPresenter.RegisterInNameScope(scope); + layout.Children.Add(rightAddOnContentPresenter); + Grid.SetColumn(rightAddOnContentPresenter, 2); + } - rightAddOnContentPresenter.RegisterInNameScope(scope); - layout.Children.Add(rightAddOnContentPresenter); - Grid.SetColumn(rightAddOnContentPresenter, 2); - } - private void BuildFixedStyle() - { - this.Add(AddOnDecoratedBox.VerticalAlignmentProperty, VerticalAlignment.Center); - this.Add(ScrollViewer.IsScrollChainingEnabledProperty, true); - } + { + this.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Center); + this.Add(ScrollViewer.IsScrollChainingEnabledProperty, true); + } - private void BuildCommonStyle() - { - var commonStyle = new Style(selector => selector.Nesting()); - commonStyle.Add(AddOnDecoratedBox.ForegroundProperty, GlobalTokenResourceKey.ColorText); + private void BuildCommonStyle() + { + var commonStyle = new Style(selector => selector.Nesting()); + commonStyle.Add(TemplatedControl.ForegroundProperty, GlobalTokenResourceKey.ColorText); - var largeStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Large)); - { - var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart))); - addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingLG); - largeStyle.Add(addOnStyle); - } + var largeStyle = + new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Large)); + { + var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), + selector.Nesting().Template().Name(RightAddOnPart))); + addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingLG); + largeStyle.Add(addOnStyle); + } - largeStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSizeLG); - largeStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusLG); - commonStyle.Add(largeStyle); + largeStyle.Add(TemplatedControl.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSizeLG); + largeStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusLG); + commonStyle.Add(largeStyle); - var middleStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Middle)); - { - var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart))); - addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.Padding); - middleStyle.Add(addOnStyle); - } - - middleStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSize); - middleStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius); - commonStyle.Add(middleStyle); + var middleStyle = + new Style( + selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Middle)); + { + var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), + selector.Nesting().Template().Name(RightAddOnPart))); + addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.Padding); + middleStyle.Add(addOnStyle); + } - var smallStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Small)); - { - var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart))); - addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingSM); - smallStyle.Add(addOnStyle); - } - - smallStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSizeSM); - smallStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusSM); - commonStyle.Add(smallStyle); + middleStyle.Add(TemplatedControl.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSize); + middleStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius); + commonStyle.Add(middleStyle); - Add(commonStyle); - } + var smallStyle = + new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedBox.SizeTypeProperty, SizeType.Small)); + { + var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), + selector.Nesting().Template().Name(RightAddOnPart))); + addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingSM); + smallStyle.Add(addOnStyle); + } - private void BuildDisabledStyle() - { - var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled)); - disabledStyle.Add(AddOnDecoratedBox.ForegroundProperty, GlobalTokenResourceKey.ColorTextDisabled); - // TODO 暂时这么简单处理吧 - var addOnStyle = new Style(selector => selector.Nesting().Template().OfType()); - addOnStyle.Add(ContentPresenter.ForegroundProperty, GlobalTokenResourceKey.ColorTextDisabled); - disabledStyle.Add(addOnStyle); - Add(disabledStyle); - } + smallStyle.Add(TemplatedControl.FontSizeProperty, AddOnDecoratedBoxTokenResourceKey.FontSizeSM); + smallStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusSM); + commonStyle.Add(smallStyle); + + Add(commonStyle); + } + + private void BuildDisabledStyle() + { + var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled)); + disabledStyle.Add(TemplatedControl.ForegroundProperty, GlobalTokenResourceKey.ColorTextDisabled); + + // TODO 暂时这么简单处理吧 + var addOnStyle = new Style(selector => selector.Nesting().Template().OfType()); + addOnStyle.Add(ContentPresenter.ForegroundProperty, GlobalTokenResourceKey.ColorTextDisabled); + disabledStyle.Add(addOnStyle); + Add(disabledStyle); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs index 3771e06..7b67721 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs @@ -7,151 +7,152 @@ namespace AtomUI.Controls; [ControlDesignToken] internal class AddOnDecoratedBoxToken : AbstractControlDesignToken { - public const string ID = "AddOnDecoratedBox"; - - public AddOnDecoratedBoxToken() - : base(ID) - { - } - - /// - /// 输入框内边距 - /// - public Thickness Padding { get; set; } - - /// - /// 小号输入框内边距 - /// - public Thickness PaddingSM { get; set; } - - /// - /// 大号输入框内边距 - /// - public Thickness PaddingLG { get; set; } - - /// - /// 前/后置标签背景色 - /// - public Color AddonBg { get; set; } - - /// - /// 悬浮态边框色 - /// - public Color HoverBorderColor { get; set; } - - /// - /// 激活态边框色 - /// - public Color ActiveBorderColor { get; set; } - - /// - /// 激活态阴影 - /// - public BoxShadow ActiveShadow { get; set; } - - /// - /// 错误状态时激活态阴影 - /// - public BoxShadow ErrorActiveShadow { get; set; } - - /// - /// 警告状态时激活态阴影 - /// - public BoxShadow WarningActiveShadow { get; set; } - - /// - /// hover 状态时背景颜色 - /// - public Color HoverBg { get; set; } - - /// - /// 激活状态时背景颜色 - /// - public Color ActiveBg { get; set; } - - /// - /// 字体大小 - /// - public double FontSize { get; set; } - - /// - /// 大号字体大小 - /// - public double FontSizeLG { get; set; } - - /// - /// 小号字体大小 - /// - public double FontSizeSM { get; set; } - - /// - /// AddOn 内边距 - /// - public Thickness AddOnPadding { get; set; } - - /// - /// AddOn 小号内边距 - /// - public Thickness AddOnPaddingSM { get; set; } - - /// - /// AddOn 大号内边距 - /// - public Thickness AddOnPaddingLG { get; set; } - - /// - /// 左边内部小组件的边距 - /// - public Thickness LeftInnerAddOnMargin { get; set; } - - /// - /// 右边内部小组件的边距 - /// - public Thickness RightInnerAddOnMargin { get; set; } - - internal override void CalculateFromAlias() - { - base.CalculateFromAlias(); - var fontSize = _globalToken.FontToken.FontSize; - var fontSizeLG = _globalToken.FontToken.FontSizeLG; - var lineHeight = _globalToken.FontToken.LineHeight; - var lineHeightLG = _globalToken.FontToken.LineHeightLG; - var lineWidth = _globalToken.SeedToken.LineWidth; - Padding = new Thickness(_globalToken.PaddingSM - lineWidth, - Math.Round(((_globalToken.SeedToken.ControlHeight - fontSize * lineHeight) / 2) * 10) / 10 - lineWidth); - PaddingSM = new Thickness(_globalToken.ControlPaddingSM - lineWidth, - Math.Round(((_globalToken.HeightToken.ControlHeightSM - fontSize * lineHeight) / 2) * 10) / 10 - lineWidth); - PaddingLG = new Thickness(_globalToken.ControlPadding - lineWidth, - Math.Ceiling(((_globalToken.HeightToken.ControlHeightLG - fontSizeLG * lineHeightLG) / 2) * 10) / 10 - lineWidth); - AddOnPadding = new Thickness(_globalToken.PaddingSM, 0); - AddOnPaddingSM = new Thickness(_globalToken.ControlPaddingSM, 0); - AddOnPaddingLG = new Thickness(_globalToken.ControlPadding, 0); + public const string ID = "AddOnDecoratedBox"; - AddonBg = _globalToken.ColorFillAlter; - ActiveBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary; - HoverBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimaryHover; - ActiveShadow = new BoxShadow() - { - Spread = _globalToken.ControlOutlineWidth, - Color = _globalToken.ColorControlOutline - }; - ErrorActiveShadow = new BoxShadow() - { - Spread = _globalToken.ControlOutlineWidth, - Color = _globalToken.ColorErrorOutline - }; - WarningActiveShadow = new BoxShadow() - { - Spread = _globalToken.ControlOutlineWidth, - Color = _globalToken.ColorWarningOutline - }; - HoverBg = _globalToken.ColorToken.ColorNeutralToken.ColorBgContainer; - ActiveBg = _globalToken.SeedToken.ColorTransparent; - FontSize = _globalToken.FontToken.FontSize; - FontSizeLG = _globalToken.FontToken.FontSizeLG; - FontSizeSM = _globalToken.FontToken.FontSizeSM; + public AddOnDecoratedBoxToken() + : base(ID) + { + } - LeftInnerAddOnMargin = new Thickness(0, 0, _globalToken.MarginXXS, 0); - RightInnerAddOnMargin = new Thickness(_globalToken.MarginXXS, 0, 0, 0); - } + /// + /// 输入框内边距 + /// + public Thickness Padding { get; set; } + + /// + /// 小号输入框内边距 + /// + public Thickness PaddingSM { get; set; } + + /// + /// 大号输入框内边距 + /// + public Thickness PaddingLG { get; set; } + + /// + /// 前/后置标签背景色 + /// + public Color AddonBg { get; set; } + + /// + /// 悬浮态边框色 + /// + public Color HoverBorderColor { get; set; } + + /// + /// 激活态边框色 + /// + public Color ActiveBorderColor { get; set; } + + /// + /// 激活态阴影 + /// + public BoxShadow ActiveShadow { get; set; } + + /// + /// 错误状态时激活态阴影 + /// + public BoxShadow ErrorActiveShadow { get; set; } + + /// + /// 警告状态时激活态阴影 + /// + public BoxShadow WarningActiveShadow { get; set; } + + /// + /// hover 状态时背景颜色 + /// + public Color HoverBg { get; set; } + + /// + /// 激活状态时背景颜色 + /// + public Color ActiveBg { get; set; } + + /// + /// 字体大小 + /// + public double FontSize { get; set; } + + /// + /// 大号字体大小 + /// + public double FontSizeLG { get; set; } + + /// + /// 小号字体大小 + /// + public double FontSizeSM { get; set; } + + /// + /// AddOn 内边距 + /// + public Thickness AddOnPadding { get; set; } + + /// + /// AddOn 小号内边距 + /// + public Thickness AddOnPaddingSM { get; set; } + + /// + /// AddOn 大号内边距 + /// + public Thickness AddOnPaddingLG { get; set; } + + /// + /// 左边内部小组件的边距 + /// + public Thickness LeftInnerAddOnMargin { get; set; } + + /// + /// 右边内部小组件的边距 + /// + public Thickness RightInnerAddOnMargin { get; set; } + + internal override void CalculateFromAlias() + { + base.CalculateFromAlias(); + var fontSize = _globalToken.FontToken.FontSize; + var fontSizeLG = _globalToken.FontToken.FontSizeLG; + var lineHeight = _globalToken.FontToken.LineHeight; + var lineHeightLG = _globalToken.FontToken.LineHeightLG; + var lineWidth = _globalToken.SeedToken.LineWidth; + Padding = new Thickness(_globalToken.PaddingSM - lineWidth, + Math.Round((_globalToken.SeedToken.ControlHeight - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); + PaddingSM = new Thickness(_globalToken.ControlPaddingSM - lineWidth, + Math.Round((_globalToken.HeightToken.ControlHeightSM - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); + PaddingLG = new Thickness(_globalToken.ControlPadding - lineWidth, + Math.Ceiling((_globalToken.HeightToken.ControlHeightLG - fontSizeLG * lineHeightLG) / 2 * 10) / 10 - + lineWidth); + AddOnPadding = new Thickness(_globalToken.PaddingSM, 0); + AddOnPaddingSM = new Thickness(_globalToken.ControlPaddingSM, 0); + AddOnPaddingLG = new Thickness(_globalToken.ControlPadding, 0); + + AddonBg = _globalToken.ColorFillAlter; + ActiveBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary; + HoverBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimaryHover; + ActiveShadow = new BoxShadow + { + Spread = _globalToken.ControlOutlineWidth, + Color = _globalToken.ColorControlOutline + }; + ErrorActiveShadow = new BoxShadow + { + Spread = _globalToken.ControlOutlineWidth, + Color = _globalToken.ColorErrorOutline + }; + WarningActiveShadow = new BoxShadow + { + Spread = _globalToken.ControlOutlineWidth, + Color = _globalToken.ColorWarningOutline + }; + HoverBg = _globalToken.ColorToken.ColorNeutralToken.ColorBgContainer; + ActiveBg = _globalToken.SeedToken.ColorTransparent; + FontSize = _globalToken.FontToken.FontSize; + FontSizeLG = _globalToken.FontToken.FontSizeLG; + FontSizeSM = _globalToken.FontToken.FontSizeSM; + + LeftInnerAddOnMargin = new Thickness(0, 0, _globalToken.MarginXXS, 0); + RightInnerAddOnMargin = new Thickness(_globalToken.MarginXXS, 0, 0, 0); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs index 090b3fd..942ee0a 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBox.cs @@ -13,189 +13,180 @@ namespace AtomUI.Controls; [TemplatePart(AddOnDecoratedInnerBoxTheme.ContentPresenterPart, typeof(ContentPresenter), IsRequired = true)] public class AddOnDecoratedInnerBox : ContentControl { - #region 公共属性定义 + private IconButton? _clearButton; - public static readonly StyledProperty SizeTypeProperty = - AddOnDecoratedBox.SizeTypeProperty.AddOwner(); - - public static readonly StyledProperty StyleVariantProperty = - AddOnDecoratedBox.StyleVariantProperty.AddOwner(); - - public static readonly StyledProperty StatusProperty = - AddOnDecoratedBox.StatusProperty.AddOwner(); - - public static readonly StyledProperty LeftAddOnContentProperty = - AvaloniaProperty.Register(nameof(LeftAddOnContent)); + private StackPanel? _leftAddOnLayout; + private StackPanel? _rightAddOnLayout; - public static readonly StyledProperty RightAddOnContentProperty = - AvaloniaProperty.Register(nameof(RightAddOnContent)); + protected virtual void NotifyClearButtonClicked() + { + } - public static readonly StyledProperty IsClearButtonVisibleProperty = - AvaloniaProperty.Register(nameof(IsClearButtonVisible)); - - public SizeType SizeType - { - get => GetValue(SizeTypeProperty); - set => SetValue(SizeTypeProperty, value); - } - - public AddOnDecoratedVariant StyleVariant - { - get => GetValue(StyleVariantProperty); - set => SetValue(StyleVariantProperty, value); - } - - public AddOnDecoratedStatus Status - { - get => GetValue(StatusProperty); - set => SetValue(StatusProperty, value); - } - - public object? LeftAddOnContent - { - get => GetValue(LeftAddOnContentProperty); - set => SetValue(LeftAddOnContentProperty, value); - } + protected virtual void BuildEffectiveInnerBoxPadding() + { + BindUtils.RelayBind(this, InnerBoxPaddingProperty, this, EffectiveInnerBoxPaddingProperty); + } - public object? RightAddOnContent - { - get => GetValue(RightAddOnContentProperty); - set => SetValue(RightAddOnContentProperty, value); - } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); - public bool IsClearButtonVisible - { - get => GetValue(IsClearButtonVisibleProperty); - set => SetValue(IsClearButtonVisibleProperty, value); - } + if (change.Property == LeftAddOnContentProperty || change.Property == RightAddOnContentProperty) + { + if (change.OldValue is Control oldControl) UIStructureUtils.SetTemplateParent(oldControl, null); - #endregion + if (change.NewValue is Control newControl) UIStructureUtils.SetTemplateParent(newControl, this); + } + } - #region 内部属性定义 - - internal static readonly StyledProperty InnerBoxPaddingProperty = - AvaloniaProperty.Register(nameof(InnerBoxPadding)); - - internal static readonly DirectProperty EffectiveInnerBoxPaddingProperty = - AvaloniaProperty.RegisterDirect(nameof(EffectiveInnerBoxPadding), - o => o.EffectiveInnerBoxPadding, - (o, v) => o.EffectiveInnerBoxPadding = v); - - internal static readonly DirectProperty ContentPresenterMarginProperty = - AvaloniaProperty.RegisterDirect(nameof(ContentPresenterMargin), - o => o.ContentPresenterMargin, - (o, v) => o.ContentPresenterMargin = v); - - private static readonly DirectProperty MarginXSTokenProperty = - AvaloniaProperty.RegisterDirect(nameof(MarginXSToken), - o => o.MarginXSToken, - (o, v) => o.MarginXSToken = v); - internal Thickness InnerBoxPadding - { - get => GetValue(InnerBoxPaddingProperty); - set => SetValue(InnerBoxPaddingProperty, value); - } - - private Thickness _effectiveInnerBoxPadding; + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + TokenResourceBinder.CreateGlobalResourceBinding(this, MarginXSTokenProperty, GlobalTokenResourceKey.MarginXS); + _leftAddOnLayout = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.LeftAddOnLayoutPart); + _rightAddOnLayout = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.RightAddOnLayoutPart); + _clearButton = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.ClearButtonPart); - internal Thickness EffectiveInnerBoxPadding - { - get => _effectiveInnerBoxPadding; - set => SetAndRaise(EffectiveInnerBoxPaddingProperty, ref _effectiveInnerBoxPadding, value); - } - - private double _marginXSToken; + if (_leftAddOnLayout is not null) _leftAddOnLayout.SizeChanged += HandleLayoutSizeChanged; + if (_rightAddOnLayout is not null) _rightAddOnLayout.SizeChanged += HandleLayoutSizeChanged; - private double MarginXSToken - { - get => _marginXSToken; - set => SetAndRaise(MarginXSTokenProperty, ref _marginXSToken, value); - } + if (_clearButton is not null) + _clearButton.Click += (sender, args) => { NotifyClearButtonClicked(); }; - private Thickness _contentPresenterMargin; + SetupContentPresenterMargin(); + BuildEffectiveInnerBoxPadding(); + } - internal Thickness ContentPresenterMargin - { - get => _contentPresenterMargin; - set => SetAndRaise(ContentPresenterMarginProperty, ref _contentPresenterMargin, value); - } - - #endregion + private void HandleLayoutSizeChanged(object? sender, SizeChangedEventArgs args) + { + SetupContentPresenterMargin(); + } - private StackPanel? _leftAddOnLayout; - private StackPanel? _rightAddOnLayout; - private IconButton? _clearButton; + private void SetupContentPresenterMargin() + { + var marginLeft = 0d; + var marginRight = 0d; + if (_leftAddOnLayout is not null) + if (_leftAddOnLayout.DesiredSize.Width > 0 && _leftAddOnLayout.DesiredSize.Height > 0) + marginLeft = _marginXSToken; + if (_rightAddOnLayout is not null) + if (_rightAddOnLayout.DesiredSize.Width > 0 && _rightAddOnLayout.DesiredSize.Height > 0) + marginRight = _marginXSToken; - protected virtual void NotifyClearButtonClicked() { } + ContentPresenterMargin = new Thickness(marginLeft, 0, marginRight, 0); + } - protected virtual void BuildEffectiveInnerBoxPadding() - { - BindUtils.RelayBind(this, InnerBoxPaddingProperty, this, EffectiveInnerBoxPaddingProperty); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - if (change.Property == LeftAddOnContentProperty || change.Property == RightAddOnContentProperty) { - if (change.OldValue is Control oldControl) { - UIStructureUtils.SetTemplateParent(oldControl, null); - } - if (change.NewValue is Control newControl) { - UIStructureUtils.SetTemplateParent(newControl, this); - } - } - - } - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - TokenResourceBinder.CreateGlobalResourceBinding(this, MarginXSTokenProperty, GlobalTokenResourceKey.MarginXS); - _leftAddOnLayout = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.LeftAddOnLayoutPart); - _rightAddOnLayout = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.RightAddOnLayoutPart); - _clearButton = e.NameScope.Find(AddOnDecoratedInnerBoxTheme.ClearButtonPart); + #region 公共属性定义 - if (_leftAddOnLayout is not null) { - _leftAddOnLayout.SizeChanged += HandleLayoutSizeChanged; - } - if (_rightAddOnLayout is not null) { - _rightAddOnLayout.SizeChanged += HandleLayoutSizeChanged; - } - - if (_clearButton is not null) { - _clearButton.Click += (sender, args) => - { - NotifyClearButtonClicked(); - }; - } - - SetupContentPresenterMargin(); - BuildEffectiveInnerBoxPadding(); - } + public static readonly StyledProperty SizeTypeProperty = + AddOnDecoratedBox.SizeTypeProperty.AddOwner(); - private void HandleLayoutSizeChanged(object? sender, SizeChangedEventArgs args) - { - SetupContentPresenterMargin(); - } + public static readonly StyledProperty StyleVariantProperty = + AddOnDecoratedBox.StyleVariantProperty.AddOwner(); - private void SetupContentPresenterMargin() - { - var marginLeft = 0d; - var marginRight = 0d; - if (_leftAddOnLayout is not null) { - if (_leftAddOnLayout.DesiredSize.Width > 0 && _leftAddOnLayout.DesiredSize.Height > 0) { - marginLeft = _marginXSToken; - } - } - if (_rightAddOnLayout is not null) { - if (_rightAddOnLayout.DesiredSize.Width > 0 && _rightAddOnLayout.DesiredSize.Height > 0) { - marginRight = _marginXSToken; - } - } + public static readonly StyledProperty StatusProperty = + AddOnDecoratedBox.StatusProperty.AddOwner(); - ContentPresenterMargin = new Thickness(marginLeft, 0, marginRight, 0); - } - + public static readonly StyledProperty LeftAddOnContentProperty = + AvaloniaProperty.Register(nameof(LeftAddOnContent)); + + public static readonly StyledProperty RightAddOnContentProperty = + AvaloniaProperty.Register(nameof(RightAddOnContent)); + + public static readonly StyledProperty IsClearButtonVisibleProperty = + AvaloniaProperty.Register(nameof(IsClearButtonVisible)); + + public SizeType SizeType + { + get => GetValue(SizeTypeProperty); + set => SetValue(SizeTypeProperty, value); + } + + public AddOnDecoratedVariant StyleVariant + { + get => GetValue(StyleVariantProperty); + set => SetValue(StyleVariantProperty, value); + } + + public AddOnDecoratedStatus Status + { + get => GetValue(StatusProperty); + set => SetValue(StatusProperty, value); + } + + public object? LeftAddOnContent + { + get => GetValue(LeftAddOnContentProperty); + set => SetValue(LeftAddOnContentProperty, value); + } + + public object? RightAddOnContent + { + get => GetValue(RightAddOnContentProperty); + set => SetValue(RightAddOnContentProperty, value); + } + + public bool IsClearButtonVisible + { + get => GetValue(IsClearButtonVisibleProperty); + set => SetValue(IsClearButtonVisibleProperty, value); + } + + #endregion + + + + #region 内部属性定义 + + internal static readonly StyledProperty InnerBoxPaddingProperty = + AvaloniaProperty.Register(nameof(InnerBoxPadding)); + + internal static readonly DirectProperty EffectiveInnerBoxPaddingProperty = + AvaloniaProperty.RegisterDirect(nameof(EffectiveInnerBoxPadding), + o => o.EffectiveInnerBoxPadding, + (o, v) => o.EffectiveInnerBoxPadding = v); + + internal static readonly DirectProperty ContentPresenterMarginProperty = + AvaloniaProperty.RegisterDirect(nameof(ContentPresenterMargin), + o => o.ContentPresenterMargin, + (o, v) => o.ContentPresenterMargin = v); + + private static readonly DirectProperty MarginXSTokenProperty = + AvaloniaProperty.RegisterDirect(nameof(MarginXSToken), + o => o.MarginXSToken, + (o, v) => o.MarginXSToken = v); + + internal Thickness InnerBoxPadding + { + get => GetValue(InnerBoxPaddingProperty); + set => SetValue(InnerBoxPaddingProperty, value); + } + + private Thickness _effectiveInnerBoxPadding; + + internal Thickness EffectiveInnerBoxPadding + { + get => _effectiveInnerBoxPadding; + set => SetAndRaise(EffectiveInnerBoxPaddingProperty, ref _effectiveInnerBoxPadding, value); + } + + private double _marginXSToken; + + private double MarginXSToken + { + get => _marginXSToken; + set => SetAndRaise(MarginXSTokenProperty, ref _marginXSToken, value); + } + + private Thickness _contentPresenterMargin; + + internal Thickness ContentPresenterMargin + { + get => _contentPresenterMargin; + set => SetAndRaise(ContentPresenterMarginProperty, ref _contentPresenterMargin, value); + } + + #endregion } \ No newline at end of file diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs index 011343c..db4ea93 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedInnerBoxTheme.cs @@ -3,9 +3,11 @@ using AtomUI.Theme; using AtomUI.Theme.Data; using AtomUI.Theme.Styling; using AtomUI.Theme.Utils; +using Avalonia; using Avalonia.Animation; using Avalonia.Controls; using Avalonia.Controls.Presenters; +using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Layout; using Avalonia.Styling; @@ -15,492 +17,521 @@ namespace AtomUI.Controls; [ControlThemeProvider] internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme { - public const string MainLayoutPart = "PART_MainLayout"; - public const string ContentPresenterPart = "PART_ContentPresenter"; - public const string LeftAddOnPart = "PART_LeftAddOn"; - public const string RightAddOnPart = "PART_RightAddOn"; - public const string LeftAddOnLayoutPart = "PART_LeftAddOnLayout"; - public const string RightAddOnLayoutPart = "PART_RightAddOnLayout"; - public const string ClearButtonPart = "PART_ClearButton"; - public const string InnerBoxDecoratorPart = "PART_InnerBoxDecorator"; + public const string MainLayoutPart = "PART_MainLayout"; + public const string ContentPresenterPart = "PART_ContentPresenter"; + public const string LeftAddOnPart = "PART_LeftAddOn"; + public const string RightAddOnPart = "PART_RightAddOn"; + public const string LeftAddOnLayoutPart = "PART_LeftAddOnLayout"; + public const string RightAddOnLayoutPart = "PART_RightAddOnLayout"; + public const string ClearButtonPart = "PART_ClearButton"; + public const string InnerBoxDecoratorPart = "PART_InnerBoxDecorator"; - public AddOnDecoratedInnerBoxTheme() : base(typeof(AddOnDecoratedInnerBox)) {} - protected AddOnDecoratedInnerBoxTheme(Type targetType) : base(targetType) { } + public AddOnDecoratedInnerBoxTheme() : base(typeof(AddOnDecoratedInnerBox)) + { + } - protected override IControlTemplate BuildControlTemplate() - { - return new FuncControlTemplate((decoratedBox, scope) => - { - var frameLayout = new Panel(); - BuildFrameDecorator(frameLayout, decoratedBox, scope); - NotifyBuildExtraChild(frameLayout, decoratedBox, scope); - return frameLayout; - }); - } + protected AddOnDecoratedInnerBoxTheme(Type targetType) : base(targetType) + { + } - protected virtual void NotifyBuildExtraChild(Panel layout, AddOnDecoratedInnerBox decoratedBox, INameScope scope) - { - } + protected override IControlTemplate BuildControlTemplate() + { + return new FuncControlTemplate((decoratedBox, scope) => + { + var frameLayout = new Panel(); + BuildFrameDecorator(frameLayout, decoratedBox, scope); + NotifyBuildExtraChild(frameLayout, decoratedBox, scope); + return frameLayout; + }); + } - protected virtual void BuildFrameDecorator(Panel layout, AddOnDecoratedInnerBox decoratedBox, INameScope scope) - { - var innerBoxDecorator = new Border() - { - Name = InnerBoxDecoratorPart, - Transitions = new Transitions() - { - AnimationUtils.CreateTransition(Border.BorderBrushProperty), - AnimationUtils.CreateTransition(Border.BackgroundProperty) - } - }; - - innerBoxDecorator.RegisterInNameScope(scope); - CreateTemplateParentBinding(innerBoxDecorator, Border.PaddingProperty, AddOnDecoratedInnerBox.EffectiveInnerBoxPaddingProperty); - CreateTemplateParentBinding(innerBoxDecorator, Border.BorderThicknessProperty, AddOnDecoratedInnerBox.BorderThicknessProperty); - CreateTemplateParentBinding(innerBoxDecorator, Border.CornerRadiusProperty, AddOnDecoratedInnerBox.CornerRadiusProperty); - - var mainLayout = BuildBoxMainLayout(decoratedBox, scope); - innerBoxDecorator.Child = mainLayout; - - layout.Children.Add(innerBoxDecorator); - } + protected virtual void NotifyBuildExtraChild(Panel layout, AddOnDecoratedInnerBox decoratedBox, INameScope scope) + { + } - protected virtual Panel BuildBoxMainLayout(AddOnDecoratedInnerBox decoratedBox, INameScope scope) - { - var mainLayout = new Grid() - { - Name = MainLayoutPart, - ColumnDefinitions = new ColumnDefinitions() - { - new ColumnDefinition(GridLength.Auto), - new ColumnDefinition(GridLength.Star), - new ColumnDefinition(GridLength.Auto) - } - }; - BuildGridChildren(decoratedBox, mainLayout, scope); - return mainLayout; - } + protected virtual void BuildFrameDecorator(Panel layout, AddOnDecoratedInnerBox decoratedBox, INameScope scope) + { + var innerBoxDecorator = new Border + { + Name = InnerBoxDecoratorPart, + Transitions = new Transitions + { + AnimationUtils.CreateTransition(Border.BorderBrushProperty), + AnimationUtils.CreateTransition(Border.BackgroundProperty) + } + }; - protected virtual void BuildGridChildren(AddOnDecoratedInnerBox decoratedBox, Grid mainLayout, INameScope scope) - { - BuildLeftAddOn(mainLayout, scope); - BuildContent(decoratedBox, mainLayout, scope); - BuildRightAddOn(mainLayout, scope); - } + innerBoxDecorator.RegisterInNameScope(scope); + CreateTemplateParentBinding(innerBoxDecorator, Decorator.PaddingProperty, + AddOnDecoratedInnerBox.EffectiveInnerBoxPaddingProperty); + CreateTemplateParentBinding(innerBoxDecorator, Border.BorderThicknessProperty, + TemplatedControl.BorderThicknessProperty); + CreateTemplateParentBinding(innerBoxDecorator, Border.CornerRadiusProperty, + TemplatedControl.CornerRadiusProperty); - protected virtual void BuildLeftAddOn(Grid layout, INameScope scope) - { - // 理论上可以支持多个,暂时先支持一个 - var addLayout = new StackPanel() - { - Name = LeftAddOnLayoutPart, - Orientation = Orientation.Horizontal, - }; - TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalTokenResourceKey.PaddingXXS); - addLayout.RegisterInNameScope(scope); - - var leftAddOnContentPresenter = new ContentPresenter() - { - Name = LeftAddOnPart, - VerticalAlignment = VerticalAlignment.Stretch, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Left, - Focusable = false, - }; + var mainLayout = BuildBoxMainLayout(decoratedBox, scope); + innerBoxDecorator.Child = mainLayout; - CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty, - AddOnDecoratedInnerBox.LeftAddOnContentProperty); - leftAddOnContentPresenter.RegisterInNameScope(scope); + layout.Children.Add(innerBoxDecorator); + } - addLayout.Children.Add(leftAddOnContentPresenter); + protected virtual Panel BuildBoxMainLayout(AddOnDecoratedInnerBox decoratedBox, INameScope scope) + { + var mainLayout = new Grid + { + Name = MainLayoutPart, + ColumnDefinitions = new ColumnDefinitions + { + new(GridLength.Auto), + new(GridLength.Star), + new(GridLength.Auto) + } + }; + BuildGridChildren(decoratedBox, mainLayout, scope); + return mainLayout; + } - Grid.SetColumn(addLayout, 0); - layout.Children.Add(addLayout); - } + protected virtual void BuildGridChildren(AddOnDecoratedInnerBox decoratedBox, Grid mainLayout, INameScope scope) + { + BuildLeftAddOn(mainLayout, scope); + BuildContent(decoratedBox, mainLayout, scope); + BuildRightAddOn(mainLayout, scope); + } - protected virtual void BuildContent(AddOnDecoratedInnerBox decoratedBox, Grid layout, INameScope scope) - { - var innerBox = new ContentPresenter() - { - Name = ContentPresenterPart, - }; - innerBox.RegisterInNameScope(scope); + protected virtual void BuildLeftAddOn(Grid layout, INameScope scope) + { + // 理论上可以支持多个,暂时先支持一个 + var addLayout = new StackPanel + { + Name = LeftAddOnLayoutPart, + Orientation = Orientation.Horizontal + }; + TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, + GlobalTokenResourceKey.PaddingXXS); + addLayout.RegisterInNameScope(scope); - CreateTemplateParentBinding(innerBox, ContentPresenter.MarginProperty, AddOnDecoratedInnerBox.ContentPresenterMarginProperty); - CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, AddOnDecoratedInnerBox.ContentProperty); - CreateTemplateParentBinding(innerBox, ContentPresenter.ContentTemplateProperty, - AddOnDecoratedInnerBox.ContentTemplateProperty); + var leftAddOnContentPresenter = new ContentPresenter + { + Name = LeftAddOnPart, + VerticalAlignment = VerticalAlignment.Stretch, + VerticalContentAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Left, + Focusable = false + }; - layout.Children.Add(innerBox); - Grid.SetColumn(innerBox, 1); - } + CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty, + AddOnDecoratedInnerBox.LeftAddOnContentProperty); + leftAddOnContentPresenter.RegisterInNameScope(scope); - private void BuildRightAddOn(Grid layout, INameScope scope) - { - var addLayout = new StackPanel() - { - Name = RightAddOnLayoutPart, - Orientation = Orientation.Horizontal - }; - TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalTokenResourceKey.PaddingXXS); - addLayout.RegisterInNameScope(scope); - - BuildRightAddOnItems(addLayout, scope); - - var rightAddOnContentPresenter = new ContentPresenter() - { - Name = RightAddOnPart, - VerticalAlignment = VerticalAlignment.Stretch, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Right, - Focusable = false - }; - CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty, - AddOnDecoratedInnerBox.RightAddOnContentProperty); + addLayout.Children.Add(leftAddOnContentPresenter); - rightAddOnContentPresenter.RegisterInNameScope(scope); - addLayout.Children.Add(rightAddOnContentPresenter); + Grid.SetColumn(addLayout, 0); + layout.Children.Add(addLayout); + } - layout.Children.Add(addLayout); - Grid.SetColumn(addLayout, 2); - } + protected virtual void BuildContent(AddOnDecoratedInnerBox decoratedBox, Grid layout, INameScope scope) + { + var innerBox = new ContentPresenter + { + Name = ContentPresenterPart + }; + innerBox.RegisterInNameScope(scope); - protected virtual void BuildRightAddOnItems(StackPanel layout, INameScope scope) - { - BuildClearButton(layout, scope); - } + CreateTemplateParentBinding(innerBox, Layoutable.MarginProperty, + AddOnDecoratedInnerBox.ContentPresenterMarginProperty); + CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, ContentControl.ContentProperty); + CreateTemplateParentBinding(innerBox, ContentPresenter.ContentTemplateProperty, + ContentControl.ContentTemplateProperty); - protected virtual void BuildClearButton(StackPanel addOnLayout, INameScope scope) - { - var closeIcon = new PathIcon() - { - Kind = "CloseCircleFilled" - }; - var clearButton = new IconButton() - { - Name = ClearButtonPart, - Icon = closeIcon - }; + layout.Children.Add(innerBox); + Grid.SetColumn(innerBox, 1); + } - TokenResourceBinder.CreateGlobalTokenBinding(clearButton, IconButton.IconHeightProperty, GlobalTokenResourceKey.IconSize); - TokenResourceBinder.CreateGlobalTokenBinding(clearButton, IconButton.IconWidthProperty, GlobalTokenResourceKey.IconSize); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty, - GlobalTokenResourceKey.ColorTextQuaternary); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty, - GlobalTokenResourceKey.ColorTextTertiary); - TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty, - GlobalTokenResourceKey.ColorText); + private void BuildRightAddOn(Grid layout, INameScope scope) + { + var addLayout = new StackPanel + { + Name = RightAddOnLayoutPart, + Orientation = Orientation.Horizontal + }; + TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, + GlobalTokenResourceKey.PaddingXXS); + addLayout.RegisterInNameScope(scope); - clearButton.RegisterInNameScope(scope); - CreateTemplateParentBinding(clearButton, IconButton.IsVisibleProperty, - AddOnDecoratedInnerBox.IsClearButtonVisibleProperty); - addOnLayout.Children.Add(clearButton); - } + BuildRightAddOnItems(addLayout, scope); - protected override void BuildStyles() - { - BuildCommonStyle(); - BuildDisabledStyle(); - BuildOutLineStyle(); - BuildFilledStyle(); - BuildAddOnStyle(); - } - - private void BuildCommonStyle() - { - var commonStyle = new Style(selector => selector.Nesting()); - - var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - decoratorStyle.Add(Border.ZIndexProperty, AddOnDecoratedBoxTheme.NormalZIndex); - commonStyle.Add(decoratorStyle); - - var largeStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Large)); - largeStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingLG); - - { - var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); - innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeightLG); - innerBoxContentStyle.Add(Border.MinHeightProperty, GlobalTokenResourceKey.FontHeightLG); - largeStyle.Add(innerBoxContentStyle); - } - { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); - iconStyle.Add(PathIcon.WidthProperty, GlobalTokenResourceKey.IconSizeLG); - iconStyle.Add(PathIcon.HeightProperty, GlobalTokenResourceKey.IconSizeLG); - largeStyle.Add(iconStyle); - } - commonStyle.Add(largeStyle); + var rightAddOnContentPresenter = new ContentPresenter + { + Name = RightAddOnPart, + VerticalAlignment = VerticalAlignment.Stretch, + VerticalContentAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Right, + Focusable = false + }; + CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty, + AddOnDecoratedInnerBox.RightAddOnContentProperty); - var middleStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Middle)); - middleStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.Padding); - { - var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); - innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeight); - innerBoxContentStyle.Add(Border.MinHeightProperty, GlobalTokenResourceKey.FontHeight); - middleStyle.Add(innerBoxContentStyle); - } - { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); - iconStyle.Add(PathIcon.WidthProperty, GlobalTokenResourceKey.IconSize); - iconStyle.Add(PathIcon.HeightProperty, GlobalTokenResourceKey.IconSize); - middleStyle.Add(iconStyle); - } - commonStyle.Add(middleStyle); + rightAddOnContentPresenter.RegisterInNameScope(scope); + addLayout.Children.Add(rightAddOnContentPresenter); - var smallStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Small)); - smallStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingSM); - { - var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); - innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeightSM); - innerBoxContentStyle.Add(Border.MinHeightProperty, GlobalTokenResourceKey.FontHeightSM); - smallStyle.Add(innerBoxContentStyle); - } - { - var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); - iconStyle.Add(PathIcon.WidthProperty, GlobalTokenResourceKey.IconSizeSM); - iconStyle.Add(PathIcon.HeightProperty, GlobalTokenResourceKey.IconSizeSM); - smallStyle.Add(iconStyle); - } - commonStyle.Add(smallStyle); - - Add(commonStyle); - } - - private void BuildOutLineStyle() - { - var outlineStyle = - new Style(selector => selector.Nesting() - .PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Outline)); + layout.Children.Add(addLayout); + Grid.SetColumn(addLayout, 2); + } - { - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorTransparent); - outlineStyle.Add(innerBoxDecoratorStyle); - } + protected virtual void BuildRightAddOnItems(StackPanel layout, INameScope scope) + { + BuildClearButton(layout, scope); + } - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxTokenResourceKey.HoverBorderColor); - hoverStyle.Add(innerBoxDecoratorStyle); - } + protected virtual void BuildClearButton(StackPanel addOnLayout, INameScope scope) + { + var closeIcon = new PathIcon + { + Kind = "CloseCircleFilled" + }; + var clearButton = new IconButton + { + Name = ClearButtonPart, + Icon = closeIcon + }; - outlineStyle.Add(hoverStyle); + TokenResourceBinder.CreateGlobalTokenBinding(clearButton, IconButton.IconHeightProperty, + GlobalTokenResourceKey.IconSize); + TokenResourceBinder.CreateGlobalTokenBinding(clearButton, IconButton.IconWidthProperty, + GlobalTokenResourceKey.IconSize); + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty, + GlobalTokenResourceKey.ColorTextQuaternary); + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty, + GlobalTokenResourceKey.ColorTextTertiary); + TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty, + GlobalTokenResourceKey.ColorText); - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBorderColor); - focusStyle.Add(innerBoxDecoratorStyle); - } - outlineStyle.Add(focusStyle); - } - { - var errorStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); - - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); - errorStyle.Add(innerBoxDecoratorStyle); - } - - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorErrorBorderHover); - hoverStyle.Add(innerBoxDecoratorStyle); - } - errorStyle.Add(hoverStyle); - - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); - focusStyle.Add(innerBoxDecoratorStyle); - } - errorStyle.Add(focusStyle); - outlineStyle.Add(errorStyle); - } - - { - var warningStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); - - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); - warningStyle.Add(innerBoxDecoratorStyle); - } - - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarningBorderHover); - hoverStyle.Add(innerBoxDecoratorStyle); - } - warningStyle.Add(hoverStyle); - - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); - focusStyle.Add(innerBoxDecoratorStyle); - } - warningStyle.Add(focusStyle); - outlineStyle.Add(warningStyle); - } + clearButton.RegisterInNameScope(scope); + CreateTemplateParentBinding(clearButton, Visual.IsVisibleProperty, + AddOnDecoratedInnerBox.IsClearButtonVisibleProperty); + addOnLayout.Children.Add(clearButton); + } - Add(outlineStyle); - } - - private void BuildFilledStyle() - { - var filledStyle = - new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Filled)); + protected override void BuildStyles() + { + BuildCommonStyle(); + BuildDisabledStyle(); + BuildOutLineStyle(); + BuildFilledStyle(); + BuildAddOnStyle(); + } - { - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorFillTertiary); - filledStyle.Add(innerBoxDecoratorStyle); - } + private void BuildCommonStyle() + { + var commonStyle = new Style(selector => selector.Nesting()); - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorFillSecondary); - hoverStyle.Add(innerBoxDecoratorStyle); - } - filledStyle.Add(hoverStyle); + var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + decoratorStyle.Add(Visual.ZIndexProperty, AddOnDecoratedBoxTheme.NormalZIndex); + commonStyle.Add(decoratorStyle); - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBorderColor); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorTransparent); - focusStyle.Add(innerBoxDecoratorStyle); - } - filledStyle.Add(focusStyle); - } + var largeStyle = + new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Large)); + largeStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingLG); - { - var errorStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); + { + var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); + innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeightLG); + innerBoxContentStyle.Add(Layoutable.MinHeightProperty, GlobalTokenResourceKey.FontHeightLG); + largeStyle.Add(innerBoxContentStyle); + } + { + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSizeLG); + iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSizeLG); + largeStyle.Add(iconStyle); + } + commonStyle.Add(largeStyle); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + var middleStyle = + new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Middle)); + middleStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.Padding); + { + var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); + innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeight); + innerBoxContentStyle.Add(Layoutable.MinHeightProperty, GlobalTokenResourceKey.FontHeight); + middleStyle.Add(innerBoxContentStyle); + } + { + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSize); + iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSize); + middleStyle.Add(iconStyle); + } + commonStyle.Add(middleStyle); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorErrorBg); - errorStyle.Add(innerBoxDecoratorStyle); - } + var smallStyle = + new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Small)); + smallStyle.Add(AddOnDecoratedInnerBox.InnerBoxPaddingProperty, AddOnDecoratedBoxTokenResourceKey.PaddingSM); + { + var innerBoxContentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); + innerBoxContentStyle.Add(TextBlock.LineHeightProperty, GlobalTokenResourceKey.FontHeightSM); + innerBoxContentStyle.Add(Layoutable.MinHeightProperty, GlobalTokenResourceKey.FontHeightSM); + smallStyle.Add(innerBoxContentStyle); + } + { + var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType()); + iconStyle.Add(Layoutable.WidthProperty, GlobalTokenResourceKey.IconSizeSM); + iconStyle.Add(Layoutable.HeightProperty, GlobalTokenResourceKey.IconSizeSM); + smallStyle.Add(iconStyle); + } + commonStyle.Add(smallStyle); - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorErrorBgHover); - hoverStyle.Add(innerBoxDecoratorStyle); - } - errorStyle.Add(hoverStyle); + Add(commonStyle); + } - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBg); - focusStyle.Add(innerBoxDecoratorStyle); - } + private void BuildOutLineStyle() + { + var outlineStyle = + new Style(selector => selector.Nesting() + .PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Outline)); - errorStyle.Add(focusStyle); - filledStyle.Add(errorStyle); - } + { + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorTransparent); + outlineStyle.Add(innerBoxDecoratorStyle); + } - { - var warningStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, + AddOnDecoratedBoxTokenResourceKey.HoverBorderColor); + hoverStyle.Add(innerBoxDecoratorStyle); + } - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + outlineStyle.Add(hoverStyle); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorWarningBg); - warningStyle.Add(innerBoxDecoratorStyle); - } + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, + AddOnDecoratedBoxTokenResourceKey.ActiveBorderColor); + focusStyle.Add(innerBoxDecoratorStyle); + } + outlineStyle.Add(focusStyle); + } + { + var errorStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); - var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorWarningBgHover); - hoverStyle.Add(innerBoxDecoratorStyle); - } - warningStyle.Add(hoverStyle); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); + errorStyle.Add(innerBoxDecoratorStyle); + } - var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); - { - var innerBoxDecoratorStyle = - new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); - innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBg); - focusStyle.Add(innerBoxDecoratorStyle); - } - warningStyle.Add(focusStyle); - - filledStyle.Add(warningStyle); - } + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorErrorBorderHover); + hoverStyle.Add(innerBoxDecoratorStyle); + } + errorStyle.Add(hoverStyle); - Add(filledStyle); - } + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); + focusStyle.Add(innerBoxDecoratorStyle); + } + errorStyle.Add(focusStyle); + outlineStyle.Add(errorStyle); + } - private void BuildAddOnStyle() - { - { - var errorStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); - { - var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); - iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); - errorStyle.Add(iconStyle); - } - Add(errorStyle); - } + { + var warningStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); - { - var warningStyle = new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); - { - var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), - selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); - iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); - warningStyle.Add(iconStyle); - } - Add(warningStyle); - } - } + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); + warningStyle.Add(innerBoxDecoratorStyle); + } - protected virtual void BuildDisabledStyle() - { - var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled)); - var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); - decoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainerDisabled); - disabledStyle.Add(decoratorStyle); - Add(disabledStyle); - } + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarningBorderHover); + hoverStyle.Add(innerBoxDecoratorStyle); + } + warningStyle.Add(hoverStyle); + + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); + focusStyle.Add(innerBoxDecoratorStyle); + } + warningStyle.Add(focusStyle); + outlineStyle.Add(warningStyle); + } + + Add(outlineStyle); + } + + private void BuildFilledStyle() + { + var filledStyle = + new Style(selector => + selector.Nesting() + .PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Filled)); + + { + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorFillTertiary); + filledStyle.Add(innerBoxDecoratorStyle); + } + + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorFillSecondary); + hoverStyle.Add(innerBoxDecoratorStyle); + } + filledStyle.Add(hoverStyle); + + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, + AddOnDecoratedBoxTokenResourceKey.ActiveBorderColor); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorTransparent); + focusStyle.Add(innerBoxDecoratorStyle); + } + filledStyle.Add(focusStyle); + } + + { + var errorStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); + + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorErrorBg); + errorStyle.Add(innerBoxDecoratorStyle); + } + + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorErrorBgHover); + hoverStyle.Add(innerBoxDecoratorStyle); + } + errorStyle.Add(hoverStyle); + + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorError); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBg); + focusStyle.Add(innerBoxDecoratorStyle); + } + + errorStyle.Add(focusStyle); + filledStyle.Add(errorStyle); + } + + { + var warningStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); + + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorTransparent); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorWarningBg); + warningStyle.Add(innerBoxDecoratorStyle); + } + + var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorWarningBgHover); + hoverStyle.Add(innerBoxDecoratorStyle); + } + warningStyle.Add(hoverStyle); + + var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn)); + { + var innerBoxDecoratorStyle = + new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalTokenResourceKey.ColorWarning); + innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxTokenResourceKey.ActiveBg); + focusStyle.Add(innerBoxDecoratorStyle); + } + warningStyle.Add(focusStyle); + + filledStyle.Add(warningStyle); + } + + Add(filledStyle); + } + + private void BuildAddOnStyle() + { + { + var errorStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Error)); + { + var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), + selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); + iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorError); + errorStyle.Add(iconStyle); + } + Add(errorStyle); + } + + { + var warningStyle = new Style(selector => + selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.StatusProperty, AddOnDecoratedStatus.Warning)); + { + var iconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart), + selector.Nesting().Template().Name(RightAddOnPart)).Nesting().Descendant().OfType()); + iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorWarning); + warningStyle.Add(iconStyle); + } + Add(warningStyle); + } + } + + protected virtual void BuildDisabledStyle() + { + var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled)); + var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)); + decoratorStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainerDisabled); + disabledStyle.Add(decoratorStyle); + Add(disabledStyle); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Alert/Alert.cs b/src/AtomUI.Controls/Alert/Alert.cs index d00dfdc..14f17d1 100644 --- a/src/AtomUI.Controls/Alert/Alert.cs +++ b/src/AtomUI.Controls/Alert/Alert.cs @@ -10,151 +10,154 @@ namespace AtomUI.Controls; public enum AlertType { - Success, - Info, - Warning, - Error + Success, + Info, + Warning, + Error } + public class Alert : TemplatedControl, IControlCustomStyle { - public static readonly StyledProperty TypeProperty = - AvaloniaProperty.Register(nameof(Type)); + public static readonly StyledProperty TypeProperty = + AvaloniaProperty.Register(nameof(Type)); - public static readonly StyledProperty IsShowIconProperty = - AvaloniaProperty.Register(nameof(IsShowIcon)); + public static readonly StyledProperty IsShowIconProperty = + AvaloniaProperty.Register(nameof(IsShowIcon)); - public static readonly StyledProperty IsMessageMarqueEnabledProperty = - AvaloniaProperty.Register(nameof(IsMessageMarqueEnabled)); + public static readonly StyledProperty IsMessageMarqueEnabledProperty = + AvaloniaProperty.Register(nameof(IsMessageMarqueEnabled)); - public static readonly StyledProperty IsClosableProperty = - AvaloniaProperty.Register(nameof(IsClosable)); + public static readonly StyledProperty IsClosableProperty = + AvaloniaProperty.Register(nameof(IsClosable)); + + public static readonly StyledProperty CloseIconProperty = + AvaloniaProperty.Register(nameof(CloseIcon)); + + public static readonly StyledProperty MessageProperty = + AvaloniaProperty.Register(nameof(Message)); + + public static readonly StyledProperty DescriptionProperty = + AvaloniaProperty.Register(nameof(Description)); + + public static readonly StyledProperty ExtraActionProperty = + AvaloniaProperty.Register(nameof(Description)); + + private readonly IControlCustomStyle _customStyle; + + static Alert() + { + AffectsMeasure(IsClosableProperty, + IsShowIconProperty, + MessageProperty, + DescriptionProperty, + IsMessageMarqueEnabledProperty, + PaddingProperty, + ExtraActionProperty, + IsMessageMarqueEnabledProperty); + AffectsRender(TypeProperty); + } + + public Alert() + { + _customStyle = this; + _customStyle.InitOnConstruct(); + } + + public AlertType Type + { + get => GetValue(TypeProperty); + set => SetValue(TypeProperty, value); + } + + public bool IsShowIcon + { + get => GetValue(IsShowIconProperty); + set => SetValue(IsShowIconProperty, value); + } + + public bool IsMessageMarqueEnabled + { + get => GetValue(IsMessageMarqueEnabledProperty); + set => SetValue(IsMessageMarqueEnabledProperty, value); + } + + public bool IsClosable + { + get => GetValue(IsClosableProperty); + set => SetValue(IsClosableProperty, value); + } + + public PathIcon? CloseIcon + { + get => GetValue(CloseIconProperty); + set => SetValue(CloseIconProperty, value); + } + + [Content] + public string Message + { + get => GetValue(MessageProperty); + set => SetValue(MessageProperty, value); + } + + public string? Description + { + get => GetValue(DescriptionProperty); + set => SetValue(DescriptionProperty, value); + } + + public Control? ExtraAction + { + get => GetValue(ExtraActionProperty); + set => SetValue(ExtraActionProperty, value); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + _customStyle.HandlePropertyChangedForStyle(e); + } + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + _customStyle.HandleTemplateApplied(e.NameScope); + } - public static readonly StyledProperty CloseIconProperty = - AvaloniaProperty.Register(nameof(CloseIcon)); - public static readonly StyledProperty MessageProperty = - AvaloniaProperty.Register(nameof(Message)); + #region IControlCustomStyle 实现 - public static readonly StyledProperty DescriptionProperty = - AvaloniaProperty.Register(nameof(Description)); + void IControlCustomStyle.HandleTemplateApplied(INameScope scope) + { + TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty, GlobalTokenResourceKey.BorderThickness, + BindingPriority.Template, + new RenderScaleAwareThicknessConfigure(this)); + SetupCloseButton(); + } - public static readonly StyledProperty ExtraActionProperty = - AvaloniaProperty.Register(nameof(Description)); + void IControlCustomStyle.HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e) + { + if (VisualRoot is not null) + if (e.Property == IsClosableProperty) + SetupCloseButton(); + } - public AlertType Type - { - get => GetValue(TypeProperty); - set => SetValue(TypeProperty, value); - } + private void SetupCloseButton() + { + if (CloseIcon is null) + { + CloseIcon = new PathIcon + { + Kind = "CloseOutlined" + }; + TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.NormalFilledBrushProperty, + GlobalTokenResourceKey.ColorIcon); + TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.ActiveFilledBrushProperty, + GlobalTokenResourceKey.ColorIconHover); + } + } - public bool IsShowIcon - { - get => GetValue(IsShowIconProperty); - set => SetValue(IsShowIconProperty, value); - } - - public bool IsMessageMarqueEnabled - { - get => GetValue(IsMessageMarqueEnabledProperty); - set => SetValue(IsMessageMarqueEnabledProperty, value); - } - - public bool IsClosable - { - get => GetValue(IsClosableProperty); - set => SetValue(IsClosableProperty, value); - } - - public PathIcon? CloseIcon - { - get => GetValue(CloseIconProperty); - set => SetValue(CloseIconProperty, value); - } - - [Content] - public string Message - { - get => GetValue(MessageProperty); - set => SetValue(MessageProperty, value); - } - - public string? Description - { - get => GetValue(DescriptionProperty); - set => SetValue(DescriptionProperty, value); - } - - public Control? ExtraAction - { - get => GetValue(ExtraActionProperty); - set => SetValue(ExtraActionProperty, value); - } - - private readonly IControlCustomStyle _customStyle; - - static Alert() - { - AffectsMeasure(IsClosableProperty, - IsShowIconProperty, - MessageProperty, - DescriptionProperty, - IsMessageMarqueEnabledProperty, - PaddingProperty, - ExtraActionProperty, - IsMessageMarqueEnabledProperty); - AffectsRender(TypeProperty); - } - - public Alert() - { - _customStyle = this; - _customStyle.InitOnConstruct(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) - { - base.OnPropertyChanged(e); - _customStyle.HandlePropertyChangedForStyle(e); - } - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - _customStyle.HandleTemplateApplied(e.NameScope); - } - - #region IControlCustomStyle 实现 - - void IControlCustomStyle.HandleTemplateApplied(INameScope scope) - { - TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty, GlobalTokenResourceKey.BorderThickness, - BindingPriority.Template, - new RenderScaleAwareThicknessConfigure(this)); - SetupCloseButton(); - } - - void IControlCustomStyle.HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e) - { - if (VisualRoot is not null) { - if (e.Property == IsClosableProperty) { - SetupCloseButton(); - } - } - } - - private void SetupCloseButton() - { - if (CloseIcon is null) { - CloseIcon = new PathIcon - { - Kind = "CloseOutlined", - }; - TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorIcon); - TokenResourceBinder.CreateTokenBinding(CloseIcon, PathIcon.ActiveFilledBrushProperty, GlobalTokenResourceKey.ColorIconHover); - } - } - - #endregion + #endregion } \ No newline at end of file diff --git a/src/AtomUI.Controls/Alert/AlertTheme.cs b/src/AtomUI.Controls/Alert/AlertTheme.cs index ef79609..4effcf6 100644 --- a/src/AtomUI.Controls/Alert/AlertTheme.cs +++ b/src/AtomUI.Controls/Alert/AlertTheme.cs @@ -19,350 +19,372 @@ namespace AtomUI.Controls; [ControlThemeProvider] internal class AlertTheme : BaseControlTheme { - public const string CloseBtnPart = "PART_CloseBtn"; - public const string InfoIconPart = "PART_InfoIcon"; - public const string DescriptionLabelPart = "PART_DescriptionLabel"; - public const string MessageLabelPart = "PART_MessageLabel"; - public const string MarqueeLabelPart = "PART_MarqueeLabel"; - - public AlertTheme() - : base(typeof(Alert)) - { - } + public const string CloseBtnPart = "PART_CloseBtn"; + public const string InfoIconPart = "PART_InfoIcon"; + public const string DescriptionLabelPart = "PART_DescriptionLabel"; + public const string MessageLabelPart = "PART_MessageLabel"; + public const string MarqueeLabelPart = "PART_MarqueeLabel"; - protected override void BuildStyles() - { - BuildAlertTypeStyle(); - BuildMessageLabelStyle(); - BuildCloseBtnStyle(); - BuildInfoIconStyle(); - } + public AlertTheme() + : base(typeof(Alert)) + { + } - private void BuildAlertTypeStyle() - { - this.Add(Alert.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusLG); - var successStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Success)); - successStyle.Add(Alert.BackgroundProperty, GlobalTokenResourceKey.ColorSuccessBg); - successStyle.Add(Alert.BorderBrushProperty, GlobalTokenResourceKey.ColorSuccessBorder); - Add(successStyle); - - var infoStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Info)); - infoStyle.Add(Alert.BackgroundProperty, GlobalTokenResourceKey.ColorInfoBg); - infoStyle.Add(Alert.BorderBrushProperty, GlobalTokenResourceKey.ColorInfoBorder); - Add(infoStyle); - - var warningStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Warning)); - warningStyle.Add(Alert.BackgroundProperty, GlobalTokenResourceKey.ColorWarningBg); - warningStyle.Add(Alert.BorderBrushProperty, GlobalTokenResourceKey.ColorWarningBorder); - Add(warningStyle); - - var errorStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.TypeProperty, AlertType.Error)); - errorStyle.Add(Alert.BackgroundProperty, GlobalTokenResourceKey.ColorErrorBg); - errorStyle.Add(Alert.BorderBrushProperty, GlobalTokenResourceKey.ColorErrorBorder); - Add(errorStyle); - - // 根据是否显示 Description 设置 Padding - { - // 为空 - var paddingStyle = new Style(selector => selector.Nesting().PropertyEquals(Alert.DescriptionProperty, null)); - paddingStyle.Add(TemplatedControl.PaddingProperty, AlertTokenResourceKey.DefaultPadding); - Add(paddingStyle); - } - { - // 不为空 - var paddingStyle = new Style(selector => selector.Nesting().Not(x=> x.PropertyEquals(Alert.DescriptionProperty, null))); - paddingStyle.Add(TemplatedControl.PaddingProperty, AlertTokenResourceKey.WithDescriptionPadding); - Add(paddingStyle); - } - } + protected override void BuildStyles() + { + BuildAlertTypeStyle(); + BuildMessageLabelStyle(); + BuildCloseBtnStyle(); + BuildInfoIconStyle(); + } - private void BuildMessageLabelStyle() - { - var normalLabel = default(Selector).Nesting().Template().OfType