From eb14cf9e132cb9b5dd7b594d4c03d2af60628e90 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Wed, 6 Mar 2024 15:46:06 +0800 Subject: [PATCH] feat: Add theme. --- demo/Ursa.Demo/Models/MenuKeys.cs | 37 --------- demo/Ursa.Demo/Pages/BadgeDemo.axaml | 2 +- demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml | 76 +++++++++++++++++++ .../Pages/ScrollToButtonDemo.axaml.cs | 13 ++++ demo/Ursa.Demo/Ursa.Demo.csproj | 4 + .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 1 + demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 38 ++++++++++ .../ViewModels/ScrollToButtonDemoViewModel.cs | 15 ++++ .../Controls/ScrollToButton.axaml | 11 ++- src/Ursa/Controls/BackTop/ScrollTo.cs | 19 ++--- src/Ursa/Controls/BackTop/ScrollToButton.cs | 22 +++--- 11 files changed, 181 insertions(+), 57 deletions(-) delete mode 100644 demo/Ursa.Demo/Models/MenuKeys.cs create mode 100644 demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml create mode 100644 demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs create mode 100644 demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs deleted file mode 100644 index b7b1a76..0000000 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Ursa.Demo; - -public static class MenuKeys -{ - public const string MenuKeyIntroduction = "Introduction"; - public const string MenuKeyBadge = "Badge"; - public const string MenuKeyBanner = "Banner"; - public const string MenuKeyButtonGroup = "ButtonGroup"; - public const string MenuKeyBreadcrumb = "Breadcrumb"; - public const string MenuKeyClassInput = "Class Input"; - public const string MenuKeyDialog = "Dialog"; - public const string MenuKeyDivider = "Divider"; - public const string MenuKeyDisableContainer = "DisableContainer"; - public const string MenuKeyDrawer = "Drawer"; - public const string MenuKeyDualBadge = "DualBadge"; - public const string MenuKeyEnumSelector = "EnumSelector"; - public const string MenuKeyForm = "Form"; - public const string MenuKeyImageViewer = "ImageViewer"; - public const string MenuKeyIpBox = "IPv4Box"; - public const string MenuKeyIconButton = "IconButton"; - public const string MenuKeyKeyGestureInput = "KeyGestureInput"; - public const string MenuKeyLoading = "Loading"; - public const string MenuKeyMessageBox = "MessageBox"; - public const string MenuKeyNavMenu = "NavMenu"; - public const string MenuKeyNumberDisplayer = "NumberDisplayer"; - public const string MenuKeyNumericUpDown = "NumericUpDown"; - public const string MenuKeyPagination = "Pagination"; - public const string MenuKeyRangeSlider = "RangeSlider"; - public const string MenuKeySelectionList = "SelectionList"; - public const string MenuKeyTagInput = "TagInput"; - public const string MenuKeySkeleton = "Skeleton"; - public const string MenuKeyTimeline = "Timeline"; - public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon"; - public const string MenuKeyThemeToggler = "ThemeToggler"; - public const string MenuKeyToolBar = "ToolBar"; - -} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/BadgeDemo.axaml b/demo/Ursa.Demo/Pages/BadgeDemo.axaml index fda3614..f46673b 100644 --- a/demo/Ursa.Demo/Pages/BadgeDemo.axaml +++ b/demo/Ursa.Demo/Pages/BadgeDemo.axaml @@ -8,7 +8,7 @@ d:DesignHeight="850" d:DesignWidth="850" mc:Ignorable="d"> - + + + + + + + Scroll To Top + Scroll To Bottom + Scroll To Left + Scroll To Right + Scroll To Top + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs b/demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs new file mode 100644 index 0000000..5e7741c --- /dev/null +++ b/demo/Ursa.Demo/Pages/ScrollToButtonDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class ScrollToButtonDemo : UserControl +{ + public ScrollToButtonDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj index cdf1e1b..92d7e39 100644 --- a/demo/Ursa.Demo/Ursa.Demo.csproj +++ b/demo/Ursa.Demo/Ursa.Demo.csproj @@ -32,4 +32,8 @@ SkeletonDemo.axaml + + + + diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index d987128..5a0cd77 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -48,6 +48,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyNumericUpDown => new NumericUpDownDemoViewModel(), MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(), MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(), + MenuKeys.MenuKeyScrollToButton => new ScrollToButtonDemoViewModel(), MenuKeys.MenuKeySelectionList => new SelectionListDemoViewModel(), MenuKeys.MenuKeySkeleton => new SkeletonDemoViewModel(), MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index a4eaa14..b500267 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -35,6 +35,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Numeric UpDown", Key = MenuKeys.MenuKeyNumericUpDown }, new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination }, new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider }, + new() { MenuHeader = "ScrollToButton", Key = MenuKeys.MenuKeyScrollToButton, Status = "New" }, new() { MenuHeader = "Selection List", Key = MenuKeys.MenuKeySelectionList, Status = "New" }, new() { MenuHeader = "Skeleton", Key = MenuKeys.MenuKeySkeleton, Status = "New" }, new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput }, @@ -44,4 +45,41 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "ToolBar", Key = MenuKeys.MenuKeyToolBar, Status = "New" } }; } +} + +public static class MenuKeys +{ + public const string MenuKeyIntroduction = "Introduction"; + public const string MenuKeyBadge = "Badge"; + public const string MenuKeyBanner = "Banner"; + public const string MenuKeyButtonGroup = "ButtonGroup"; + public const string MenuKeyBreadcrumb= "Breadcrumb"; + public const string MenuKeyClassInput = "Class Input"; + public const string MenuKeyDialog = "Dialog"; + public const string MenuKeyDivider = "Divider"; + public const string MenuKeyDisableContainer = "DisableContainer"; + public const string MenuKeyDrawer = "Drawer"; + public const string MenuKeyDualBadge = "DualBadge"; + public const string MenuKeyEnumSelector = "EnumSelector"; + public const string MenuKeyForm = "Form"; + public const string MenuKeyImageViewer = "ImageViewer"; + public const string MenuKeyIpBox = "IPv4Box"; + public const string MenuKeyIconButton = "IconButton"; + public const string MenuKeyKeyGestureInput = "KeyGestureInput"; + public const string MenuKeyLoading = "Loading"; + public const string MenuKeyMessageBox = "MessageBox"; + public const string MenuKeyNavMenu = "NavMenu"; + public const string MenuKeyNumberDisplayer = "NumberDisplayer"; + public const string MenuKeyNumericUpDown = "NumericUpDown"; + public const string MenuKeyPagination = "Pagination"; + public const string MenuKeyRangeSlider = "RangeSlider"; + public const string MenuKeyScrollToButton = "ScrollToButton"; + public const string MenuKeySelectionList = "SelectionList"; + public const string MenuKeyTagInput = "TagInput"; + public const string MenuKeySkeleton = "Skeleton"; + public const string MenuKeyTimeline = "Timeline"; + public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon"; + public const string MenuKeyThemeToggler = "ThemeToggler"; + public const string MenuKeyToolBar = "ToolBar"; + } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs new file mode 100644 index 0000000..833189f --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/ScrollToButtonDemoViewModel.cs @@ -0,0 +1,15 @@ +using System.Collections.ObjectModel; +using System.Linq; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public class ScrollToButtonDemoViewModel: ObservableObject +{ + public ObservableCollection Items { get; set; } + + public ScrollToButtonDemoViewModel() + { + Items = new ObservableCollection(Enumerable.Range(0, 1000).Select(a => "Item " + a)); + } +} \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/ScrollToButton.axaml b/src/Ursa.Themes.Semi/Controls/ScrollToButton.axaml index 22816d8..02a00fe 100644 --- a/src/Ursa.Themes.Semi/Controls/ScrollToButton.axaml +++ b/src/Ursa.Themes.Semi/Controls/ScrollToButton.axaml @@ -7,7 +7,7 @@ - + + + + diff --git a/src/Ursa/Controls/BackTop/ScrollTo.cs b/src/Ursa/Controls/BackTop/ScrollTo.cs index 09d076c..1f20340 100644 --- a/src/Ursa/Controls/BackTop/ScrollTo.cs +++ b/src/Ursa/Controls/BackTop/ScrollTo.cs @@ -2,20 +2,22 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Styling; +using Avalonia.VisualTree; using Ursa.Common; namespace Ursa.Controls; public class ScrollTo { - public static readonly AttachedProperty DirectionProperty = - AvaloniaProperty.RegisterAttached("Direction"); + public static readonly AttachedProperty DirectionProperty = + AvaloniaProperty.RegisterAttached("Direction"); public static void SetDirection(Control obj, Position value) => obj.SetValue(DirectionProperty, value); - public static Position GetDirection(Control obj) => obj.GetValue(DirectionProperty); + public static Position? GetDirection(Control obj) => obj.GetValue(DirectionProperty); public static readonly AttachedProperty ButtonThemeProperty = AvaloniaProperty.RegisterAttached("ButtonTheme"); @@ -25,7 +27,7 @@ public class ScrollTo static ScrollTo() { - DirectionProperty.Changed.AddClassHandler(OnDirectionChanged); + DirectionProperty.Changed.AddClassHandler(OnDirectionChanged); ButtonThemeProperty.Changed.AddClassHandler(OnButtonThemeChanged); } @@ -36,8 +38,9 @@ public class ScrollTo button.SetCurrentValue(StyledElement.ThemeProperty, arg2.NewValue.Value); } - private static void OnDirectionChanged(Control control, AvaloniaPropertyChangedEventArgs args) + private static void OnDirectionChanged(Control control, AvaloniaPropertyChangedEventArgs args) { + if (args.NewValue.Value is null) return; var button = EnsureButtonInAdorner(control); if (button is null) return; button.SetCurrentValue(ScrollToButton.DirectionProperty, args.NewValue.Value); @@ -45,15 +48,13 @@ public class ScrollTo private static ScrollToButton? EnsureButtonInAdorner(Control control) { - var scroll = control.GetSelfAndLogicalDescendants().OfType().FirstOrDefault(); - if (scroll is null) return null; - var adorner = AdornerLayer.GetAdorner(scroll); + var adorner = AdornerLayer.GetAdorner(control); if (adorner is not ScrollToButton button) { button = new ScrollToButton(); AdornerLayer.SetAdorner(control, button); } - button.SetCurrentValue(ScrollToButton.TargetProperty, scroll); + button.SetCurrentValue(ScrollToButton.TargetProperty, control); button.SetCurrentValue(ScrollToButton.DirectionProperty, GetDirection(control)); if ( GetButtonTheme(control) is { } theme) { diff --git a/src/Ursa/Controls/BackTop/ScrollToButton.cs b/src/Ursa/Controls/BackTop/ScrollToButton.cs index 18bb28f..4d85d0e 100644 --- a/src/Ursa/Controls/BackTop/ScrollToButton.cs +++ b/src/Ursa/Controls/BackTop/ScrollToButton.cs @@ -1,6 +1,8 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.LogicalTree; +using Avalonia.VisualTree; using Irihi.Avalonia.Shared.Helpers; using Ursa.Common; @@ -46,10 +48,11 @@ public class ScrollToButton: Button _disposable?.Dispose(); if (arg2.NewValue.Value is { } newValue) { - var scroll = newValue.GetSelfAndLogicalDescendants().OfType().FirstOrDefault(); + var scroll = newValue.GetSelfAndVisualDescendants().OfType().FirstOrDefault(); if (_scroll is not null) { _disposable?.Dispose(); + _scroll = null; } _scroll = scroll; _disposable = ScrollViewer.OffsetProperty.Changed.AddClassHandler(OnScrollChanged); @@ -69,14 +72,15 @@ public class ScrollToButton: Button }; _scroll?.SetCurrentValue(ScrollViewer.OffsetProperty, vector); } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + + protected override void OnLoaded(RoutedEventArgs e) { - base.OnAttachedToVisualTree(e); - var scroll = Target.GetSelfAndLogicalDescendants().OfType().FirstOrDefault(); + base.OnLoaded(e); + var scroll = Target.GetSelfAndVisualDescendants().OfType().FirstOrDefault(); if (_scroll is not null) { _disposable?.Dispose(); + _scroll = null; } _scroll = scroll; _disposable = ScrollViewer.OffsetProperty.Changed.AddClassHandler(OnScrollChanged); @@ -91,8 +95,8 @@ public class ScrollToButton: Button private void SetVisibility(Position direction, Vector? vector) { - if (vector is null) return; - if (direction == Position.Bottom && vector.Value.Y < 0) + if (vector is null || _scroll is null) return; + if (direction == Position.Bottom && vector.Value.Y < _scroll.Extent.Height - _scroll.Bounds.Height) { IsVisible = true; } @@ -100,11 +104,11 @@ public class ScrollToButton: Button { IsVisible = true; } - else if (direction == Position.Left && vector.Value.X < 0) + else if (direction == Position.Left && vector.Value.X > 0) { IsVisible = true; } - else if (direction == Position.Right && vector.Value.X > 0) + else if (direction == Position.Right && vector.Value.X < _scroll.Extent.Width - _scroll.Bounds.Width) { IsVisible = true; }