From 515e0843dec9544aa3c6964c4a580aee2ea28b59 Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Wed, 19 Jul 2023 14:31:48 +0200 Subject: [PATCH] Handle ScrollContentPresenter extent rounding errors --- samples/Sandbox/MainWindow.axaml | 7 ----- .../Presenters/ScrollContentPresenter.cs | 19 ++++++++++-- .../Presenters/ScrollContentPresenterTests.cs | 31 +++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/samples/Sandbox/MainWindow.axaml b/samples/Sandbox/MainWindow.axaml index f96abcac96..6929f192c7 100644 --- a/samples/Sandbox/MainWindow.axaml +++ b/samples/Sandbox/MainWindow.axaml @@ -1,11 +1,4 @@ - - - - - - - diff --git a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs index bd3d2b5171..4ff8e7cfef 100644 --- a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs @@ -473,18 +473,31 @@ namespace Avalonia.Controls.Presenters } Viewport = finalSize; + Extent = ComputeExtent(finalSize); + _isAnchorElementDirty = true; + return finalSize; + } + + private Size ComputeExtent(Size viewportSize) + { var childMargin = Child!.Margin; + if (Child.UseLayoutRounding) { var scale = LayoutHelper.GetLayoutScale(Child); childMargin = LayoutHelper.RoundLayoutThickness(childMargin, scale, scale); } - Extent = Child!.Bounds.Size.Inflate(childMargin); - _isAnchorElementDirty = true; + var extent = Child!.Bounds.Size.Inflate(childMargin); - return finalSize; + if (MathUtilities.AreClose(extent.Width, viewportSize.Width, LayoutHelper.LayoutEpsilon)) + extent = extent.WithWidth(viewportSize.Width); + + if (MathUtilities.AreClose(extent.Height, viewportSize.Height, LayoutHelper.LayoutEpsilon)) + extent = extent.WithHeight(viewportSize.Height); + + return extent; } private void OnScrollGesture(object? sender, ScrollGestureEventArgs e) diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs index c7ea5c1b69..30628b1af8 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs @@ -275,6 +275,37 @@ namespace Avalonia.Controls.UnitTests.Presenters Assert.Equal(new Size(203.2, 203.2), target.Extent); } + [Fact] + public void Extent_Should_Be_Rounded_To_Viewport_When_Close() + { + var root = new TestRoot + { + LayoutScaling = 1.75, + UseLayoutRounding = true + }; + + var target = new ScrollContentPresenter + { + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Content = new Border + { + Width = 164.57142857142858, + Height = 164.57142857142858, + Margin = new Thickness(6) + } + }; + + root.Child = target; + target.UpdateChild(); + target.Measure(new Size(1000, 1000)); + target.Arrange(new Rect(0, 0, 1000, 1000)); + + Assert.Equal(new Size(176.00000000000003, 176.00000000000003), target.Child!.DesiredSize); + Assert.Equal(new Size(176, 176), target.Viewport); + Assert.Equal(new Size(176, 176), target.Extent); + } + [Fact] public void Extent_Width_Should_Be_Arrange_Width_When_CanScrollHorizontally_False() {