ScrollBarViewTests.cs 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. using System.Reflection;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class ScrollBarViewTests
  5. {
  6. private static HostView _hostView;
  7. private readonly ITestOutputHelper _output;
  8. private bool _added;
  9. private ScrollBarView _scrollBar;
  10. public ScrollBarViewTests (ITestOutputHelper output) { _output = output; }
  11. [Fact]
  12. [ScrollBarAutoInitShutdown]
  13. public void AutoHideScrollBars_Check ()
  14. {
  15. Hosting_A_View_To_A_ScrollBarView ();
  16. AddHandlers ();
  17. _hostView.Draw ();
  18. Assert.True (_scrollBar.ShowScrollIndicator);
  19. Assert.True (_scrollBar.Visible);
  20. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  21. Assert.Equal (1, _scrollBar.Viewport.Width);
  22. Assert.Equal (
  23. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  24. _scrollBar.Height.ToString ()
  25. );
  26. Assert.Equal (24, _scrollBar.Viewport.Height);
  27. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  28. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  29. Assert.Equal (
  30. $"Combine(View(Width,HostView(){_hostView.Frame})-Absolute(1))",
  31. _scrollBar.OtherScrollBarView.Width.ToString ()
  32. );
  33. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  34. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  35. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  36. _hostView.Lines = 10;
  37. _hostView.Draw ();
  38. Assert.False (_scrollBar.ShowScrollIndicator);
  39. Assert.False (_scrollBar.Visible);
  40. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  41. Assert.Equal (1, _scrollBar.Viewport.Width);
  42. Assert.Equal (
  43. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  44. _scrollBar.Height.ToString ()
  45. );
  46. Assert.Equal (24, _scrollBar.Viewport.Height);
  47. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  48. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  49. Assert.Equal (
  50. $"View(Width,HostView(){_hostView.Frame})",
  51. _scrollBar.OtherScrollBarView.Width.ToString ()
  52. );
  53. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  54. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  55. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  56. _hostView.Cols = 60;
  57. _hostView.Draw ();
  58. Assert.False (_scrollBar.ShowScrollIndicator);
  59. Assert.False (_scrollBar.Visible);
  60. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  61. Assert.Equal (1, _scrollBar.Viewport.Width);
  62. Assert.Equal (
  63. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  64. _scrollBar.Height.ToString ()
  65. );
  66. Assert.Equal (24, _scrollBar.Viewport.Height);
  67. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  68. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  69. Assert.Equal (
  70. $"View(Width,HostView(){_hostView.Frame})",
  71. _scrollBar.OtherScrollBarView.Width.ToString ()
  72. );
  73. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  74. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  75. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  76. _hostView.Lines = 40;
  77. _hostView.Draw ();
  78. Assert.True (_scrollBar.ShowScrollIndicator);
  79. Assert.True (_scrollBar.Visible);
  80. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  81. Assert.Equal (1, _scrollBar.Viewport.Width);
  82. Assert.Equal (
  83. $"View(Height,HostView(){_hostView.Frame})",
  84. _scrollBar.Height.ToString ()
  85. );
  86. Assert.Equal (25, _scrollBar.Viewport.Height);
  87. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  88. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  89. Assert.Equal (
  90. $"View(Width,HostView(){_hostView.Frame})",
  91. _scrollBar.OtherScrollBarView.Width.ToString ()
  92. );
  93. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  94. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  95. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  96. _hostView.Cols = 120;
  97. _hostView.Draw ();
  98. Assert.True (_scrollBar.ShowScrollIndicator);
  99. Assert.True (_scrollBar.Visible);
  100. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  101. Assert.Equal (1, _scrollBar.Viewport.Width);
  102. Assert.Equal (
  103. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  104. _scrollBar.Height.ToString ()
  105. );
  106. Assert.Equal (24, _scrollBar.Viewport.Height);
  107. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  108. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  109. Assert.Equal (
  110. $"Combine(View(Width,HostView(){_hostView.Frame})-Absolute(1))",
  111. _scrollBar.OtherScrollBarView.Width.ToString ()
  112. );
  113. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  114. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  115. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  116. }
  117. [Fact]
  118. [AutoInitShutdown]
  119. public void Both_Default_Draws_Correctly ()
  120. {
  121. var width = 3;
  122. var height = 40;
  123. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  124. var top = new Toplevel ();
  125. top.Add (super);
  126. var horiz = new ScrollBarView
  127. {
  128. Id = "horiz",
  129. Size = width * 2,
  130. // BUGBUG: ScrollBarView should work if Host is null
  131. Host = super,
  132. ShowScrollIndicator = true,
  133. IsVertical = true
  134. };
  135. super.Add (horiz);
  136. var vert = new ScrollBarView
  137. {
  138. Id = "vert",
  139. Size = height * 2,
  140. // BUGBUG: ScrollBarView should work if Host is null
  141. Host = super,
  142. ShowScrollIndicator = true,
  143. IsVertical = true
  144. };
  145. super.Add (vert);
  146. Application.Begin (top);
  147. ((FakeDriver)Application.Driver).SetBufferSize (width, height);
  148. var expected = @"
  149. ┌─┐
  150. │▲│
  151. │┬│
  152. │││
  153. │││
  154. │││
  155. │││
  156. │││
  157. │││
  158. │││
  159. │││
  160. │││
  161. │││
  162. │││
  163. │││
  164. │││
  165. │││
  166. │││
  167. │││
  168. │┴│
  169. │░│
  170. │░│
  171. │░│
  172. │░│
  173. │░│
  174. │░│
  175. │░│
  176. │░│
  177. │░│
  178. │░│
  179. │░│
  180. │░│
  181. │░│
  182. │░│
  183. │░│
  184. │░│
  185. │░│
  186. │░│
  187. │▼│
  188. └─┘";
  189. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  190. }
  191. [Fact]
  192. [ScrollBarAutoInitShutdown]
  193. public void ChangedPosition_Negative_Value ()
  194. {
  195. Hosting_A_View_To_A_ScrollBarView ();
  196. AddHandlers ();
  197. _scrollBar.Position = -20;
  198. Assert.Equal (0, _scrollBar.Position);
  199. Assert.Equal (_scrollBar.Position, _hostView.Top);
  200. _scrollBar.OtherScrollBarView.Position = -50;
  201. Assert.Equal (0, _scrollBar.OtherScrollBarView.Position);
  202. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  203. }
  204. [Fact]
  205. [ScrollBarAutoInitShutdown]
  206. public void ChangedPosition_Scrolling ()
  207. {
  208. Hosting_A_View_To_A_ScrollBarView ();
  209. AddHandlers ();
  210. for (var i = 0; i < _scrollBar.Size; i++)
  211. {
  212. _scrollBar.Position += 1;
  213. Assert.Equal (_scrollBar.Position, _hostView.Top);
  214. }
  215. for (int i = _scrollBar.Size - 1; i >= 0; i--)
  216. {
  217. _scrollBar.Position -= 1;
  218. Assert.Equal (_scrollBar.Position, _hostView.Top);
  219. }
  220. for (var i = 0; i < _scrollBar.OtherScrollBarView.Size; i++)
  221. {
  222. _scrollBar.OtherScrollBarView.Position += i;
  223. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  224. }
  225. for (int i = _scrollBar.OtherScrollBarView.Size - 1; i >= 0; i--)
  226. {
  227. _scrollBar.OtherScrollBarView.Position -= 1;
  228. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  229. }
  230. }
  231. [Fact]
  232. [ScrollBarAutoInitShutdown]
  233. public void ChangedPosition_Update_The_Hosted_View ()
  234. {
  235. Hosting_A_View_To_A_ScrollBarView ();
  236. AddHandlers ();
  237. _scrollBar.Position = 2;
  238. Assert.Equal (_scrollBar.Position, _hostView.Top);
  239. _scrollBar.OtherScrollBarView.Position = 5;
  240. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  241. }
  242. [Fact]
  243. [AutoInitShutdown]
  244. public void ClearOnVisibleFalse_Gets_Sets ()
  245. {
  246. var text =
  247. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  248. var label = new Label { Text = text };
  249. var top = new Toplevel ();
  250. top.Add (label);
  251. var sbv = new ScrollBarView (label, true, false) { Size = 100, ClearOnVisibleFalse = false };
  252. Application.Begin (top);
  253. Assert.True (sbv.Visible);
  254. TestHelpers.AssertDriverContentsWithFrameAre (
  255. @"
  256. This is a tes▲
  257. This is a tes┬
  258. This is a tes┴
  259. This is a tes░
  260. This is a tes░
  261. This is a tes▼
  262. ",
  263. _output
  264. );
  265. sbv.Visible = false;
  266. Assert.False (sbv.Visible);
  267. top.Draw ();
  268. TestHelpers.AssertDriverContentsWithFrameAre (
  269. @"
  270. This is a test
  271. This is a test
  272. This is a test
  273. This is a test
  274. This is a test
  275. This is a test
  276. ",
  277. _output
  278. );
  279. sbv.Visible = true;
  280. Assert.True (sbv.Visible);
  281. top.Draw ();
  282. TestHelpers.AssertDriverContentsWithFrameAre (
  283. @"
  284. This is a tes▲
  285. This is a tes┬
  286. This is a tes┴
  287. This is a tes░
  288. This is a tes░
  289. This is a tes▼
  290. ",
  291. _output
  292. );
  293. sbv.ClearOnVisibleFalse = true;
  294. sbv.Visible = false;
  295. Assert.False (sbv.Visible);
  296. TestHelpers.AssertDriverContentsWithFrameAre (
  297. @"
  298. This is a tes
  299. This is a tes
  300. This is a tes
  301. This is a tes
  302. This is a tes
  303. This is a tes
  304. ",
  305. _output
  306. );
  307. }
  308. [Fact]
  309. public void
  310. Constructor_ShowBothScrollIndicator_False_And_IsVertical_False_Refresh_Does_Not_Throws_An_Object_Null_Exception ()
  311. {
  312. var exception = Record.Exception (
  313. () =>
  314. {
  315. Application.Init (new FakeDriver ());
  316. Toplevel top = new ();
  317. var win = new Window { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
  318. List<string> source = new ();
  319. for (var i = 0; i < 50; i++)
  320. {
  321. var text = $"item {i} - ";
  322. for (var j = 0; j < 160; j++)
  323. {
  324. var col = j.ToString ();
  325. text += col.Length == 1 ? col [0] : col [1];
  326. }
  327. source.Add (text);
  328. }
  329. var listView = new ListView
  330. {
  331. X = 0,
  332. Y = 0,
  333. Width = Dim.Fill (),
  334. Height = Dim.Fill (),
  335. Source = new ListWrapper (source)
  336. };
  337. win.Add (listView);
  338. var newScrollBarView = new ScrollBarView (listView, false, false) { KeepContentAlwaysInViewport = true };
  339. win.Add (newScrollBarView);
  340. newScrollBarView.ChangedPosition += (s, e) =>
  341. {
  342. listView.LeftItem = newScrollBarView.Position;
  343. if (listView.LeftItem != newScrollBarView.Position)
  344. {
  345. newScrollBarView.Position = listView.LeftItem;
  346. }
  347. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  348. listView.SetNeedsDisplay ();
  349. };
  350. listView.DrawContent += (s, e) =>
  351. {
  352. newScrollBarView.Size = listView.MaxLength;
  353. Assert.Equal (newScrollBarView.Size, listView.MaxLength);
  354. newScrollBarView.Position = listView.LeftItem;
  355. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  356. newScrollBarView.Refresh ();
  357. };
  358. top.Ready += (s, e) =>
  359. {
  360. newScrollBarView.Position = 100;
  361. Assert.Equal (
  362. newScrollBarView.Position,
  363. newScrollBarView.Size
  364. - listView.LeftItem
  365. + (listView.LeftItem - listView.Viewport.Width));
  366. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  367. Assert.Equal (92, newScrollBarView.Position);
  368. Assert.Equal (92, listView.LeftItem);
  369. Application.RequestStop ();
  370. };
  371. top.Add (win);
  372. Application.Run (top);
  373. top.Dispose ();
  374. Application.Shutdown ();
  375. });
  376. Assert.Null (exception);
  377. }
  378. [Fact]
  379. public void
  380. Constructor_ShowBothScrollIndicator_False_And_IsVertical_True_Refresh_Does_Not_Throws_An_Object_Null_Exception ()
  381. {
  382. Exception exception = Record.Exception (
  383. () =>
  384. {
  385. Application.Init (new FakeDriver ());
  386. Toplevel top = new ();
  387. var win = new Window { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
  388. List<string> source = new ();
  389. for (var i = 0; i < 50; i++)
  390. {
  391. source.Add ($"item {i}");
  392. }
  393. var listView = new ListView
  394. {
  395. X = 0,
  396. Y = 0,
  397. Width = Dim.Fill (),
  398. Height = Dim.Fill (),
  399. Source = new ListWrapper (source)
  400. };
  401. win.Add (listView);
  402. var newScrollBarView = new ScrollBarView (listView, true, false) { KeepContentAlwaysInViewport = true };
  403. win.Add (newScrollBarView);
  404. newScrollBarView.ChangedPosition += (s, e) =>
  405. {
  406. listView.TopItem = newScrollBarView.Position;
  407. if (listView.TopItem != newScrollBarView.Position)
  408. {
  409. newScrollBarView.Position = listView.TopItem;
  410. }
  411. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  412. listView.SetNeedsDisplay ();
  413. };
  414. listView.DrawContent += (s, e) =>
  415. {
  416. newScrollBarView.Size = listView.Source.Count;
  417. Assert.Equal (newScrollBarView.Size, listView.Source.Count);
  418. newScrollBarView.Position = listView.TopItem;
  419. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  420. newScrollBarView.Refresh ();
  421. };
  422. top.Ready += (s, e) =>
  423. {
  424. newScrollBarView.Position = 45;
  425. Assert.Equal (
  426. newScrollBarView.Position,
  427. newScrollBarView.Size
  428. - listView.TopItem
  429. + (listView.TopItem - listView.Viewport.Height)
  430. );
  431. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  432. Assert.Equal (27, newScrollBarView.Position);
  433. Assert.Equal (27, listView.TopItem);
  434. Application.RequestStop ();
  435. };
  436. top.Add (win);
  437. Application.Run (top);
  438. top.Dispose ();
  439. Application.Shutdown ();
  440. }
  441. );
  442. Assert.Null (exception);
  443. }
  444. [Fact]
  445. [AutoInitShutdown]
  446. public void ContentBottomRightCorner_Not_Redraw_If_Both_Size_Equal_To_Zero ()
  447. {
  448. var text =
  449. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  450. var label = new Label { Text = text };
  451. var top = new Toplevel ();
  452. top.Add (label);
  453. var sbv = new ScrollBarView (label, true) { Size = 100 };
  454. sbv.OtherScrollBarView.Size = 100;
  455. Application.Begin (top);
  456. Assert.Equal (100, sbv.Size);
  457. Assert.Equal (100, sbv.OtherScrollBarView.Size);
  458. Assert.True (sbv.ShowScrollIndicator);
  459. Assert.True (sbv.OtherScrollBarView.ShowScrollIndicator);
  460. Assert.True (sbv.Visible);
  461. Assert.True (sbv.OtherScrollBarView.Visible);
  462. View contentBottomRightCorner =
  463. label.SuperView.Subviews.First (v => v is ScrollBarView.ContentBottomRightCorner);
  464. Assert.True (contentBottomRightCorner is ScrollBarView.ContentBottomRightCorner);
  465. Assert.True (contentBottomRightCorner.Visible);
  466. TestHelpers.AssertDriverContentsWithFrameAre (
  467. @"
  468. This is a tes▲
  469. This is a tes┬
  470. This is a tes┴
  471. This is a tes░
  472. This is a tes▼
  473. ◄├─┤░░░░░░░░►
  474. ",
  475. _output
  476. );
  477. sbv.Size = 0;
  478. sbv.OtherScrollBarView.Size = 0;
  479. Assert.Equal (0, sbv.Size);
  480. Assert.Equal (0, sbv.OtherScrollBarView.Size);
  481. Assert.False (sbv.ShowScrollIndicator);
  482. Assert.False (sbv.OtherScrollBarView.ShowScrollIndicator);
  483. Assert.False (sbv.Visible);
  484. Assert.False (sbv.OtherScrollBarView.Visible);
  485. top.Draw ();
  486. TestHelpers.AssertDriverContentsWithFrameAre (
  487. @"
  488. This is a test
  489. This is a test
  490. This is a test
  491. This is a test
  492. This is a test
  493. This is a test
  494. ",
  495. _output
  496. );
  497. sbv.Size = 50;
  498. sbv.OtherScrollBarView.Size = 50;
  499. Assert.Equal (50, sbv.Size);
  500. Assert.Equal (50, sbv.OtherScrollBarView.Size);
  501. Assert.True (sbv.ShowScrollIndicator);
  502. Assert.True (sbv.OtherScrollBarView.ShowScrollIndicator);
  503. Assert.True (sbv.Visible);
  504. Assert.True (sbv.OtherScrollBarView.Visible);
  505. top.Draw ();
  506. TestHelpers.AssertDriverContentsWithFrameAre (
  507. @"
  508. This is a tes▲
  509. This is a tes┬
  510. This is a tes┴
  511. This is a tes░
  512. This is a tes▼
  513. ◄├──┤░░░░░░░►
  514. ",
  515. _output
  516. );
  517. }
  518. [Fact]
  519. [AutoInitShutdown]
  520. public void ContentBottomRightCorner_Not_Redraw_If_One_Size_Equal_To_Zero ()
  521. {
  522. var text =
  523. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  524. var label = new Label { Text = text };
  525. var top = new Toplevel ();
  526. top.Add (label);
  527. var sbv = new ScrollBarView (label, true, false) { Size = 100 };
  528. Application.Begin (top);
  529. Assert.Equal (100, sbv.Size);
  530. Assert.Null (sbv.OtherScrollBarView);
  531. Assert.True (sbv.ShowScrollIndicator);
  532. Assert.True (sbv.Visible);
  533. TestHelpers.AssertDriverContentsWithFrameAre (
  534. @"
  535. This is a tes▲
  536. This is a tes┬
  537. This is a tes┴
  538. This is a tes░
  539. This is a tes░
  540. This is a tes▼
  541. ",
  542. _output
  543. );
  544. sbv.Size = 0;
  545. Assert.Equal (0, sbv.Size);
  546. Assert.False (sbv.ShowScrollIndicator);
  547. Assert.False (sbv.Visible);
  548. top.Draw ();
  549. TestHelpers.AssertDriverContentsWithFrameAre (
  550. @"
  551. This is a test
  552. This is a test
  553. This is a test
  554. This is a test
  555. This is a test
  556. This is a test
  557. ",
  558. _output
  559. );
  560. }
  561. [Fact]
  562. [ScrollBarAutoInitShutdown]
  563. public void DrawContent_Update_The_ScrollBarView_Position ()
  564. {
  565. Hosting_A_View_To_A_ScrollBarView ();
  566. AddHandlers ();
  567. _hostView.Top = 3;
  568. _hostView.Draw ();
  569. Assert.Equal (_scrollBar.Position, _hostView.Top);
  570. _hostView.Left = 6;
  571. _hostView.Draw ();
  572. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  573. }
  574. [Fact]
  575. [AutoInitShutdown]
  576. public void Horizontal_Default_Draws_Correctly ()
  577. {
  578. var width = 40;
  579. var height = 3;
  580. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  581. var top = new Toplevel ();
  582. top.Add (super);
  583. var sbv = new ScrollBarView { Id = "sbv", Size = width * 2, ShowScrollIndicator = true };
  584. super.Add (sbv);
  585. Application.Begin (top);
  586. ((FakeDriver)Application.Driver).SetBufferSize (width, height);
  587. var expected = @"
  588. ┌──────────────────────────────────────┐
  589. │◄├────────────────┤░░░░░░░░░░░░░░░░░░►│
  590. └──────────────────────────────────────┘";
  591. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  592. }
  593. [Fact]
  594. [ScrollBarAutoInitShutdown]
  595. public void Hosting_A_Null_SuperView_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  596. {
  597. Assert.Throws<ArgumentNullException> (
  598. "The host SuperView parameter can't be null.",
  599. () => new ScrollBarView (new View (), true)
  600. );
  601. Assert.Throws<ArgumentNullException> (
  602. "The host SuperView parameter can't be null.",
  603. () => new ScrollBarView (new View (), false)
  604. );
  605. }
  606. [Fact]
  607. [ScrollBarAutoInitShutdown]
  608. public void Hosting_A_Null_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  609. {
  610. Assert.Throws<ArgumentNullException> (
  611. "The host parameter can't be null.",
  612. () => new ScrollBarView (null, true)
  613. );
  614. Assert.Throws<ArgumentNullException> (
  615. "The host parameter can't be null.",
  616. () => new ScrollBarView (null, false)
  617. );
  618. }
  619. [Fact]
  620. [ScrollBarAutoInitShutdown]
  621. public void Hosting_A_View_To_A_ScrollBarView ()
  622. {
  623. RemoveHandlers ();
  624. _scrollBar = new ScrollBarView (_hostView, true);
  625. Application.Begin (_hostView.SuperView as Toplevel);
  626. Assert.True (_scrollBar.IsVertical);
  627. Assert.False (_scrollBar.OtherScrollBarView.IsVertical);
  628. Assert.Equal (_scrollBar.Position, _hostView.Top);
  629. Assert.NotEqual (_scrollBar.Size, _hostView.Lines);
  630. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  631. Assert.NotEqual (_scrollBar.OtherScrollBarView.Size, _hostView.Cols);
  632. AddHandlers ();
  633. _hostView.SuperView.LayoutSubviews ();
  634. _hostView.Draw ();
  635. Assert.Equal (_scrollBar.Position, _hostView.Top);
  636. Assert.Equal (_scrollBar.Size, _hostView.Lines);
  637. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  638. Assert.Equal (_scrollBar.OtherScrollBarView.Size, _hostView.Cols);
  639. }
  640. [Fact]
  641. [AutoInitShutdown]
  642. public void Hosting_ShowBothScrollIndicator_Invisible ()
  643. {
  644. var textView = new TextView
  645. {
  646. Width = Dim.Fill (),
  647. Height = Dim.Fill (),
  648. Text =
  649. "This is the help text for the Second Step.\n\nPress the button to see a message box.\n\nEnter name too."
  650. };
  651. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  652. win.Add (textView);
  653. var scrollBar = new ScrollBarView (textView, true);
  654. scrollBar.ChangedPosition += (s, e) =>
  655. {
  656. textView.TopRow = scrollBar.Position;
  657. if (textView.TopRow != scrollBar.Position)
  658. {
  659. scrollBar.Position = textView.TopRow;
  660. }
  661. textView.SetNeedsDisplay ();
  662. };
  663. scrollBar.OtherScrollBarView.ChangedPosition += (s, e) =>
  664. {
  665. textView.LeftColumn = scrollBar.OtherScrollBarView.Position;
  666. if (textView.LeftColumn != scrollBar.OtherScrollBarView.Position)
  667. {
  668. scrollBar.OtherScrollBarView.Position = textView.LeftColumn;
  669. }
  670. textView.SetNeedsDisplay ();
  671. };
  672. scrollBar.VisibleChanged += (s, e) =>
  673. {
  674. if (scrollBar.Visible && textView.RightOffset == 0)
  675. {
  676. textView.RightOffset = 1;
  677. }
  678. else if (!scrollBar.Visible && textView.RightOffset == 1)
  679. {
  680. textView.RightOffset = 0;
  681. }
  682. };
  683. scrollBar.OtherScrollBarView.VisibleChanged += (s, e) =>
  684. {
  685. if (scrollBar.OtherScrollBarView.Visible && textView.BottomOffset == 0)
  686. {
  687. textView.BottomOffset = 1;
  688. }
  689. else if (!scrollBar.OtherScrollBarView.Visible && textView.BottomOffset == 1)
  690. {
  691. textView.BottomOffset = 0;
  692. }
  693. };
  694. textView.LayoutComplete += (s, e) =>
  695. {
  696. scrollBar.Size = textView.Lines;
  697. scrollBar.Position = textView.TopRow;
  698. if (scrollBar.OtherScrollBarView != null)
  699. {
  700. scrollBar.OtherScrollBarView.Size = textView.Maxlength;
  701. scrollBar.OtherScrollBarView.Position = textView.LeftColumn;
  702. }
  703. scrollBar.LayoutSubviews ();
  704. scrollBar.Refresh ();
  705. };
  706. var top = new Toplevel ();
  707. top.Add (win);
  708. Application.Begin (top);
  709. ((FakeDriver)Application.Driver).SetBufferSize (45, 20);
  710. Assert.True (scrollBar.AutoHideScrollBars);
  711. Assert.False (scrollBar.ShowScrollIndicator);
  712. Assert.False (scrollBar.OtherScrollBarView.ShowScrollIndicator);
  713. Assert.Equal (5, textView.Lines);
  714. Assert.Equal (42, textView.Maxlength);
  715. Assert.Equal (0, textView.LeftColumn);
  716. Assert.Equal (0, scrollBar.Position);
  717. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  718. var expected = @"
  719. ┌───────────────────────────────────────────┐
  720. │This is the help text for the Second Step. │
  721. │ │
  722. │Press the button to see a message box. │
  723. │ │
  724. │Enter name too. │
  725. │ │
  726. │ │
  727. │ │
  728. │ │
  729. │ │
  730. │ │
  731. │ │
  732. │ │
  733. │ │
  734. │ │
  735. │ │
  736. │ │
  737. │ │
  738. └───────────────────────────────────────────┘
  739. ";
  740. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  741. Assert.Equal (new Rectangle (0, 0, 45, 20), pos);
  742. textView.WordWrap = true;
  743. ((FakeDriver)Application.Driver).SetBufferSize (26, 20);
  744. Application.Refresh ();
  745. Assert.True (textView.WordWrap);
  746. Assert.True (scrollBar.AutoHideScrollBars);
  747. Assert.Equal (7, textView.Lines);
  748. Assert.Equal (22, textView.Maxlength);
  749. Assert.Equal (0, textView.LeftColumn);
  750. Assert.Equal (0, scrollBar.Position);
  751. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  752. expected = @"
  753. ┌────────────────────────┐
  754. │This is the help text │
  755. │for the Second Step. │
  756. │ │
  757. │Press the button to │
  758. │see a message box. │
  759. │ │
  760. │Enter name too. │
  761. │ │
  762. │ │
  763. │ │
  764. │ │
  765. │ │
  766. │ │
  767. │ │
  768. │ │
  769. │ │
  770. │ │
  771. │ │
  772. └────────────────────────┘
  773. ";
  774. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  775. Assert.Equal (new Rectangle (0, 0, 26, 20), pos);
  776. ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
  777. Application.Refresh ();
  778. Assert.True (textView.WordWrap);
  779. Assert.True (scrollBar.AutoHideScrollBars);
  780. Assert.Equal (20, textView.Lines);
  781. Assert.Equal (7, textView.Maxlength);
  782. Assert.Equal (0, textView.LeftColumn);
  783. Assert.Equal (0, scrollBar.Position);
  784. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  785. Assert.True (scrollBar.ShowScrollIndicator);
  786. expected = @"
  787. ┌────────┐
  788. │This ▲│
  789. │is the ┬│
  790. │help ││
  791. │text ┴│
  792. │for ░│
  793. │the ░│
  794. │Second ░│
  795. │Step. ▼│
  796. └────────┘
  797. ";
  798. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  799. Assert.Equal (new Rectangle (0, 0, 10, 10), pos);
  800. }
  801. [Fact]
  802. [ScrollBarAutoInitShutdown]
  803. public void Hosting_Two_Horizontal_ScrollBarView_Throws_ArgumentException ()
  804. {
  805. var top = new Toplevel ();
  806. var host = new View ();
  807. top.Add (host);
  808. var v = new ScrollBarView (host, false);
  809. var h = new ScrollBarView (host, false);
  810. Assert.Throws<ArgumentException> (() => v.OtherScrollBarView = h);
  811. Assert.Throws<ArgumentException> (() => h.OtherScrollBarView = v);
  812. }
  813. [Fact]
  814. [ScrollBarAutoInitShutdown]
  815. public void Hosting_Two_Vertical_ScrollBarView_Throws_ArgumentException ()
  816. {
  817. var top = new Toplevel ();
  818. var host = new View ();
  819. top.Add (host);
  820. var v = new ScrollBarView (host, true);
  821. var h = new ScrollBarView (host, true);
  822. Assert.Throws<ArgumentException> (() => v.OtherScrollBarView = h);
  823. Assert.Throws<ArgumentException> (() => h.OtherScrollBarView = v);
  824. }
  825. [Fact]
  826. [AutoInitShutdown]
  827. public void Internal_Tests ()
  828. {
  829. Toplevel top = new ();
  830. Assert.Equal (new Rectangle (0, 0, 80, 25), top.Viewport);
  831. var view = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  832. top.Add (view);
  833. var sbv = new ScrollBarView (view, true);
  834. top.Add (sbv);
  835. Assert.Equal (view, sbv.Host);
  836. sbv.Size = 40;
  837. sbv.Position = 0;
  838. sbv.OtherScrollBarView.Size = 100;
  839. sbv.OtherScrollBarView.Position = 0;
  840. // Host bounds is not empty.
  841. Assert.True (sbv.CanScroll (10, out int max, sbv.IsVertical));
  842. Assert.Equal (10, max);
  843. Assert.True (sbv.OtherScrollBarView.CanScroll (10, out max, sbv.OtherScrollBarView.IsVertical));
  844. Assert.Equal (10, max);
  845. Application.Begin (top);
  846. // They are visible so they are drawn.
  847. Assert.True (sbv.Visible);
  848. Assert.True (sbv.OtherScrollBarView.Visible);
  849. top.LayoutSubviews ();
  850. // Now the host bounds is not empty.
  851. Assert.True (sbv.CanScroll (10, out max, sbv.IsVertical));
  852. Assert.Equal (10, max);
  853. Assert.True (sbv.OtherScrollBarView.CanScroll (10, out max, sbv.OtherScrollBarView.IsVertical));
  854. Assert.Equal (10, max);
  855. Assert.True (sbv.CanScroll (50, out max, sbv.IsVertical));
  856. Assert.Equal (40, sbv.Size);
  857. Assert.Equal (16, max); // 16+25=41
  858. Assert.True (sbv.OtherScrollBarView.CanScroll (150, out max, sbv.OtherScrollBarView.IsVertical));
  859. Assert.Equal (100, sbv.OtherScrollBarView.Size);
  860. Assert.Equal (21, max); // 21+80=101
  861. Assert.True (sbv.Visible);
  862. Assert.True (sbv.OtherScrollBarView.Visible);
  863. sbv.KeepContentAlwaysInViewport = false;
  864. sbv.OtherScrollBarView.KeepContentAlwaysInViewport = false;
  865. Assert.True (sbv.CanScroll (50, out max, sbv.IsVertical));
  866. Assert.Equal (39, max);
  867. Assert.True (sbv.OtherScrollBarView.CanScroll (150, out max, sbv.OtherScrollBarView.IsVertical));
  868. Assert.Equal (99, max);
  869. Assert.True (sbv.Visible);
  870. Assert.True (sbv.OtherScrollBarView.Visible);
  871. }
  872. [Fact]
  873. [ScrollBarAutoInitShutdown]
  874. public void KeepContentAlwaysInViewport_False ()
  875. {
  876. Hosting_A_View_To_A_ScrollBarView ();
  877. AddHandlers ();
  878. _scrollBar.KeepContentAlwaysInViewport = false;
  879. _scrollBar.Position = 50;
  880. Assert.Equal (_scrollBar.Position, _scrollBar.Size - 1);
  881. Assert.Equal (_scrollBar.Position, _hostView.Top);
  882. Assert.Equal (29, _scrollBar.Position);
  883. Assert.Equal (29, _hostView.Top);
  884. _scrollBar.OtherScrollBarView.Position = 150;
  885. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _scrollBar.OtherScrollBarView.Size - 1);
  886. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  887. Assert.Equal (99, _scrollBar.OtherScrollBarView.Position);
  888. Assert.Equal (99, _hostView.Left);
  889. }
  890. [Fact]
  891. [ScrollBarAutoInitShutdown]
  892. public void KeepContentAlwaysInViewport_True ()
  893. {
  894. Hosting_A_View_To_A_ScrollBarView ();
  895. AddHandlers ();
  896. Assert.Equal (80, _hostView.Viewport.Width);
  897. Assert.Equal (25, _hostView.Viewport.Height);
  898. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  899. Assert.Equal (24, _scrollBar.Viewport.Height);
  900. Assert.Equal (30, _scrollBar.Size);
  901. Assert.Equal (100, _scrollBar.OtherScrollBarView.Size);
  902. Assert.True (_scrollBar.ShowScrollIndicator);
  903. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  904. Assert.True (_scrollBar.Visible);
  905. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  906. _scrollBar.Position = 50;
  907. Assert.Equal (_scrollBar.Position, _scrollBar.Size - _scrollBar.Viewport.Height);
  908. Assert.Equal (_scrollBar.Position, _hostView.Top);
  909. Assert.Equal (6, _scrollBar.Position);
  910. Assert.Equal (6, _hostView.Top);
  911. Assert.True (_scrollBar.ShowScrollIndicator);
  912. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  913. Assert.True (_scrollBar.Visible);
  914. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  915. _scrollBar.OtherScrollBarView.Position = 150;
  916. Assert.Equal (
  917. _scrollBar.OtherScrollBarView.Position,
  918. _scrollBar.OtherScrollBarView.Size - _scrollBar.OtherScrollBarView.Viewport.Width
  919. );
  920. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  921. Assert.Equal (21, _scrollBar.OtherScrollBarView.Position);
  922. Assert.Equal (21, _hostView.Left);
  923. Assert.True (_scrollBar.ShowScrollIndicator);
  924. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  925. Assert.True (_scrollBar.Visible);
  926. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  927. }
  928. [Fact]
  929. [ScrollBarAutoInitShutdown]
  930. public void OtherScrollBarView_Not_Null ()
  931. {
  932. Hosting_A_View_To_A_ScrollBarView ();
  933. AddHandlers ();
  934. Assert.NotNull (_scrollBar.OtherScrollBarView);
  935. Assert.NotEqual (_scrollBar, _scrollBar.OtherScrollBarView);
  936. Assert.Equal (_scrollBar.OtherScrollBarView.OtherScrollBarView, _scrollBar);
  937. }
  938. [Fact]
  939. [ScrollBarAutoInitShutdown]
  940. public void Scrolling_With_Default_Constructor_Do_Not_Scroll ()
  941. {
  942. var sbv = new ScrollBarView { Position = 1 };
  943. Assert.Equal (1, sbv.Position);
  944. Assert.NotEqual (0, sbv.Position);
  945. }
  946. [Fact]
  947. [ScrollBarAutoInitShutdown]
  948. public void ShowScrollIndicator_Check ()
  949. {
  950. Hosting_A_View_To_A_ScrollBarView ();
  951. AddHandlers ();
  952. Assert.True (_scrollBar.ShowScrollIndicator);
  953. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  954. }
  955. [Fact]
  956. [AutoInitShutdown]
  957. public void ShowScrollIndicator_False_Must_Also_Set_Visible_To_False_To_Not_Respond_To_Events ()
  958. {
  959. var clicked = false;
  960. var text = "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  961. var label = new Label { AutoSize = false, Width = 14, Height = 5, Text = text };
  962. var btn = new Button { X = 14, Text = "Click Me!" };
  963. btn.Accept += (s, e) => clicked = true;
  964. var top = new Toplevel ();
  965. top.Add (label, btn);
  966. var sbv = new ScrollBarView (label, true, false) { Size = 5 };
  967. Application.Begin (top);
  968. Assert.Equal (5, sbv.Size);
  969. Assert.Null (sbv.OtherScrollBarView);
  970. Assert.False (sbv.ShowScrollIndicator);
  971. Assert.False (sbv.Visible);
  972. TestHelpers.AssertDriverContentsWithFrameAre (
  973. @$"
  974. This is a test{
  975. CM.Glyphs.LeftBracket
  976. } Click Me! {
  977. CM.Glyphs.RightBracket
  978. }
  979. This is a test
  980. This is a test
  981. This is a test
  982. This is a test ",
  983. _output
  984. );
  985. Application.OnMouseEvent (
  986. new MouseEventEventArgs (
  987. new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked }
  988. )
  989. );
  990. Assert.Null (Application.MouseGrabView);
  991. Assert.True (clicked);
  992. clicked = false;
  993. sbv.Visible = true;
  994. Assert.Equal (5, sbv.Size);
  995. Assert.False (sbv.ShowScrollIndicator);
  996. Assert.True (sbv.Visible);
  997. top.Draw ();
  998. Assert.False (sbv.Visible);
  999. TestHelpers.AssertDriverContentsWithFrameAre (
  1000. @$"
  1001. This is a test{
  1002. CM.Glyphs.LeftBracket
  1003. } Click Me! {
  1004. CM.Glyphs.RightBracket
  1005. }
  1006. This is a test
  1007. This is a test
  1008. This is a test
  1009. This is a test ",
  1010. _output
  1011. );
  1012. Application.OnMouseEvent (
  1013. new MouseEventEventArgs (
  1014. new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked }
  1015. )
  1016. );
  1017. Assert.Null (Application.MouseGrabView);
  1018. Assert.True (clicked);
  1019. Assert.Equal (5, sbv.Size);
  1020. Assert.False (sbv.ShowScrollIndicator);
  1021. Assert.False (sbv.Visible);
  1022. }
  1023. [Fact]
  1024. [AutoInitShutdown]
  1025. public void Vertical_Default_Draws_Correctly ()
  1026. {
  1027. var width = 3;
  1028. var height = 40;
  1029. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  1030. var top = new Toplevel ();
  1031. top.Add (super);
  1032. var sbv = new ScrollBarView
  1033. {
  1034. Id = "sbv",
  1035. Size = height * 2,
  1036. // BUGBUG: ScrollBarView should work if Host is null
  1037. Host = super,
  1038. ShowScrollIndicator = true,
  1039. IsVertical = true
  1040. };
  1041. super.Add (sbv);
  1042. Application.Begin (top);
  1043. ((FakeDriver)Application.Driver).SetBufferSize (width, height);
  1044. var expected = @"
  1045. ┌─┐
  1046. │▲│
  1047. │┬│
  1048. │││
  1049. │││
  1050. │││
  1051. │││
  1052. │││
  1053. │││
  1054. │││
  1055. │││
  1056. │││
  1057. │││
  1058. │││
  1059. │││
  1060. │││
  1061. │││
  1062. │││
  1063. │││
  1064. │┴│
  1065. │░│
  1066. │░│
  1067. │░│
  1068. │░│
  1069. │░│
  1070. │░│
  1071. │░│
  1072. │░│
  1073. │░│
  1074. │░│
  1075. │░│
  1076. │░│
  1077. │░│
  1078. │░│
  1079. │░│
  1080. │░│
  1081. │░│
  1082. │░│
  1083. │▼│
  1084. └─┘";
  1085. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  1086. }
  1087. private void _hostView_DrawContent (object sender, DrawEventArgs e)
  1088. {
  1089. _scrollBar.Size = _hostView.Lines;
  1090. _scrollBar.Position = _hostView.Top;
  1091. _scrollBar.OtherScrollBarView.Size = _hostView.Cols;
  1092. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  1093. _scrollBar.Refresh ();
  1094. }
  1095. private void _scrollBar_ChangedPosition (object sender, EventArgs e)
  1096. {
  1097. _hostView.Top = _scrollBar.Position;
  1098. if (_hostView.Top != _scrollBar.Position)
  1099. {
  1100. _scrollBar.Position = _hostView.Top;
  1101. }
  1102. _hostView.SetNeedsDisplay ();
  1103. }
  1104. private void _scrollBar_OtherScrollBarView_ChangedPosition (object sender, EventArgs e)
  1105. {
  1106. _hostView.Left = _scrollBar.OtherScrollBarView.Position;
  1107. if (_hostView.Left != _scrollBar.OtherScrollBarView.Position)
  1108. {
  1109. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  1110. }
  1111. _hostView.SetNeedsDisplay ();
  1112. }
  1113. private void AddHandlers ()
  1114. {
  1115. if (!_added)
  1116. {
  1117. _hostView.DrawContent += _hostView_DrawContent;
  1118. _scrollBar.ChangedPosition += _scrollBar_ChangedPosition;
  1119. _scrollBar.OtherScrollBarView.ChangedPosition += _scrollBar_OtherScrollBarView_ChangedPosition;
  1120. }
  1121. _added = true;
  1122. }
  1123. private void RemoveHandlers ()
  1124. {
  1125. if (_added)
  1126. {
  1127. _hostView.DrawContent -= _hostView_DrawContent;
  1128. _scrollBar.ChangedPosition -= _scrollBar_ChangedPosition;
  1129. _scrollBar.OtherScrollBarView.ChangedPosition -= _scrollBar_OtherScrollBarView_ChangedPosition;
  1130. }
  1131. _added = false;
  1132. }
  1133. public class HostView : View
  1134. {
  1135. public int Cols { get; set; }
  1136. public int Left { get; set; }
  1137. public int Lines { get; set; }
  1138. public int Top { get; set; }
  1139. }
  1140. // This class enables test functions annotated with the [InitShutdown] attribute
  1141. // to have a function called before the test function is called and after.
  1142. //
  1143. // This is necessary because a) Application is a singleton and Init/Shutdown must be called
  1144. // as a pair, and b) all unit test functions should be atomic.
  1145. [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
  1146. public class ScrollBarAutoInitShutdownAttribute : AutoInitShutdownAttribute
  1147. {
  1148. public override void After (MethodInfo methodUnderTest)
  1149. {
  1150. _hostView = null;
  1151. base.After (methodUnderTest);
  1152. }
  1153. public override void Before (MethodInfo methodUnderTest)
  1154. {
  1155. base.Before (methodUnderTest);
  1156. _hostView = new HostView
  1157. {
  1158. Width = Dim.Fill (),
  1159. Height = Dim.Fill (),
  1160. Top = 0,
  1161. Lines = 30,
  1162. Left = 0,
  1163. Cols = 100
  1164. };
  1165. var top = new Toplevel ();
  1166. top.Add (_hostView);
  1167. }
  1168. }
  1169. }