NonVirtualizingStackLayoutTests.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using Avalonia.Controls;
  4. using Avalonia.Layout;
  5. using Xunit;
  6. namespace Avalonia.Base.UnitTests.Layout
  7. {
  8. public class NonVirtualizingStackLayoutTests
  9. {
  10. [Fact]
  11. public void Lays_Out_Children_Vertically()
  12. {
  13. var target = new NonVirtualizingStackLayout { Orientation = Orientation.Vertical };
  14. var context = CreateContext(new[]
  15. {
  16. new Border { Height = 20, Width = 120 },
  17. new Border { Height = 30 },
  18. new Border { Height = 50 },
  19. });
  20. var desiredSize = target.Measure(context, Size.Infinity);
  21. var arrangeSize = target.Arrange(context, desiredSize);
  22. Assert.Equal(new Size(120, 100), desiredSize);
  23. Assert.Equal(new Size(120, 100), arrangeSize);
  24. Assert.Equal(new Rect(0, 0, 120, 20), context.Children[0].Bounds);
  25. Assert.Equal(new Rect(0, 20, 120, 30), context.Children[1].Bounds);
  26. Assert.Equal(new Rect(0, 50, 120, 50), context.Children[2].Bounds);
  27. }
  28. [Fact]
  29. public void Lays_Out_Children_Horizontally()
  30. {
  31. var target = new NonVirtualizingStackLayout { Orientation = Orientation.Horizontal };
  32. var context = CreateContext(new[]
  33. {
  34. new Border { Width = 20, Height = 120 },
  35. new Border { Width = 30 },
  36. new Border { Width = 50 },
  37. });
  38. var desiredSize = target.Measure(context, Size.Infinity);
  39. var arrangeSize = target.Arrange(context, desiredSize);
  40. Assert.Equal(new Size(100, 120), desiredSize);
  41. Assert.Equal(new Size(100, 120), arrangeSize);
  42. Assert.Equal(new Rect(0, 0, 20, 120), context.Children[0].Bounds);
  43. Assert.Equal(new Rect(20, 0, 30, 120), context.Children[1].Bounds);
  44. Assert.Equal(new Rect(50, 0, 50, 120), context.Children[2].Bounds);
  45. }
  46. [Fact]
  47. public void Lays_Out_Children_Vertically_With_Spacing()
  48. {
  49. var target = new NonVirtualizingStackLayout
  50. {
  51. Orientation = Orientation.Vertical,
  52. Spacing = 10,
  53. };
  54. var context = CreateContext(new[]
  55. {
  56. new Border { Height = 20, Width = 120 },
  57. new Border { Height = 30 },
  58. new Border { Height = 50 },
  59. });
  60. var desiredSize = target.Measure(context, Size.Infinity);
  61. var arrangeSize = target.Arrange(context, desiredSize);
  62. Assert.Equal(new Size(120, 120), desiredSize);
  63. Assert.Equal(new Size(120, 120), arrangeSize);
  64. Assert.Equal(new Rect(0, 0, 120, 20), context.Children[0].Bounds);
  65. Assert.Equal(new Rect(0, 30, 120, 30), context.Children[1].Bounds);
  66. Assert.Equal(new Rect(0, 70, 120, 50), context.Children[2].Bounds);
  67. }
  68. [Fact]
  69. public void Lays_Out_Children_Horizontally_With_Spacing()
  70. {
  71. var target = new NonVirtualizingStackLayout
  72. {
  73. Orientation = Orientation.Horizontal,
  74. Spacing = 10,
  75. };
  76. var context = CreateContext(new[]
  77. {
  78. new Border { Width = 20, Height = 120 },
  79. new Border { Width = 30 },
  80. new Border { Width = 50 },
  81. });
  82. var desiredSize = target.Measure(context, Size.Infinity);
  83. var arrangeSize = target.Arrange(context, desiredSize);
  84. Assert.Equal(new Size(120, 120), desiredSize);
  85. Assert.Equal(new Size(120, 120), arrangeSize);
  86. Assert.Equal(new Rect(0, 0, 20, 120), context.Children[0].Bounds);
  87. Assert.Equal(new Rect(30, 0, 30, 120), context.Children[1].Bounds);
  88. Assert.Equal(new Rect(70, 0, 50, 120), context.Children[2].Bounds);
  89. }
  90. [Fact]
  91. public void Arranges_Vertical_Children_With_Correct_Bounds()
  92. {
  93. var target = new NonVirtualizingStackLayout
  94. {
  95. Orientation = Orientation.Vertical
  96. };
  97. var context = CreateContext(new[]
  98. {
  99. new TestControl
  100. {
  101. HorizontalAlignment = HorizontalAlignment.Left,
  102. MeasureSize = new Size(50, 10),
  103. },
  104. new TestControl
  105. {
  106. HorizontalAlignment = HorizontalAlignment.Left,
  107. MeasureSize = new Size(150, 10),
  108. },
  109. new TestControl
  110. {
  111. HorizontalAlignment = HorizontalAlignment.Center,
  112. MeasureSize = new Size(50, 10),
  113. },
  114. new TestControl
  115. {
  116. HorizontalAlignment = HorizontalAlignment.Center,
  117. MeasureSize = new Size(150, 10),
  118. },
  119. new TestControl
  120. {
  121. HorizontalAlignment = HorizontalAlignment.Right,
  122. MeasureSize = new Size(50, 10),
  123. },
  124. new TestControl
  125. {
  126. HorizontalAlignment = HorizontalAlignment.Right,
  127. MeasureSize = new Size(150, 10),
  128. },
  129. new TestControl
  130. {
  131. HorizontalAlignment = HorizontalAlignment.Stretch,
  132. MeasureSize = new Size(50, 10),
  133. },
  134. new TestControl
  135. {
  136. HorizontalAlignment = HorizontalAlignment.Stretch,
  137. MeasureSize = new Size(150, 10),
  138. },
  139. });
  140. var desiredSize = target.Measure(context, new Size(100, 150));
  141. Assert.Equal(new Size(100, 80), desiredSize);
  142. target.Arrange(context, desiredSize);
  143. var bounds = context.Children.Select(x => x.Bounds).ToArray();
  144. Assert.Equal(
  145. new[]
  146. {
  147. new Rect(0, 0, 50, 10),
  148. new Rect(0, 10, 100, 10),
  149. new Rect(25, 20, 50, 10),
  150. new Rect(0, 30, 100, 10),
  151. new Rect(50, 40, 50, 10),
  152. new Rect(0, 50, 100, 10),
  153. new Rect(0, 60, 100, 10),
  154. new Rect(0, 70, 100, 10),
  155. }, bounds);
  156. }
  157. [Fact]
  158. public void Arranges_Horizontal_Children_With_Correct_Bounds()
  159. {
  160. var target = new NonVirtualizingStackLayout
  161. {
  162. Orientation = Orientation.Horizontal
  163. };
  164. var context = CreateContext(new[]
  165. {
  166. new TestControl
  167. {
  168. VerticalAlignment = VerticalAlignment.Top,
  169. MeasureSize = new Size(10, 50),
  170. },
  171. new TestControl
  172. {
  173. VerticalAlignment = VerticalAlignment.Top,
  174. MeasureSize = new Size(10, 150),
  175. },
  176. new TestControl
  177. {
  178. VerticalAlignment = VerticalAlignment.Center,
  179. MeasureSize = new Size(10, 50),
  180. },
  181. new TestControl
  182. {
  183. VerticalAlignment = VerticalAlignment.Center,
  184. MeasureSize = new Size(10, 150),
  185. },
  186. new TestControl
  187. {
  188. VerticalAlignment = VerticalAlignment.Bottom,
  189. MeasureSize = new Size(10, 50),
  190. },
  191. new TestControl
  192. {
  193. VerticalAlignment = VerticalAlignment.Bottom,
  194. MeasureSize = new Size(10, 150),
  195. },
  196. new TestControl
  197. {
  198. VerticalAlignment = VerticalAlignment.Stretch,
  199. MeasureSize = new Size(10, 50),
  200. },
  201. new TestControl
  202. {
  203. VerticalAlignment = VerticalAlignment.Stretch,
  204. MeasureSize = new Size(10, 150),
  205. },
  206. });
  207. var desiredSize = target.Measure(context, new Size(150, 100));
  208. Assert.Equal(new Size(80, 100), desiredSize);
  209. target.Arrange(context, desiredSize);
  210. var bounds = context.Children.Select(x => x.Bounds).ToArray();
  211. Assert.Equal(
  212. new[]
  213. {
  214. new Rect(0, 0, 10, 50),
  215. new Rect(10, 0, 10, 100),
  216. new Rect(20, 25, 10, 50),
  217. new Rect(30, 0, 10, 100),
  218. new Rect(40, 50, 10, 50),
  219. new Rect(50, 0, 10, 100),
  220. new Rect(60, 0, 10, 100),
  221. new Rect(70, 0, 10, 100),
  222. }, bounds);
  223. }
  224. [Theory]
  225. [InlineData(Orientation.Horizontal)]
  226. [InlineData(Orientation.Vertical)]
  227. public void Spacing_Not_Added_For_Invisible_Children(Orientation orientation)
  228. {
  229. var targetThreeChildrenOneInvisble = new NonVirtualizingStackLayout
  230. {
  231. Orientation = orientation,
  232. Spacing = 40,
  233. };
  234. var contextThreeChildrenOneInvisble = CreateContext(new[]
  235. {
  236. new StackPanel { Width = 10, Height= 10, IsVisible = false },
  237. new StackPanel { Width = 10, Height= 10 },
  238. new StackPanel { Width = 10, Height= 10 },
  239. });
  240. var targetTwoChildrenNoneInvisible = new NonVirtualizingStackLayout
  241. {
  242. Spacing = 40,
  243. Orientation = orientation,
  244. };
  245. var contextTwoChildrenNoneInvisible = CreateContext(new[]
  246. {
  247. new StackPanel { Width = 10, Height = 10 },
  248. new StackPanel { Width = 10, Height = 10 }
  249. });
  250. var desiredSize1 = targetThreeChildrenOneInvisble.Measure(contextThreeChildrenOneInvisble, Size.Infinity);
  251. var desiredSize2 = targetTwoChildrenNoneInvisible.Measure(contextTwoChildrenNoneInvisible, Size.Infinity);
  252. Assert.Equal(desiredSize2, desiredSize1);
  253. }
  254. [Theory]
  255. [InlineData(Orientation.Horizontal)]
  256. [InlineData(Orientation.Vertical)]
  257. public void Only_Arrange_Visible_Children(Orientation orientation)
  258. {
  259. var hiddenPanel = new Panel { Width = 10, Height = 10, IsVisible = false };
  260. var panel = new Panel { Width = 10, Height = 10 };
  261. var target = new NonVirtualizingStackLayout
  262. {
  263. Spacing = 40,
  264. Orientation = orientation,
  265. };
  266. var context = CreateContext(new[]
  267. {
  268. hiddenPanel,
  269. panel
  270. });
  271. var desiredSize = target.Measure(context, Size.Infinity);
  272. var arrangeSize = target.Arrange(context, desiredSize);
  273. Assert.Equal(new Size(10, 10), arrangeSize);
  274. }
  275. private static NonVirtualizingLayoutContext CreateContext(Control[] children)
  276. {
  277. return new TestLayoutContext(children);
  278. }
  279. private class TestLayoutContext : NonVirtualizingLayoutContext
  280. {
  281. public TestLayoutContext(Control[] children) => ChildrenCore = children;
  282. protected override IReadOnlyList<ILayoutable> ChildrenCore { get; }
  283. }
  284. private class TestControl : Control
  285. {
  286. public Size MeasureConstraint { get; private set; }
  287. public Size MeasureSize { get; set; }
  288. protected override Size MeasureOverride(Size availableSize)
  289. {
  290. MeasureConstraint = availableSize;
  291. return MeasureSize;
  292. }
  293. }
  294. }
  295. }