diff --git a/src/Core/src/Layouts/AbsoluteLayoutManager.cs b/src/Core/src/Layouts/AbsoluteLayoutManager.cs index 2608f279dc28..72bee22c2bfd 100644 --- a/src/Core/src/Layouts/AbsoluteLayoutManager.cs +++ b/src/Core/src/Layouts/AbsoluteLayoutManager.cs @@ -60,11 +60,14 @@ public override Size ArrangeChildren(Rect bounds) { var padding = AbsoluteLayout.Padding; - double top = padding.Top + bounds.Y; - double left = padding.Left + bounds.X; + double top = padding.Top + bounds.Top; + double left = padding.Left + bounds.Left; + double right = bounds.Right - padding.Right; double availableWidth = bounds.Width - padding.HorizontalThickness; double availableHeight = bounds.Height - padding.VerticalThickness; + bool leftToRight = AbsoluteLayout.ShouldArrangeLeftToRight(); + for (int n = 0; n < AbsoluteLayout.Count; n++) { var child = AbsoluteLayout[n]; @@ -93,7 +96,12 @@ public override Size ArrangeChildren(Rect bounds) destination.Y = (availableHeight - destination.Height) * destination.Y; } - destination.X += left; + // Figure out where we're starting from (the left edge of the padded area, or the right edge) + if (leftToRight) + destination.X += left; + else + destination.X = right - destination.X - destination.Width; + destination.Y += top; child.Arrange(destination); diff --git a/src/Core/tests/UnitTests/Layouts/AbsoluteLayoutManagerTests.cs b/src/Core/tests/UnitTests/Layouts/AbsoluteLayoutManagerTests.cs index 88ff4a176b47..d8f5ce463a6a 100644 --- a/src/Core/tests/UnitTests/Layouts/AbsoluteLayoutManagerTests.cs +++ b/src/Core/tests/UnitTests/Layouts/AbsoluteLayoutManagerTests.cs @@ -445,5 +445,47 @@ public void ChildMeasureRespectsProportionalBounds() child.Received().Measure(Arg.Is(expectedWidth * widthConstraint), Arg.Is(expectedHeight * heightConstraint)); } + + [Fact(DisplayName = "First View in LTR Absolute Layout is on the left")] + public void LtrShouldHaveFirstItemOnTheLeft() + { + var abs = CreateTestLayout(); + var child = CreateTestView(); + SubstituteChildren(abs, child); + var childBounds = new Rect(10, 0, 100, 100); + SetLayoutBounds(abs, child, childBounds); + + abs.FlowDirection.Returns(FlowDirection.LeftToRight); + + var manager = new AbsoluteLayoutManager(abs); + var measuredSize = manager.Measure(double.PositiveInfinity, 100); + manager.ArrangeChildren(new Rect(Point.Zero, measuredSize)); + + // We expect that the view should be arranged on the left + var expectedRectangle = new Rect(10, 0, 100, 100); + + abs[0].Received().Arrange(Arg.Is(expectedRectangle)); + } + + [Fact(DisplayName = "First View in RTL Absolute Layout is on the right")] + public void RtlShouldHaveFirstItemOnTheRight() + { + var abs = CreateTestLayout(); + var child = CreateTestView(); + SubstituteChildren(abs, child); + var childBounds = new Rect(10, 0, 100, 100); + SetLayoutBounds(abs, child, childBounds); + + abs.FlowDirection.Returns(FlowDirection.RightToLeft); + + var manager = new AbsoluteLayoutManager(abs); + var measuredSize = manager.Measure(double.PositiveInfinity, 100); + manager.ArrangeChildren(new Rect(Point.Zero, measuredSize)); + + // We expect that the view should be arranged on the right + var expectedRectangle = new Rect(0, 0, 100, 100); + + abs[0].Received().Arrange(Arg.Is(expectedRectangle)); + } } }