NonVirtualizingStackLayoutTests.cs 12 KB

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