From b1b63cba2abcd10776f6141921a7cf29c8cb7c24 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Fri, 20 Jan 2023 12:54:22 +0000 Subject: [PATCH] wip --- src/Avalonia.Controls/ItemsControl.cs | 60 ++++++++++++++++- .../Presenters/ItemsPresenter.cs | 67 ++++++++++++++++++- 2 files changed, 124 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index d19a04eb21..1948fda928 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -12,6 +12,8 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Metadata; using Avalonia.Styling; @@ -23,7 +25,7 @@ namespace Avalonia.Controls /// Displays a collection of items. /// [PseudoClasses(":empty", ":singleitem")] - public class ItemsControl : TemplatedControl, IChildIndexProvider + public class ItemsControl : TemplatedControl, IChildIndexProvider, IScrollSnapPointsInfo { /// /// The default value for the property. @@ -91,6 +93,7 @@ namespace Avalonia.Controls private IDataTemplate? _displayMemberItemTemplate; private Tuple? _containerBeingPrepared; private ScrollViewer? _scrollViewer; + private ItemsPresenter? _itemsPresenter; /// /// Initializes a new instance of the class. @@ -203,6 +206,45 @@ namespace Avalonia.Controls remove => _childIndexChanged -= value; } + + public event EventHandler HorizontalSnapPointsChanged + { + add + { + if (_itemsPresenter != null) + { + _itemsPresenter.HorizontalSnapPointsChanged += value; + } + } + + remove + { + if (_itemsPresenter != null) + { + _itemsPresenter.HorizontalSnapPointsChanged -= value; + } + } + } + + public event EventHandler VerticalSnapPointsChanged + { + add + { + if (_itemsPresenter != null) + { + _itemsPresenter.VerticalSnapPointsChanged += value; + } + } + + remove + { + if (_itemsPresenter != null) + { + _itemsPresenter.VerticalSnapPointsChanged -= value; + } + } + } + /// /// Returns the container for the item at the specified index. /// @@ -254,7 +296,8 @@ 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. @@ -355,6 +398,7 @@ namespace Avalonia.Controls { base.OnApplyTemplate(e); _scrollViewer = e.NameScope.Find("PART_ScrollViewer"); + _itemsPresenter = e.NameScope.Find("PART_ItemsPresenter"); } /// @@ -671,5 +715,17 @@ namespace Avalonia.Controls count = ItemsView.Count; return true; } + + public IReadOnlyList GetIrregularSnapPoints(Orientation orientation, SnapPointsAlignment snapPointsAlignment) + { + return _itemsPresenter?.GetIrregularSnapPoints(orientation, snapPointsAlignment) ?? new List(); + } + + public double GetRegularSnapPoints(Orientation orientation, SnapPointsAlignment snapPointsAlignment, out double offset) + { + offset = 0; + + return _itemsPresenter?.GetRegularSnapPoints(orientation, snapPointsAlignment, out offset) ?? 0; + } } } diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index e0252feed5..08de6bf5a8 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -3,13 +3,15 @@ using System.Collections.Generic; using System.Diagnostics; using Avalonia.Controls.Primitives; using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Layout; namespace Avalonia.Controls.Presenters { /// /// Presents items inside an . /// - public class ItemsPresenter : Control, ILogicalScrollable + public class ItemsPresenter : Control, ILogicalScrollable, IScrollSnapPointsInfo { /// /// Defines the property. @@ -21,6 +23,44 @@ namespace Avalonia.Controls.Presenters private ILogicalScrollable? _logicalScrollable; private EventHandler? _scrollInvalidated; + public event EventHandler HorizontalSnapPointsChanged + { + add + { + if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + scrollSnapPointsInfo.HorizontalSnapPointsChanged += value; + } + } + + remove + { + if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + scrollSnapPointsInfo.HorizontalSnapPointsChanged -= value; + } + } + } + + public event EventHandler VerticalSnapPointsChanged + { + add + { + if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + scrollSnapPointsInfo.VerticalSnapPointsChanged += value; + } + } + + remove + { + if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + scrollSnapPointsInfo.VerticalSnapPointsChanged -= value; + } + } + } + static ItemsPresenter() { KeyboardNavigation.TabNavigationProperty.OverrideDefaultValue( @@ -89,6 +129,9 @@ 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; + public override sealed void ApplyTemplate() { if (Panel is null && ItemsControl is not null) @@ -204,5 +247,27 @@ namespace Avalonia.Controls.Presenters } private void OnLogicalScrollInvalidated(object? sender, EventArgs e) => _scrollInvalidated?.Invoke(this, e); + + public IReadOnlyList GetIrregularSnapPoints(Orientation orientation, SnapPointsAlignment snapPointsAlignment) + { + if(Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + return scrollSnapPointsInfo.GetIrregularSnapPoints(orientation, snapPointsAlignment); + } + + return new List(); + } + + public double GetRegularSnapPoints(Orientation orientation, SnapPointsAlignment snapPointsAlignment, out double offset) + { + if (Panel is IScrollSnapPointsInfo scrollSnapPointsInfo) + { + return scrollSnapPointsInfo.GetRegularSnapPoints(orientation, snapPointsAlignment, out offset); + } + + offset = 0; + + return 0; + } } }