From 03c138ff90ed8ccd3df403acecd2547ef56fca41 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 24 May 2016 11:31:11 +0200 Subject: [PATCH] Delegate ScrollIntoView to ItemVirtualizer. This doesn't make sense for ItemVirtualizationMode.Simple so we do nothing here. --- .../XamlTestApplicationPcl/TestScrollable.cs | 46 +++++++++++-------- .../Presenters/ItemVirtualizer.cs | 6 +++ .../Presenters/ItemsPresenter.cs | 7 +++ .../Presenters/ScrollContentPresenter.cs | 7 +++ .../Primitives/IScrollable.cs | 9 ++++ ...ScrollContentPresenterTests_IScrollable.cs | 7 ++- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/samples/XamlTestApplicationPcl/TestScrollable.cs b/samples/XamlTestApplicationPcl/TestScrollable.cs index 76f4cdd106..1f0961af27 100644 --- a/samples/XamlTestApplicationPcl/TestScrollable.cs +++ b/samples/XamlTestApplicationPcl/TestScrollable.cs @@ -3,6 +3,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Media; +using Avalonia.VisualTree; namespace XamlTestApplication { @@ -54,6 +55,31 @@ namespace XamlTestApplication } } + public override void Render(DrawingContext context) + { + var y = 0.0; + + for (var i = (int)_offset.Y; i < itemCount; ++i) + { + using (var line = new FormattedText( + "Item " + (i + 1), + TextBlock.GetFontFamily(this), + TextBlock.GetFontSize(this), + TextBlock.GetFontStyle(this), + TextAlignment.Left, + TextBlock.GetFontWeight(this))) + { + context.DrawText(Brushes.Black, new Point(-_offset.X, y), line); + y += _lineSize.Height; + } + } + } + + public bool BringIntoView(IVisual target, Rect targetRect) + { + throw new NotImplementedException(); + } + protected override Size MeasureOverride(Size availableSize) { using (var line = new FormattedText( @@ -77,25 +103,5 @@ namespace XamlTestApplication InvalidateScroll?.Invoke(); return finalSize; } - - public override void Render(DrawingContext context) - { - var y = 0.0; - - for (var i = (int)_offset.Y; i < itemCount; ++i) - { - using (var line = new FormattedText( - "Item " + (i + 1), - TextBlock.GetFontFamily(this), - TextBlock.GetFontSize(this), - TextBlock.GetFontStyle(this), - TextAlignment.Left, - TextBlock.GetFontWeight(this))) - { - context.DrawText(Brushes.Black, new Point(-_offset.X, y), line); - y += _lineSize.Height; - } - } - } } } \ No newline at end of file diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs index b45ed8065b..63d4503df7 100644 --- a/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs +++ b/src/Avalonia.Controls/Presenters/ItemVirtualizer.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Specialized; using Avalonia.Controls.Primitives; +using Avalonia.VisualTree; namespace Avalonia.Controls.Presenters { @@ -45,6 +46,11 @@ namespace Avalonia.Controls.Presenters public abstract void Arranging(Size finalSize); + public virtual bool BringIntoView(IVisual target, Rect targetRect) + { + return false; + } + public virtual void ItemsChanged(IEnumerable items, NotifyCollectionChangedEventArgs e) { Items = items; diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index fc20add96c..86636b1837 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Specialized; using Avalonia.Controls.Primitives; using Avalonia.Input; +using Avalonia.VisualTree; using static Avalonia.Utilities.MathUtilities; namespace Avalonia.Controls.Presenters @@ -71,6 +72,12 @@ namespace Avalonia.Controls.Presenters /// Size IScrollable.PageScrollSize => new Size(0, 1); + /// + bool IScrollable.BringIntoView(IVisual target, Rect targetRect) + { + return _virtualizer?.BringIntoView(target, targetRect) ?? false; + } + /// protected override Size ArrangeOverride(Size finalSize) { diff --git a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs index 5d295d7fc8..4c7a00f6fd 100644 --- a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs @@ -117,6 +117,13 @@ namespace Avalonia.Controls.Presenters return false; } + var scrollable = Child as IScrollable; + + if (scrollable?.IsLogicalScrollEnabled == true) + { + return scrollable.BringIntoView(target, targetRect); + } + var transform = target.TransformToVisual(Child); if (transform == null) diff --git a/src/Avalonia.Controls/Primitives/IScrollable.cs b/src/Avalonia.Controls/Primitives/IScrollable.cs index d37d1fdcca..b9155054b8 100644 --- a/src/Avalonia.Controls/Primitives/IScrollable.cs +++ b/src/Avalonia.Controls/Primitives/IScrollable.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Avalonia.VisualTree; namespace Avalonia.Controls.Primitives { @@ -62,5 +63,13 @@ namespace Avalonia.Controls.Primitives /// Gets the size to page by, in logical units. /// Size PageScrollSize { get; } + + /// + /// Attempts to bring a portion of the target visual into view by scrolling the content. + /// + /// The target visual. + /// The portion of the target visual to bring into view. + /// True if the scroll offset was changed; otherwise false. + bool BringIntoView(IVisual target, Rect targetRect); } } diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs index 1aea155eaa..a690522e89 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs @@ -6,6 +6,7 @@ using System.Reactive.Linq; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Layout; +using Avalonia.VisualTree; using Xunit; namespace Avalonia.Controls.UnitTests @@ -236,7 +237,6 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(new Rect(0, 0, 100, 100), scrollable.Bounds); } - private class TestScrollable : Control, IScrollable { private Size _extent; @@ -293,6 +293,11 @@ namespace Avalonia.Controls.UnitTests } } + public bool BringIntoView(IVisual target, Rect targetRect) + { + throw new NotImplementedException(); + } + protected override Size MeasureOverride(Size availableSize) { AvailableSize = availableSize;