ScrollBarTests.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.ViewsTests;
  3. public class ScrollBarTests
  4. {
  5. public ScrollBarTests (ITestOutputHelper output) { _output = output; }
  6. private readonly ITestOutputHelper _output;
  7. [Fact]
  8. [AutoInitShutdown]
  9. public void AutoHideScrollBar_CheckScrollBarVisibility ()
  10. {
  11. var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = 30 };
  12. View scrollBarSuperView = ScrollBarSuperView ();
  13. scrollBarSuperView.Add (scrollBar);
  14. Application.Begin ((scrollBarSuperView.SuperView as Toplevel)!);
  15. Assert.Equal (Orientation.Vertical, scrollBar.Orientation);
  16. Assert.True (scrollBar.ShowScrollIndicator);
  17. Assert.True (scrollBar.Visible);
  18. Assert.Equal ("Absolute(2)", scrollBar.Width!.ToString ());
  19. Assert.Equal (2, scrollBar.Viewport.Width);
  20. Assert.Equal ("Fill(Absolute(0))", scrollBar.Height!.ToString ());
  21. Assert.Equal (25, scrollBar.Viewport.Height);
  22. scrollBar.Size = 10;
  23. Assert.False (scrollBar.ShowScrollIndicator);
  24. Assert.False (scrollBar.Visible);
  25. scrollBar.Size = 30;
  26. Assert.True (scrollBar.ShowScrollIndicator);
  27. Assert.True (scrollBar.Visible);
  28. scrollBar.AutoHide = false;
  29. Assert.True (scrollBar.ShowScrollIndicator);
  30. Assert.True (scrollBar.Visible);
  31. scrollBar.Size = 10;
  32. Assert.True (scrollBar.ShowScrollIndicator);
  33. Assert.True (scrollBar.Visible);
  34. scrollBarSuperView.SuperView!.Dispose ();
  35. }
  36. [Theory]
  37. [AutoInitShutdown]
  38. [InlineData (
  39. 20,
  40. @"
  41. ▼",
  42. @"
  43. ▼",
  44. @"
  45. ▼",
  46. @"
  47. ▼",
  48. @"
  49. ◄████░░░░►",
  50. @"
  51. ◄░░████░░►",
  52. @"
  53. ◄░░░░████►",
  54. @"
  55. ◄░░██░░░░►")]
  56. [InlineData (
  57. 40,
  58. @"
  59. ▼",
  60. @"
  61. ▼",
  62. @"
  63. ▼",
  64. @"
  65. ▼",
  66. @"
  67. ◄██░░░░░░►",
  68. @"
  69. ◄░██░░░░░►",
  70. @"
  71. ◄░░██░░░░►",
  72. @"
  73. ◄░█░░░░░░►")]
  74. public void Changing_Position_Size_Orientation_Draws_Correctly (
  75. int size,
  76. string firstVertExpected,
  77. string middleVertExpected,
  78. string endVertExpected,
  79. string sizeVertExpected,
  80. string firstHoriExpected,
  81. string middleHoriExpected,
  82. string endHoriExpected,
  83. string sizeHoriExpected
  84. )
  85. {
  86. var scrollBar = new ScrollBar
  87. {
  88. Orientation = Orientation.Vertical,
  89. Size = size,
  90. Height = 10
  91. };
  92. var top = new Toplevel ();
  93. top.Add (scrollBar);
  94. Application.Begin (top);
  95. _ = TestHelpers.AssertDriverContentsWithFrameAre (firstVertExpected, _output);
  96. scrollBar.Position = 4;
  97. Application.Refresh ();
  98. _ = TestHelpers.AssertDriverContentsWithFrameAre (middleVertExpected, _output);
  99. scrollBar.Position = 10;
  100. Application.Refresh ();
  101. _ = TestHelpers.AssertDriverContentsWithFrameAre (endVertExpected, _output);
  102. scrollBar.Size = size * 2;
  103. Application.Refresh ();
  104. _ = TestHelpers.AssertDriverContentsWithFrameAre (sizeVertExpected, _output);
  105. scrollBar.Orientation = Orientation.Horizontal;
  106. scrollBar.Width = 10;
  107. scrollBar.Height = 1;
  108. scrollBar.Position = 0;
  109. scrollBar.Size = size;
  110. Application.Refresh ();
  111. _ = TestHelpers.AssertDriverContentsWithFrameAre (firstHoriExpected, _output);
  112. scrollBar.Position = 4;
  113. Application.Refresh ();
  114. _ = TestHelpers.AssertDriverContentsWithFrameAre (middleHoriExpected, _output);
  115. scrollBar.Position = 10;
  116. Application.Refresh ();
  117. _ = TestHelpers.AssertDriverContentsWithFrameAre (endHoriExpected, _output);
  118. scrollBar.Size = size * 2;
  119. Application.Refresh ();
  120. _ = TestHelpers.AssertDriverContentsWithFrameAre (sizeHoriExpected, _output);
  121. }
  122. [Fact]
  123. public void Constructor_Defaults ()
  124. {
  125. var scrollBar = new ScrollBar ();
  126. Assert.False (scrollBar.CanFocus);
  127. Assert.Equal (Orientation.Vertical, scrollBar.Orientation);
  128. Assert.Equal (0, scrollBar.Size);
  129. Assert.Equal (0, scrollBar.Position);
  130. Assert.Equal ("Auto(Content,Absolute(1),)", scrollBar.Width!.ToString ());
  131. Assert.Equal ("Auto(Content,Absolute(1),)", scrollBar.Height!.ToString ());
  132. Assert.True (scrollBar.ShowScrollIndicator);
  133. Assert.True (scrollBar.AutoHide);
  134. }
  135. [Fact]
  136. [AutoInitShutdown]
  137. public void KeepContentInAllViewport_True_False ()
  138. {
  139. var view = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  140. view.Padding.Thickness = new (0, 0, 2, 0);
  141. view.SetContentSize (new (view.Viewport.Width, 30));
  142. var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = view.GetContentSize ().Height };
  143. scrollBar.PositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue };
  144. view.Padding.Add (scrollBar);
  145. var top = new Toplevel ();
  146. top.Add (view);
  147. Application.Begin (top);
  148. Assert.True (scrollBar.KeepContentInAllViewport);
  149. Assert.Equal (80, view.Padding.Viewport.Width);
  150. Assert.Equal (25, view.Padding.Viewport.Height);
  151. Assert.Equal (2, scrollBar.Viewport.Width);
  152. Assert.Equal (25, scrollBar.Viewport.Height);
  153. Assert.Equal (30, scrollBar.Size);
  154. scrollBar.KeepContentInAllViewport = false;
  155. scrollBar.Position = 50;
  156. Assert.Equal (scrollBar.Position, scrollBar.Size - 1);
  157. Assert.Equal (scrollBar.Position, view.Viewport.Y);
  158. Assert.Equal (29, scrollBar.Position);
  159. Assert.Equal (29, view.Viewport.Y);
  160. top.Dispose ();
  161. }
  162. [Theory]
  163. [AutoInitShutdown]
  164. [InlineData (
  165. Orientation.Vertical,
  166. 20,
  167. 10,
  168. 4,
  169. @"
  170. ▼",
  171. 2,
  172. @"
  173. ▼")]
  174. [InlineData (
  175. Orientation.Vertical,
  176. 40,
  177. 10,
  178. 5,
  179. @"
  180. ▼",
  181. 18,
  182. @"
  183. ▼")]
  184. [InlineData (
  185. Orientation.Horizontal,
  186. 20,
  187. 10,
  188. 4,
  189. @"
  190. ◄░░░░████►",
  191. 2,
  192. @"
  193. ◄░████░░░►")]
  194. [InlineData (
  195. Orientation.Horizontal,
  196. 40,
  197. 10,
  198. 5,
  199. @"
  200. ◄░░██░░░░►",
  201. 18,
  202. @"
  203. ◄░░░░██░░►")]
  204. public void Mouse_On_The_Container (Orientation orientation, int size, int position, int location, string output, int expectedPos, string expectedOut)
  205. {
  206. var scrollBar = new ScrollBar
  207. {
  208. Width = orientation == Orientation.Vertical ? 1 : 10,
  209. Height = orientation == Orientation.Vertical ? 10 : 1,
  210. Orientation = orientation, Size = size,
  211. Position = position
  212. };
  213. var top = new Toplevel ();
  214. top.Add (scrollBar);
  215. Application.Begin (top);
  216. _ = TestHelpers.AssertDriverContentsWithFrameAre (output, _output);
  217. Application.OnMouseEvent (
  218. new ()
  219. {
  220. Position = orientation == Orientation.Vertical ? new (0, location) : new Point (location, 0),
  221. Flags = MouseFlags.Button1Pressed
  222. });
  223. Assert.Equal (expectedPos, scrollBar.Position);
  224. Application.Refresh ();
  225. _ = TestHelpers.AssertDriverContentsWithFrameAre (expectedOut, _output);
  226. }
  227. [Theory]
  228. [AutoInitShutdown]
  229. [InlineData (
  230. Orientation.Vertical,
  231. 20,
  232. 10,
  233. 5,
  234. 5,
  235. @"
  236. ▼",
  237. MouseFlags.Button1Pressed,
  238. 10,
  239. @"
  240. ▼")]
  241. [InlineData (
  242. Orientation.Vertical,
  243. 40,
  244. 10,
  245. 3,
  246. 3,
  247. @"
  248. ▼",
  249. MouseFlags.Button1Pressed,
  250. 10,
  251. @"
  252. ▼")]
  253. [InlineData (
  254. Orientation.Horizontal,
  255. 20,
  256. 10,
  257. 5,
  258. 5,
  259. @"
  260. ◄░░░░████►",
  261. MouseFlags.Button1Pressed,
  262. 10,
  263. @"
  264. ◄░░░░████►")]
  265. [InlineData (
  266. Orientation.Horizontal,
  267. 40,
  268. 10,
  269. 3,
  270. 3,
  271. @"
  272. ◄░░██░░░░►",
  273. MouseFlags.Button1Pressed,
  274. 10,
  275. @"
  276. ◄░░██░░░░►")]
  277. [InlineData (
  278. Orientation.Vertical,
  279. 20,
  280. 10,
  281. 5,
  282. 7,
  283. @"
  284. ▼",
  285. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  286. 12,
  287. @"
  288. ▼")]
  289. [InlineData (
  290. Orientation.Horizontal,
  291. 20,
  292. 10,
  293. 5,
  294. 4,
  295. @"
  296. ◄░░░░████►",
  297. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  298. 8,
  299. @"
  300. ◄░░░████░►")]
  301. [InlineData (
  302. Orientation.Vertical,
  303. 20,
  304. 10,
  305. 5,
  306. 6,
  307. @"
  308. ▼",
  309. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  310. 12,
  311. @"
  312. ▼")]
  313. [InlineData (
  314. Orientation.Horizontal,
  315. 20,
  316. 10,
  317. 5,
  318. 6,
  319. @"
  320. ◄░░░░████►",
  321. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  322. 12,
  323. @"
  324. ◄░░░░████►")]
  325. [InlineData (
  326. Orientation.Vertical,
  327. 40,
  328. 10,
  329. 2,
  330. 1,
  331. @"
  332. ▼",
  333. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  334. 2,
  335. @"
  336. ▼")]
  337. [InlineData (
  338. Orientation.Horizontal,
  339. 40,
  340. 10,
  341. 2,
  342. 1,
  343. @"
  344. ◄░░██░░░░►",
  345. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  346. 2,
  347. @"
  348. ◄██░░░░░░►")]
  349. [InlineData (
  350. Orientation.Vertical,
  351. 40,
  352. 10,
  353. 3,
  354. 4,
  355. @"
  356. ▼",
  357. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  358. 15,
  359. @"
  360. ▼")]
  361. [InlineData (
  362. Orientation.Horizontal,
  363. 40,
  364. 10,
  365. 3,
  366. 4,
  367. @"
  368. ◄░░██░░░░►",
  369. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  370. 15,
  371. @"
  372. ◄░░░██░░░►")]
  373. [InlineData (
  374. Orientation.Vertical,
  375. 40,
  376. 10,
  377. 3,
  378. 3,
  379. @"
  380. ▼",
  381. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  382. 10,
  383. @"
  384. ▼")]
  385. [InlineData (
  386. Orientation.Horizontal,
  387. 40,
  388. 10,
  389. 3,
  390. 3,
  391. @"
  392. ◄░░██░░░░►",
  393. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  394. 10,
  395. @"
  396. ◄░░██░░░░►")]
  397. [InlineData (
  398. Orientation.Vertical,
  399. 40,
  400. 10,
  401. 3,
  402. 5,
  403. @"
  404. ▼",
  405. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  406. 20,
  407. @"
  408. ▼")]
  409. [InlineData (
  410. Orientation.Horizontal,
  411. 40,
  412. 10,
  413. 3,
  414. 5,
  415. @"
  416. ◄░░██░░░░►",
  417. MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition,
  418. 20,
  419. @"
  420. ◄░░░░██░░►")]
  421. public void Mouse_On_The_Slider (
  422. Orientation orientation,
  423. int size,
  424. int position,
  425. int startLocation,
  426. int endLocation,
  427. string output,
  428. MouseFlags mouseFlags,
  429. int expectedPos,
  430. string expectedOut
  431. )
  432. {
  433. var scrollBar = new ScrollBar
  434. {
  435. Width = orientation == Orientation.Vertical ? 1 : 10,
  436. Height = orientation == Orientation.Vertical ? 10 : 1,
  437. Orientation = orientation,
  438. Size = size, Position = position
  439. };
  440. var top = new Toplevel ();
  441. top.Add (scrollBar);
  442. Application.Begin (top);
  443. _ = TestHelpers.AssertDriverContentsWithFrameAre (output, _output);
  444. Assert.Null (Application.MouseGrabView);
  445. if (mouseFlags.HasFlag (MouseFlags.ReportMousePosition))
  446. {
  447. MouseFlags mf = mouseFlags & ~MouseFlags.ReportMousePosition;
  448. Application.OnMouseEvent (
  449. new ()
  450. {
  451. Position = orientation == Orientation.Vertical ? new (0, startLocation) : new (startLocation, 0),
  452. Flags = mf
  453. });
  454. Application.OnMouseEvent (
  455. new ()
  456. {
  457. Position = orientation == Orientation.Vertical ? new (0, endLocation) : new (endLocation, 0),
  458. Flags = mouseFlags
  459. });
  460. }
  461. else
  462. {
  463. Assert.Equal (startLocation, endLocation);
  464. Application.OnMouseEvent (
  465. new ()
  466. {
  467. Position = orientation == Orientation.Vertical ? new (0, startLocation) : new (startLocation, 0),
  468. Flags = mouseFlags
  469. });
  470. }
  471. Assert.Equal ("scrollSlider", Application.MouseGrabView?.Id);
  472. Assert.IsType<ScrollSlider> (Application.MouseGrabView);
  473. Assert.Equal (expectedPos, scrollBar.Position);
  474. Application.Refresh ();
  475. _ = TestHelpers.AssertDriverContentsWithFrameAre (expectedOut, _output);
  476. Application.OnMouseEvent (
  477. new ()
  478. {
  479. Position = orientation == Orientation.Vertical ? new (0, startLocation) : new (startLocation, 0),
  480. Flags = MouseFlags.Button1Released
  481. });
  482. Assert.Null (Application.MouseGrabView);
  483. }
  484. [Theory]
  485. [AutoInitShutdown]
  486. [InlineData (Orientation.Vertical)]
  487. [InlineData (Orientation.Horizontal)]
  488. public void Mouse_Pressed_On_ScrollButton_Changes_Position (Orientation orientation)
  489. {
  490. var scrollBar = new ScrollBar
  491. {
  492. X = 10, Y = 10, Width = orientation == Orientation.Vertical ? 1 : 10, Height = orientation == Orientation.Vertical ? 10 : 1, Size = 20,
  493. Orientation = orientation
  494. };
  495. var top = new Toplevel ();
  496. top.Add (scrollBar);
  497. Application.Begin (top);
  498. var scroll = (Scroll)scrollBar.Subviews.FirstOrDefault (x => x is Scroll);
  499. Rectangle scrollSliderFrame = scroll!.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame;
  500. Assert.Equal (scrollSliderFrame, orientation == Orientation.Vertical ? new (0, 0, 1, 4) : new (0, 0, 4, 1));
  501. Assert.Equal (0, scrollBar.Position);
  502. // ScrollButton increase
  503. for (var i = 0; i < 13; i++)
  504. {
  505. Application.OnMouseEvent (
  506. new ()
  507. {
  508. Position = orientation == Orientation.Vertical ? new (10, 19) : new (19, 10), Flags = MouseFlags.Button1Pressed
  509. });
  510. if (i < 12)
  511. {
  512. Assert.Equal (i + 1, scrollBar.Position);
  513. }
  514. else
  515. {
  516. Assert.Equal (i, scrollBar.Position);
  517. Assert.Equal (
  518. orientation == Orientation.Vertical ? new (0, 4) : new (4, 0),
  519. scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  520. }
  521. }
  522. for (var i = 12; i > -1; i--)
  523. {
  524. Application.OnMouseEvent (new () { Position = new (10, 10), Flags = MouseFlags.Button1Pressed });
  525. if (i > 0)
  526. {
  527. Assert.Equal (i - 1, scrollBar.Position);
  528. }
  529. else
  530. {
  531. Assert.Equal (0, scrollBar.Position);
  532. Assert.Equal (new (0, 0), scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  533. }
  534. }
  535. }
  536. [Theory]
  537. [AutoInitShutdown]
  538. [InlineData (Orientation.Vertical)]
  539. [InlineData (Orientation.Horizontal)]
  540. public void Moving_Mouse_Outside_Host_Ensures_Correct_Location (Orientation orientation)
  541. {
  542. var scrollBar = new ScrollBar
  543. {
  544. X = 10, Y = 10, Width = orientation == Orientation.Vertical ? 1 : 10, Height = orientation == Orientation.Vertical ? 10 : 1, Size = 20,
  545. Position = 5, Orientation = orientation
  546. };
  547. var top = new Toplevel ();
  548. top.Add (scrollBar);
  549. Application.Begin (top);
  550. var scroll = (Scroll)scrollBar.Subviews.FirstOrDefault (x => x is Scroll);
  551. Rectangle scrollSliderFrame = scroll!.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame;
  552. Assert.Equal (scrollSliderFrame, orientation == Orientation.Vertical ? new (0, 2, 1, 4) : new (2, 0, 4, 1));
  553. Application.OnMouseEvent (new () { Position = orientation == Orientation.Vertical ? new (10, 14) : new (14, 10), Flags = MouseFlags.Button1Pressed });
  554. Application.OnMouseEvent (
  555. new ()
  556. {
  557. Position = orientation == Orientation.Vertical ? new (10, 0) : new (0, 10),
  558. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  559. });
  560. Assert.Equal (new (0, 0), scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  561. Application.OnMouseEvent (
  562. new ()
  563. {
  564. Position = orientation == Orientation.Vertical ? new (0, 25) : new (80, 0),
  565. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  566. });
  567. Assert.Equal (
  568. orientation == Orientation.Vertical ? new (0, 4) : new (4, 0),
  569. scroll.Subviews.FirstOrDefault (x => x is ScrollSlider)!.Frame.Location);
  570. }
  571. [Theory]
  572. [InlineData (Orientation.Vertical, 20, 12, 10)]
  573. [InlineData (Orientation.Vertical, 40, 32, 30)]
  574. public void Position_Cannot_Be_Negative_Nor_Greater_Than_Size_Minus_Frame_Length (Orientation orientation, int size, int expectedPos1, int expectedPos2)
  575. {
  576. var scrollBar = new ScrollBar { Orientation = orientation, Height = 10, Size = size };
  577. Assert.Equal (0, scrollBar.Position);
  578. scrollBar.Position = -1;
  579. Assert.Equal (0, scrollBar.Position);
  580. scrollBar.Position = size;
  581. Assert.Equal (expectedPos1, scrollBar.Position);
  582. scrollBar.Position = expectedPos2;
  583. Assert.Equal (expectedPos2, scrollBar.Position);
  584. }
  585. [Fact]
  586. public void PositionChanging_Cancelable_And_PositionChanged_Events ()
  587. {
  588. var changingCount = 0;
  589. var changedCount = 0;
  590. var scrollBar = new ScrollBar { Size = 10 };
  591. scrollBar.PositionChanging += (s, e) =>
  592. {
  593. if (changingCount == 0)
  594. {
  595. e.Cancel = true;
  596. }
  597. changingCount++;
  598. };
  599. scrollBar.PositionChanged += (s, e) => changedCount++;
  600. scrollBar.Position = 1;
  601. Assert.Equal (0, scrollBar.Position);
  602. Assert.Equal (1, changingCount);
  603. Assert.Equal (0, changedCount);
  604. scrollBar.Position = 1;
  605. Assert.Equal (1, scrollBar.Position);
  606. Assert.Equal (2, changingCount);
  607. Assert.Equal (1, changedCount);
  608. }
  609. [Fact]
  610. public void PositionChanging_PositionChanged_Events_Only_Raises_Once_If_Position_Was_Really_Changed ()
  611. {
  612. var changing = 0;
  613. var cancel = false;
  614. var changed = 0;
  615. var scrollBar = new ScrollBar { Height = 10, Size = 20 };
  616. scrollBar.PositionChanging += Scroll_PositionChanging;
  617. scrollBar.PositionChanged += Scroll_PositionChanged;
  618. Assert.Equal (Orientation.Vertical, scrollBar.Orientation);
  619. Assert.Equal (new (0, 0, 1, 10), scrollBar.Viewport);
  620. Assert.Equal (0, scrollBar.Position);
  621. Assert.Equal (0, changing);
  622. Assert.Equal (0, changed);
  623. scrollBar.Position = 0;
  624. Assert.Equal (0, scrollBar.Position);
  625. Assert.Equal (0, changing);
  626. Assert.Equal (0, changed);
  627. scrollBar.Position = 1;
  628. Assert.Equal (1, scrollBar.Position);
  629. Assert.Equal (1, changing);
  630. Assert.Equal (1, changed);
  631. Reset ();
  632. cancel = true;
  633. scrollBar.Position = 2;
  634. Assert.Equal (1, scrollBar.Position);
  635. Assert.Equal (1, changing);
  636. Assert.Equal (0, changed);
  637. Reset ();
  638. scrollBar.Position = 10;
  639. Assert.Equal (10, scrollBar.Position);
  640. Assert.Equal (1, changing);
  641. Assert.Equal (1, changed);
  642. Reset ();
  643. scrollBar.Position = 11;
  644. Assert.Equal (11, scrollBar.Position);
  645. Assert.Equal (1, changing);
  646. Assert.Equal (1, changed);
  647. Reset ();
  648. scrollBar.Position = 12;
  649. Assert.Equal (12, scrollBar.Position);
  650. Assert.Equal (1, changing);
  651. Assert.Equal (1, changed);
  652. Reset ();
  653. scrollBar.Position = 13;
  654. Assert.Equal (12, scrollBar.Position);
  655. Assert.Equal (0, changing);
  656. Assert.Equal (0, changed);
  657. Reset ();
  658. scrollBar.Position = 0;
  659. Assert.Equal (0, scrollBar.Position);
  660. Assert.Equal (1, changing);
  661. Assert.Equal (1, changed);
  662. scrollBar.PositionChanging -= Scroll_PositionChanging;
  663. scrollBar.PositionChanged -= Scroll_PositionChanged;
  664. void Scroll_PositionChanging (object sender, CancelEventArgs<int> e)
  665. {
  666. changing++;
  667. e.Cancel = cancel;
  668. }
  669. void Scroll_PositionChanged (object sender, EventArgs<int> e) { changed++; }
  670. void Reset ()
  671. {
  672. changing = 0;
  673. cancel = false;
  674. changed = 0;
  675. }
  676. }
  677. [Fact]
  678. [AutoInitShutdown]
  679. public void ShowScrollIndicator_CheckScrollBarVisibility ()
  680. {
  681. var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = 30 };
  682. View scrollBarSuperView = ScrollBarSuperView ();
  683. scrollBarSuperView.Add (scrollBar);
  684. Application.Begin ((scrollBarSuperView.SuperView as Toplevel)!);
  685. Assert.True (scrollBar.ShowScrollIndicator);
  686. Assert.True (scrollBar.Visible);
  687. scrollBar.ShowScrollIndicator = false;
  688. Assert.True (scrollBar.AutoHide);
  689. Assert.True (scrollBar.ShowScrollIndicator);
  690. Assert.True (scrollBar.Visible);
  691. scrollBar.AutoHide = false;
  692. Assert.False (scrollBar.ShowScrollIndicator);
  693. Assert.False (scrollBar.Visible);
  694. scrollBarSuperView.SuperView!.Dispose ();
  695. }
  696. [Fact]
  697. public void Size_Cannot_Be_Negative ()
  698. {
  699. var scrollBar = new ScrollBar { Height = 10, Size = -1 };
  700. Assert.Equal (0, scrollBar.Size);
  701. scrollBar.Size = -10;
  702. Assert.Equal (0, scrollBar.Size);
  703. }
  704. [Fact]
  705. public void SizeChanged_Event ()
  706. {
  707. var count = 0;
  708. var scrollBar = new ScrollBar ();
  709. scrollBar.SizeChanged += (s, e) => count++;
  710. scrollBar.Size = 10;
  711. Assert.Equal (10, scrollBar.Size);
  712. Assert.Equal (1, count);
  713. }
  714. [Theory]
  715. [AutoInitShutdown]
  716. [InlineData (
  717. 3,
  718. 10,
  719. 1,
  720. Orientation.Vertical,
  721. @"
  722. ┌─┐
  723. │▲│
  724. │█│
  725. │█│
  726. │░│
  727. │░│
  728. │░│
  729. │░│
  730. │▼│
  731. └─┘")]
  732. [InlineData (
  733. 10,
  734. 3,
  735. 1,
  736. Orientation.Horizontal,
  737. @"
  738. ┌────────┐
  739. │◄██░░░░►│
  740. └────────┘")]
  741. [InlineData (
  742. 3,
  743. 10,
  744. 3,
  745. Orientation.Vertical,
  746. @"
  747. ┌───┐
  748. │ ▲ │
  749. │███│
  750. │███│
  751. │░░░│
  752. │░░░│
  753. │░░░│
  754. │░░░│
  755. │ ▼ │
  756. └───┘")]
  757. [InlineData (
  758. 10,
  759. 3,
  760. 3,
  761. Orientation.Horizontal,
  762. @"
  763. ┌────────┐
  764. │ ██░░░░ │
  765. │◄██░░░░►│
  766. │ ██░░░░ │
  767. └────────┘")]
  768. public void Vertical_Horizontal_Draws_Correctly (int sizeWidth, int sizeHeight, int widthHeight, Orientation orientation, string expected)
  769. {
  770. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  771. var top = new Toplevel ();
  772. top.Add (super);
  773. var scrollBar = new ScrollBar
  774. {
  775. Orientation = orientation,
  776. Size = orientation == Orientation.Vertical ? sizeHeight * 2 : sizeWidth * 2,
  777. Width = orientation == Orientation.Vertical ? widthHeight : Dim.Fill (),
  778. Height = orientation == Orientation.Vertical ? Dim.Fill () : widthHeight
  779. };
  780. super.Add (scrollBar);
  781. Application.Begin (top);
  782. ((FakeDriver)Application.Driver)!.SetBufferSize (
  783. sizeWidth + (orientation == Orientation.Vertical ? widthHeight - 1 : 0),
  784. sizeHeight + (orientation == Orientation.Vertical ? 0 : widthHeight - 1));
  785. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  786. }
  787. private View ScrollBarSuperView ()
  788. {
  789. var view = new View
  790. {
  791. Width = Dim.Fill (),
  792. Height = Dim.Fill ()
  793. };
  794. var top = new Toplevel ();
  795. top.Add (view);
  796. return view;
  797. }
  798. }