LayoutableTests_LayoutRounding.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using Avalonia.Controls;
  2. using Avalonia.Layout;
  3. using Avalonia.UnitTests;
  4. using Xunit;
  5. using Xunit.Sdk;
  6. namespace Avalonia.Base.UnitTests.Layout
  7. {
  8. public class LayoutableTests_LayoutRounding
  9. {
  10. [Theory]
  11. [InlineData(100, 100)]
  12. [InlineData(101, 101.33333333333333)]
  13. [InlineData(103, 103.33333333333333)]
  14. public void Measure_Adjusts_DesiredSize_Upwards_When_Constraint_Allows(double desiredSize, double expectedSize)
  15. {
  16. var target = new TestLayoutable(new Size(desiredSize, desiredSize));
  17. var root = CreateRoot(1.5, target);
  18. root.LayoutManager.ExecuteInitialLayoutPass();
  19. Assert.Equal(new Size(expectedSize, expectedSize), target.DesiredSize);
  20. }
  21. [Fact]
  22. public void Measure_Constrains_Adjusted_DesiredSize_To_Constraint()
  23. {
  24. var target = new TestLayoutable(new Size(101, 101));
  25. var root = CreateRoot(1.5, target, constraint: new Size(101, 101));
  26. root.LayoutManager.ExecuteInitialLayoutPass();
  27. // Desired width/height with layout rounding is 101.3333 but constraint is 101,101 so
  28. // layout rounding should be ignored.
  29. Assert.Equal(new Size(101, 101), target.DesiredSize);
  30. }
  31. [Fact]
  32. public void Measure_Adjusts_DesiredSize_Upwards_When_Margin_Present()
  33. {
  34. var target = new TestLayoutable(new Size(101, 101), margin: 1);
  35. var root = CreateRoot(1.5, target);
  36. root.LayoutManager.ExecuteInitialLayoutPass();
  37. // - 1 pixel margin is rounded up to 1.3333; for both sides it is 2.6666
  38. // - Size of 101 gets rounded up to 101.3333
  39. // - Final size = 101.3333 + 2.6666 = 104
  40. AssertEqual(new Size(104, 104), target.DesiredSize);
  41. }
  42. [Fact]
  43. public void Arrange_Adjusts_Bounds_Upwards_With_Margin()
  44. {
  45. var target = new TestLayoutable(new Size(101, 101), margin: 1);
  46. var root = CreateRoot(1.5, target);
  47. root.LayoutManager.ExecuteInitialLayoutPass();
  48. // - 1 pixel margin is rounded up to 1.3333
  49. // - Size of 101 gets rounded up to 101.3333
  50. AssertEqual(new Point(1.3333333333333333, 1.3333333333333333), target.Bounds.Position);
  51. AssertEqual(new Size(101.33333333333333, 101.33333333333333), target.Bounds.Size);
  52. }
  53. [Theory]
  54. [InlineData(16, 6, 5.333333333333333)]
  55. [InlineData(18, 10, 4)]
  56. public void Arranges_Center_Alignment_Correctly_With_Fractional_Scaling(
  57. double containerWidth,
  58. double childWidth,
  59. double expectedX)
  60. {
  61. Border target;
  62. var root = new TestRoot
  63. {
  64. LayoutScaling = 1.5,
  65. UseLayoutRounding = true,
  66. Child = new Decorator
  67. {
  68. Width = containerWidth,
  69. Height = 100,
  70. Child = target = new Border
  71. {
  72. Width = childWidth,
  73. HorizontalAlignment = HorizontalAlignment.Center,
  74. }
  75. }
  76. };
  77. root.Measure(new Size(100, 100));
  78. root.Arrange(new Rect(target.DesiredSize));
  79. Assert.Equal(new Rect(expectedX, 0, childWidth, 100), target.Bounds);
  80. }
  81. private static TestRoot CreateRoot(
  82. double scaling,
  83. Control child,
  84. Size? constraint = null)
  85. {
  86. return new TestRoot
  87. {
  88. LayoutScaling = scaling,
  89. UseLayoutRounding = true,
  90. Child = child,
  91. ClientSize = constraint ?? new Size(1000, 1000),
  92. };
  93. }
  94. private static void AssertEqual(Point expected, Point actual)
  95. {
  96. if (!expected.NearlyEquals(actual))
  97. {
  98. throw new EqualException(expected, actual);
  99. }
  100. }
  101. private static void AssertEqual(Size expected, Size actual)
  102. {
  103. if (!expected.NearlyEquals(actual))
  104. {
  105. throw new EqualException(expected, actual);
  106. }
  107. }
  108. private class TestLayoutable : Control
  109. {
  110. private Size _desiredSize;
  111. public TestLayoutable(Size desiredSize, double margin = 0)
  112. {
  113. _desiredSize = desiredSize;
  114. Margin = new Thickness(margin);
  115. }
  116. protected override Size MeasureOverride(Size availableSize) => _desiredSize;
  117. }
  118. }
  119. }