From e227788a9589f065677622dc30576dc9d23dfea4 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Tue, 13 Feb 2024 16:09:53 +0800 Subject: [PATCH] feat: add more templates. --- demo/Ursa.Demo/Pages/NavMenuDemo.axaml | 7 +- src/Ursa.Themes.Semi/Controls/NavMenu.axaml | 186 +++++++++++++++--- .../Converters/NavMenuMarginConverter.cs | 17 ++ src/Ursa/Controls/NavMenu/NavMenu.cs | 2 +- src/Ursa/Controls/NavMenu/NavMenuItem.cs | 58 ++++-- 5 files changed, 226 insertions(+), 44 deletions(-) create mode 100644 src/Ursa.Themes.Semi/Converters/NavMenuMarginConverter.cs diff --git a/demo/Ursa.Demo/Pages/NavMenuDemo.axaml b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml index 0b192bb..bf1a6f8 100644 --- a/demo/Ursa.Demo/Pages/NavMenuDemo.axaml +++ b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml @@ -12,9 +12,9 @@ x:DataType="vm:NavMenuDemoViewModel" mc:Ignorable="d"> - + - + + Collapse + + + + @@ -14,39 +19,160 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Converters/NavMenuMarginConverter.cs b/src/Ursa.Themes.Semi/Converters/NavMenuMarginConverter.cs new file mode 100644 index 0000000..999c0b1 --- /dev/null +++ b/src/Ursa.Themes.Semi/Converters/NavMenuMarginConverter.cs @@ -0,0 +1,17 @@ +using System.Globalization; +using Avalonia; +using Avalonia.Data.Converters; + +namespace Ursa.Themes.Semi.Converters; + +public class NavMenuMarginConverter: IMultiValueConverter +{ + public object? Convert(IList values, Type targetType, object? parameter, CultureInfo culture) + { + if (values[0] is double indent && values[1] is int level) + { + return new Thickness(indent * level, 0, 0, 0); + } + return AvaloniaProperty.UnsetValue; + } +} \ No newline at end of file diff --git a/src/Ursa/Controls/NavMenu/NavMenu.cs b/src/Ursa/Controls/NavMenu/NavMenu.cs index 9e4d41a..d675d0c 100644 --- a/src/Ursa/Controls/NavMenu/NavMenu.cs +++ b/src/Ursa/Controls/NavMenu/NavMenu.cs @@ -88,7 +88,7 @@ public class NavMenu: ItemsControl } public static readonly StyledProperty SubMenuIndentProperty = AvaloniaProperty.Register( - nameof(SubMenuIndent), defaultValue: 20.0); + nameof(SubMenuIndent)); public double SubMenuIndent { diff --git a/src/Ursa/Controls/NavMenu/NavMenuItem.cs b/src/Ursa/Controls/NavMenu/NavMenuItem.cs index b5a1baf..7271c69 100644 --- a/src/Ursa/Controls/NavMenu/NavMenuItem.cs +++ b/src/Ursa/Controls/NavMenu/NavMenuItem.cs @@ -8,6 +8,7 @@ using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.VisualTree; +using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; @@ -25,6 +26,7 @@ public class NavMenuItem: HeaderedSelectingItemsControl private NavMenu? _rootMenu; private Panel? _popupPanel; + private Popup? _popup; public static readonly StyledProperty IconProperty = AvaloniaProperty.Register( nameof(Icon)); @@ -81,6 +83,24 @@ public class NavMenuItem: HeaderedSelectingItemsControl private set => SetAndRaise(IsHighlightedProperty, ref _isHighlighted, value); } + public static readonly StyledProperty IsHorizontalCollapsedProperty = + NavMenu.IsHorizontalCollapsedProperty.AddOwner(); + + public bool IsHorizontalCollapsed + { + get => GetValue(IsHorizontalCollapsedProperty); + set => SetValue(IsHorizontalCollapsedProperty, value); + } + + public static readonly StyledProperty IsVerticalCollapsedProperty = AvaloniaProperty.Register( + nameof(IsVerticalCollapsed)); + + public bool IsVerticalCollapsed + { + get => GetValue(IsVerticalCollapsedProperty); + set => SetValue(IsVerticalCollapsedProperty, value); + } + public static readonly StyledProperty SubMenuIndentProperty = NavMenu.SubMenuIndentProperty.AddOwner(); @@ -90,8 +110,6 @@ public class NavMenuItem: HeaderedSelectingItemsControl set => SetValue(SubMenuIndentProperty, value); } - - internal static readonly DirectProperty LevelProperty = AvaloniaProperty.RegisterDirect( nameof(Level), o => o.Level, (o, v) => o.Level = v); private int _level; @@ -104,20 +122,18 @@ public class NavMenuItem: HeaderedSelectingItemsControl static NavMenuItem() { - SelectableMixin.Attach(IsSelectedProperty); + // SelectableMixin.Attach(IsSelectedProperty); PressedMixin.Attach(); - IsHighlightedProperty.Changed.AddClassHandler((o, e) => o.OnIsHighlightedChange(e)); LevelProperty.Changed.AddClassHandler((item, args) => item.OnLevelChange(args)); + PropertyToPseudoClassMixin.Attach(IsHighlightedProperty, PC_Highlighted); + PropertyToPseudoClassMixin.Attach(IsHorizontalCollapsedProperty, PC_HorizontalCollapsed); + PropertyToPseudoClassMixin.Attach(IsVerticalCollapsedProperty, PC_VerticalCollapsed); + PropertyToPseudoClassMixin.Attach(IsSelectedProperty, ":selected", IsSelectedChangedEvent); } private void OnLevelChange(AvaloniaPropertyChangedEventArgs args) { - PseudoClasses.Set(PC_FirstLevel, args.NewValue.Value == 0); - } - - private void OnIsHighlightedChange(AvaloniaPropertyChangedEventArgs args) - { - PseudoClasses.Set(PC_Highlighted, args.NewValue.Value); + PseudoClasses.Set(PC_FirstLevel, args.NewValue.Value == 1); } protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) @@ -154,6 +170,8 @@ public class NavMenuItem: HeaderedSelectingItemsControl } this[!IconTemplateProperty] = _rootMenu[!NavMenu.IconTemplateProperty]; this[!HeaderTemplateProperty] = _rootMenu[!NavMenu.HeaderTemplateProperty]; + this[!SubMenuIndentProperty] = _rootMenu[!NavMenu.SubMenuIndentProperty]; + this[!IsHorizontalCollapsedProperty] = _rootMenu[!NavMenu.IsHorizontalCollapsedProperty]; } } @@ -163,6 +181,7 @@ public class NavMenuItem: HeaderedSelectingItemsControl var children = this.ItemsPanelRoot?.Children.ToList(); base.OnApplyTemplate(e); SetCurrentValue(LevelProperty,CalculateDistanceFromLogicalParent(this)); + _popup = e.NameScope.Find("PART_Popup"); } protected override void OnPointerPressed(PointerPressedEventArgs e) @@ -174,7 +193,24 @@ public class NavMenuItem: HeaderedSelectingItemsControl } else { - + if (!IsHorizontalCollapsed) + { + SetCurrentValue(IsVerticalCollapsedProperty, !IsVerticalCollapsed); + } + else + { + if (_popup is not null) + { + if (_popup.IsOpen) + { + _popup.Close(); + } + else + { + _popup.Open(); + } + } + } } Command?.Execute(CommandParameter); e.Handled = true;