Handle ScrollContentPresenter extent rounding errors

This commit is contained in:
Julien Lebosquain
2023-07-19 14:31:48 +02:00
parent 7f945293c6
commit 515e0843de
3 changed files with 47 additions and 10 deletions
-7
View File
@@ -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>
@@ -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)
@@ -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()
{