Skip to content

Commit

Permalink
Merge pull request #12256 from MrJul/fixes/scroll-fp-error
Browse files Browse the repository at this point in the history
Handle ScrollContentPresenter extent rounding errors
  • Loading branch information
grokys committed Jul 19, 2023
2 parents 7f94529 + 515e084 commit 9b83280
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 10 deletions.
7 changes: 0 additions & 7 deletions samples/Sandbox/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
x:Class="Sandbox.MainWindow">

<ScrollViewer>
<StackPanel>
<Button Margin="0 100000000000000000 0 0">0</Button>
<Button>1</Button>
</StackPanel>
</ScrollViewer>
</Window>
19 changes: 16 additions & 3 deletions src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,18 +473,31 @@ Vector TrackAnchor()
}

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,37 @@ public void Extent_Should_Include_Content_Margin_Scaled_With_Layout_Rounding()
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()
{
Expand Down

0 comments on commit 9b83280

Please sign in to comment.