From feddc7e1c48c3d478bc94873e08be8fe2aea3f10 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Mon, 23 Jan 2023 13:46:46 +0000 Subject: [PATCH] make AreVerticalSnapPointsRegular and AreHorizontalSnapPointsRegular styled properties --- src/Avalonia.Controls/ItemsControl.cs | 35 ++++++++++++- .../Presenters/ItemsPresenter.cs | 49 ++++++++++++++++++- .../Primitives/IScrollSnapPointsInfo.cs | 8 +-- .../VirtualizingStackPanel.cs | 32 ++++++++++-- .../Controls/ItemsControl.xaml | 2 + .../Controls/ListBox.xaml | 3 +- .../Controls/ItemsControl.xaml | 2 + .../Controls/ListBox.xaml | 6 ++- 8 files changed, 124 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 1948fda928..db49da85e8 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -74,6 +74,18 @@ namespace Avalonia.Controls /// public static readonly StyledProperty DisplayMemberBindingProperty = AvaloniaProperty.Register(nameof(DisplayMemberBinding)); + + /// + /// Defines the property. + /// + public static readonly StyledProperty AreHorizontalSnapPointsRegularProperty = + AvaloniaProperty.Register(nameof(AreHorizontalSnapPointsRegular)); + + /// + /// Defines the property. + /// + public static readonly StyledProperty AreVerticalSnapPointsRegularProperty = + AvaloniaProperty.Register(nameof(AreVerticalSnapPointsRegular)); /// /// Gets or sets the to use for binding to the display member of each item. @@ -94,6 +106,7 @@ namespace Avalonia.Controls private Tuple? _containerBeingPrepared; private ScrollViewer? _scrollViewer; private ItemsPresenter? _itemsPresenter; + private IScrollSnapPointsInfo? _scrolSnapPointInfo; /// /// Initializes a new instance of the class. @@ -245,6 +258,24 @@ namespace Avalonia.Controls } } + /// + /// Gets or sets whether the horizontal snap points for the are equidistant from each other. + /// + public bool AreHorizontalSnapPointsRegular + { + get { return GetValue(AreHorizontalSnapPointsRegularProperty); } + set { SetValue(AreHorizontalSnapPointsRegularProperty, value); } + } + + /// + /// Gets or sets whether the vertical snap points for the are equidistant from each other. + /// + public bool AreVerticalSnapPointsRegular + { + get { return GetValue(AreVerticalSnapPointsRegularProperty); } + set { SetValue(AreVerticalSnapPointsRegularProperty, value); } + } + /// /// Returns the container for the item at the specified index. /// @@ -296,8 +327,6 @@ namespace Avalonia.Controls /// Gets the currently realized containers. /// public IEnumerable GetRealizedContainers() => Presenter?.GetRealizedContainers() ?? Array.Empty(); - public bool AreHorizontalSnapPointsRegular => _itemsPresenter?.AreHorizontalSnapPointsRegular ?? false; - public bool AreVerticalSnapPointsRegular => _itemsPresenter?.AreVerticalSnapPointsRegular ?? false; /// /// Creates or a container that can be used to display an item. @@ -399,6 +428,8 @@ namespace Avalonia.Controls base.OnApplyTemplate(e); _scrollViewer = e.NameScope.Find("PART_ScrollViewer"); _itemsPresenter = e.NameScope.Find("PART_ItemsPresenter"); + + _scrolSnapPointInfo = _itemsPresenter as IScrollSnapPointsInfo; } /// diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index e3332ef3a2..8594b584fa 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -21,8 +21,21 @@ namespace Avalonia.Controls.Presenters private PanelContainerGenerator? _generator; private ILogicalScrollable? _logicalScrollable; + private IScrollSnapPointsInfo? _scrollSnapPointsInfo; private EventHandler? _scrollInvalidated; + /// + /// Defines the property. + /// + public static readonly StyledProperty AreHorizontalSnapPointsRegularProperty = + AvaloniaProperty.Register(nameof(AreHorizontalSnapPointsRegular)); + + /// + /// Defines the property. + /// + public static readonly StyledProperty AreVerticalSnapPointsRegularProperty = + AvaloniaProperty.Register(nameof(AreVerticalSnapPointsRegular)); + /// /// Defines the event. /// @@ -125,8 +138,23 @@ namespace Avalonia.Controls.Presenters Size IScrollable.Extent => _logicalScrollable?.Extent ?? default; Size IScrollable.Viewport => _logicalScrollable?.Viewport ?? default; - public bool AreHorizontalSnapPointsRegular => Panel is IScrollSnapPointsInfo scrollSnapPointsInfo ? scrollSnapPointsInfo.AreHorizontalSnapPointsRegular : false; - public bool AreVerticalSnapPointsRegular => Panel is IScrollSnapPointsInfo scrollSnapPointsInfo ? scrollSnapPointsInfo.AreVerticalSnapPointsRegular : false; + /// + /// Gets or sets whether the horizontal snap points for the are equidistant from each other. + /// + public bool AreHorizontalSnapPointsRegular + { + get { return GetValue(AreHorizontalSnapPointsRegularProperty); } + set { SetValue(AreHorizontalSnapPointsRegularProperty, value); } + } + + /// + /// Gets or sets whether the vertical snap points for the are equidistant from each other. + /// + public bool AreVerticalSnapPointsRegular + { + get { return GetValue(AreVerticalSnapPointsRegularProperty); } + set { SetValue(AreVerticalSnapPointsRegularProperty, value); } + } public override sealed void ApplyTemplate() { @@ -139,9 +167,16 @@ namespace Avalonia.Controls.Presenters Panel = ItemsPanel.Build(); Panel.SetValue(TemplatedParentProperty, TemplatedParent); + _scrollSnapPointsInfo = Panel as IScrollSnapPointsInfo; LogicalChildren.Add(Panel); VisualChildren.Add(Panel); + if (_scrollSnapPointsInfo != null) + { + _scrollSnapPointsInfo.AreVerticalSnapPointsRegular = AreVerticalSnapPointsRegular; + _scrollSnapPointsInfo.AreHorizontalSnapPointsRegular = AreHorizontalSnapPointsRegular; + } + if (Panel is VirtualizingPanel v) v.Attach(ItemsControl); else @@ -205,6 +240,16 @@ namespace Avalonia.Controls.Presenters ResetState(); InvalidateMeasure(); } + else if(change.Property == AreHorizontalSnapPointsRegularProperty) + { + if (_scrollSnapPointsInfo != null) + _scrollSnapPointsInfo.AreHorizontalSnapPointsRegular = AreHorizontalSnapPointsRegular; + } + else if (change.Property == AreVerticalSnapPointsRegularProperty) + { + if (_scrollSnapPointsInfo != null) + _scrollSnapPointsInfo.AreVerticalSnapPointsRegular = AreVerticalSnapPointsRegular; + } } internal void Refresh() diff --git a/src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs b/src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs index d0462aff9e..7b33db0df2 100644 --- a/src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs +++ b/src/Avalonia.Controls/Primitives/IScrollSnapPointsInfo.cs @@ -11,14 +11,14 @@ namespace Avalonia.Controls.Primitives public interface IScrollSnapPointsInfo { /// - /// Gets a value that indicates whether the horizontal snap points for the container are equidistant from each other. + /// Gets or sets a value that indicates whether the horizontal snap points for the container are equidistant from each other. /// - bool AreHorizontalSnapPointsRegular { get; } + bool AreHorizontalSnapPointsRegular { get; set; } /// - /// Gets a value that indicates whether the vertical snap points for the container are equidistant from each other. + /// Gets or sets a value that indicates whether the vertical snap points for the container are equidistant from each other. /// - bool AreVerticalSnapPointsRegular { get; } + bool AreVerticalSnapPointsRegular { get; set; } /// /// Returns the set of distances between irregular snap points for a specified orientation and alignment. diff --git a/src/Avalonia.Controls/VirtualizingStackPanel.cs b/src/Avalonia.Controls/VirtualizingStackPanel.cs index a59fffa704..6bcf3dcf5d 100644 --- a/src/Avalonia.Controls/VirtualizingStackPanel.cs +++ b/src/Avalonia.Controls/VirtualizingStackPanel.cs @@ -35,7 +35,7 @@ namespace Avalonia.Controls /// Defines the property. /// public static readonly StyledProperty AreVerticalSnapPointsRegularProperty = - AvaloniaProperty.Register(nameof(AreVerticalSnapPointsRegular)); + AvaloniaProperty.Register(nameof(AreVerticalSnapPointsRegular)); /// /// Defines the event. @@ -725,7 +725,20 @@ namespace Avalonia.Controls } else { - snapPoint += averageElementSize; + if (snapPoint == 0) + { + switch (snapPointsAlignment) + { + case SnapPointsAlignment.Center: + snapPoint = averageElementSize / 2; + break; + case SnapPointsAlignment.Far: + snapPoint = averageElementSize; + break; + } + } + else + snapPoint += averageElementSize; } snapPoints.Add(snapPoint); @@ -759,7 +772,20 @@ namespace Avalonia.Controls } else { - snapPoint += averageElementSize; + if (snapPoint == 0) + { + switch (snapPointsAlignment) + { + case SnapPointsAlignment.Center: + snapPoint = averageElementSize / 2; + break; + case SnapPointsAlignment.Far: + snapPoint = averageElementSize; + break; + } + } + else + snapPoint += averageElementSize; } snapPoints.Add(snapPoint); diff --git a/src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml b/src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml index 1306985f5f..19a29b9466 100644 --- a/src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/ItemsControl.xaml @@ -9,6 +9,8 @@ CornerRadius="{TemplateBinding CornerRadius}" Padding="{TemplateBinding Padding}"> diff --git a/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml b/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml index dc18d65797..4b9fb76b8a 100644 --- a/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml @@ -19,7 +19,6 @@ - @@ -37,6 +36,8 @@ IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}" AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"> diff --git a/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml b/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml index d85cf193fa..8cf4e0be08 100644 --- a/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml +++ b/src/Avalonia.Themes.Simple/Controls/ItemsControl.xaml @@ -10,6 +10,8 @@ BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}"> diff --git a/src/Avalonia.Themes.Simple/Controls/ListBox.xaml b/src/Avalonia.Themes.Simple/Controls/ListBox.xaml index e1257ef10f..eaa1f914ca 100644 --- a/src/Avalonia.Themes.Simple/Controls/ListBox.xaml +++ b/src/Avalonia.Themes.Simple/Controls/ListBox.xaml @@ -20,9 +20,13 @@ Background="{TemplateBinding Background}" HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}" - VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"> + VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" + VerticalSnapPointsType="{TemplateBinding (ScrollViewer.VerticalSnapPointsType)}" + HorizontalSnapPointsType="{TemplateBinding (ScrollViewer.HorizontalSnapPointsType)}">