ScrollViewerTests.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. using System;
  2. using System.Collections.Generic;
  3. using Avalonia.Controls.Presenters;
  4. using Avalonia.Controls.Primitives;
  5. using Avalonia.Controls.Templates;
  6. using Avalonia.Layout;
  7. using Avalonia.UnitTests;
  8. using Moq;
  9. using Xunit;
  10. namespace Avalonia.Controls.UnitTests
  11. {
  12. public class ScrollViewerTests
  13. {
  14. [Fact]
  15. public void Content_Is_Created()
  16. {
  17. var target = new ScrollViewer
  18. {
  19. Template = new FuncControlTemplate<ScrollViewer>(CreateTemplate),
  20. Content = "Foo",
  21. };
  22. target.ApplyTemplate();
  23. ((ContentPresenter)target.Presenter).UpdateChild();
  24. Assert.IsType<TextBlock>(target.Presenter.Child);
  25. }
  26. [Fact]
  27. public void CanHorizontallyScroll_Should_Track_HorizontalScrollBarVisibility()
  28. {
  29. var target = new ScrollViewer();
  30. var values = new List<bool>();
  31. target.GetObservable(ScrollViewer.CanHorizontallyScrollProperty).Subscribe(x => values.Add(x));
  32. target.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
  33. target.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
  34. Assert.Equal(new[] { true, false, true }, values);
  35. }
  36. [Fact]
  37. public void CanVerticallyScroll_Should_Track_VerticalScrollBarVisibility()
  38. {
  39. var target = new ScrollViewer();
  40. var values = new List<bool>();
  41. target.GetObservable(ScrollViewer.CanVerticallyScrollProperty).Subscribe(x => values.Add(x));
  42. target.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
  43. target.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
  44. Assert.Equal(new[] { true, false, true }, values);
  45. }
  46. [Fact]
  47. public void Offset_Should_Be_Coerced_To_Viewport()
  48. {
  49. var target = new ScrollViewer();
  50. target.SetValue(ScrollViewer.ExtentProperty, new Size(20, 20));
  51. target.SetValue(ScrollViewer.ViewportProperty, new Size(10, 10));
  52. target.Offset = new Vector(12, 12);
  53. Assert.Equal(new Vector(10, 10), target.Offset);
  54. }
  55. [Fact]
  56. public void Test_ScrollToHome()
  57. {
  58. var target = new ScrollViewer();
  59. target.SetValue(ScrollViewer.ExtentProperty, new Size(50, 50));
  60. target.SetValue(ScrollViewer.ViewportProperty, new Size(10, 10));
  61. target.Offset = new Vector(25, 25);
  62. target.ScrollToHome();
  63. Assert.Equal(new Vector(0, 0), target.Offset);
  64. }
  65. [Fact]
  66. public void Test_ScrollToEnd()
  67. {
  68. var target = new ScrollViewer();
  69. target.SetValue(ScrollViewer.ExtentProperty, new Size(50, 50));
  70. target.SetValue(ScrollViewer.ViewportProperty, new Size(10, 10));
  71. target.Offset = new Vector(25, 25);
  72. target.ScrollToEnd();
  73. Assert.Equal(new Vector(0, 40), target.Offset);
  74. }
  75. [Fact]
  76. public void SmallChange_Should_Be_16()
  77. {
  78. var target = new ScrollViewer();
  79. Assert.Equal(new Size(16, 16), target.SmallChange);
  80. }
  81. [Fact]
  82. public void LargeChange_Should_Be_Viewport()
  83. {
  84. var target = new ScrollViewer();
  85. target.SetValue(ScrollViewer.ViewportProperty, new Size(104, 143));
  86. Assert.Equal(new Size(104, 143), target.LargeChange);
  87. }
  88. [Fact]
  89. public void SmallChange_Should_Come_From_ILogicalScrollable_If_Present()
  90. {
  91. var child = new Mock<Control>();
  92. var logicalScroll = child.As<ILogicalScrollable>();
  93. logicalScroll.Setup(x => x.IsLogicalScrollEnabled).Returns(true);
  94. logicalScroll.Setup(x => x.ScrollSize).Returns(new Size(12, 43));
  95. var target = new ScrollViewer
  96. {
  97. Template = new FuncControlTemplate<ScrollViewer>(CreateTemplate),
  98. Content = child.Object,
  99. };
  100. target.ApplyTemplate();
  101. ((ContentPresenter)target.Presenter).UpdateChild();
  102. Assert.Equal(new Size(12, 43), target.SmallChange);
  103. }
  104. [Fact]
  105. public void LargeChange_Should_Come_From_ILogicalScrollable_If_Present()
  106. {
  107. var child = new Mock<Control>();
  108. var logicalScroll = child.As<ILogicalScrollable>();
  109. logicalScroll.Setup(x => x.IsLogicalScrollEnabled).Returns(true);
  110. logicalScroll.Setup(x => x.PageScrollSize).Returns(new Size(45, 67));
  111. var target = new ScrollViewer
  112. {
  113. Template = new FuncControlTemplate<ScrollViewer>(CreateTemplate),
  114. Content = child.Object,
  115. };
  116. target.ApplyTemplate();
  117. ((ContentPresenter)target.Presenter).UpdateChild();
  118. Assert.Equal(new Size(45, 67), target.LargeChange);
  119. }
  120. [Fact]
  121. public void Changing_Extent_Should_Raise_ScrollChanged()
  122. {
  123. var target = new ScrollViewer();
  124. var root = new TestRoot(target);
  125. var raised = 0;
  126. target.SetValue(ScrollViewer.ExtentProperty, new Size(100, 100));
  127. target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
  128. target.Offset = new Vector(10, 10);
  129. root.LayoutManager.ExecuteInitialLayoutPass(root);
  130. target.ScrollChanged += (s, e) =>
  131. {
  132. Assert.Equal(new Vector(11, 12), e.ExtentDelta);
  133. Assert.Equal(default, e.OffsetDelta);
  134. Assert.Equal(default, e.ViewportDelta);
  135. ++raised;
  136. };
  137. target.SetValue(ScrollViewer.ExtentProperty, new Size(111, 112));
  138. Assert.Equal(0, raised);
  139. root.LayoutManager.ExecuteLayoutPass();
  140. Assert.Equal(1, raised);
  141. }
  142. [Fact]
  143. public void Changing_Offset_Should_Raise_ScrollChanged()
  144. {
  145. var target = new ScrollViewer();
  146. var root = new TestRoot(target);
  147. var raised = 0;
  148. target.SetValue(ScrollViewer.ExtentProperty, new Size(100, 100));
  149. target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
  150. target.Offset = new Vector(10, 10);
  151. root.LayoutManager.ExecuteInitialLayoutPass(root);
  152. target.ScrollChanged += (s, e) =>
  153. {
  154. Assert.Equal(default, e.ExtentDelta);
  155. Assert.Equal(new Vector(12, 14), e.OffsetDelta);
  156. Assert.Equal(default, e.ViewportDelta);
  157. ++raised;
  158. };
  159. target.Offset = new Vector(22, 24);
  160. Assert.Equal(0, raised);
  161. root.LayoutManager.ExecuteLayoutPass();
  162. Assert.Equal(1, raised);
  163. }
  164. [Fact]
  165. public void Changing_Viewport_Should_Raise_ScrollChanged()
  166. {
  167. var target = new ScrollViewer();
  168. var root = new TestRoot(target);
  169. var raised = 0;
  170. target.SetValue(ScrollViewer.ExtentProperty, new Size(100, 100));
  171. target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
  172. target.Offset = new Vector(10, 10);
  173. root.LayoutManager.ExecuteInitialLayoutPass(root);
  174. target.ScrollChanged += (s, e) =>
  175. {
  176. Assert.Equal(default, e.ExtentDelta);
  177. Assert.Equal(default, e.OffsetDelta);
  178. Assert.Equal(new Vector(6, 8), e.ViewportDelta);
  179. ++raised;
  180. };
  181. target.SetValue(ScrollViewer.ViewportProperty, new Size(56, 58));
  182. Assert.Equal(0, raised);
  183. root.LayoutManager.ExecuteLayoutPass();
  184. Assert.Equal(1, raised);
  185. }
  186. private Control CreateTemplate(ScrollViewer control, INameScope scope)
  187. {
  188. return new Grid
  189. {
  190. ColumnDefinitions = new ColumnDefinitions
  191. {
  192. new ColumnDefinition(1, GridUnitType.Star),
  193. new ColumnDefinition(GridLength.Auto),
  194. },
  195. RowDefinitions = new RowDefinitions
  196. {
  197. new RowDefinition(1, GridUnitType.Star),
  198. new RowDefinition(GridLength.Auto),
  199. },
  200. Children =
  201. {
  202. new ScrollContentPresenter
  203. {
  204. Name = "PART_ContentPresenter",
  205. [~ContentPresenter.ContentProperty] = control[~ContentControl.ContentProperty],
  206. [~~ScrollContentPresenter.ExtentProperty] = control[~~ScrollViewer.ExtentProperty],
  207. [~~ScrollContentPresenter.OffsetProperty] = control[~~ScrollViewer.OffsetProperty],
  208. [~~ScrollContentPresenter.ViewportProperty] = control[~~ScrollViewer.ViewportProperty],
  209. [~ScrollContentPresenter.CanHorizontallyScrollProperty] = control[~ScrollViewer.CanHorizontallyScrollProperty],
  210. }.RegisterInNameScope(scope),
  211. new ScrollBar
  212. {
  213. Name = "horizontalScrollBar",
  214. Orientation = Orientation.Horizontal,
  215. [~RangeBase.MaximumProperty] = control[~ScrollViewer.HorizontalScrollBarMaximumProperty],
  216. [~~RangeBase.ValueProperty] = control[~~ScrollViewer.HorizontalScrollBarValueProperty],
  217. [~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.HorizontalScrollBarViewportSizeProperty],
  218. [~ScrollBar.VisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty],
  219. [Grid.RowProperty] = 1,
  220. }.RegisterInNameScope(scope),
  221. new ScrollBar
  222. {
  223. Name = "verticalScrollBar",
  224. Orientation = Orientation.Vertical,
  225. [~RangeBase.MaximumProperty] = control[~ScrollViewer.VerticalScrollBarMaximumProperty],
  226. [~~RangeBase.ValueProperty] = control[~~ScrollViewer.VerticalScrollBarValueProperty],
  227. [~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.VerticalScrollBarViewportSizeProperty],
  228. [~ScrollBar.VisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty],
  229. [Grid.ColumnProperty] = 1,
  230. }.RegisterInNameScope(scope),
  231. },
  232. };
  233. }
  234. }
  235. }