DrawTests.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. #nullable enable
  2. using System.Text;
  3. using Microsoft.VisualStudio.TestPlatform.Utilities;
  4. using Xunit.Abstractions;
  5. namespace Terminal.Gui.ViewTests;
  6. [Trait ("Category", "Output")]
  7. public class DrawTests (ITestOutputHelper _output)
  8. {
  9. [Fact]
  10. [AutoInitShutdown]
  11. [Trait ("Category", "Unicode")]
  12. public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two ()
  13. {
  14. const string us = "\U0000f900";
  15. var r = (Rune)0xf900;
  16. Assert.Equal ("豈", us);
  17. Assert.Equal ("豈", r.ToString ());
  18. Assert.Equal (us, r.ToString ());
  19. Assert.Equal (2, us.GetColumns ());
  20. Assert.Equal (2, r.GetColumns ());
  21. var win = new Window { Title = us };
  22. var view = new View { Text = r.ToString (), Height = Dim.Fill (), Width = Dim.Fill () };
  23. var tf = new TextField { Text = us, Y = 1, Width = 3 };
  24. win.Add (view, tf);
  25. Toplevel top = new ();
  26. top.Add (win);
  27. Application.Begin (top);
  28. ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
  29. const string expectedOutput = """
  30. ┌┤豈├────┐
  31. │豈 │
  32. │豈 │
  33. └────────┘
  34. """;
  35. TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output);
  36. TestHelpers.AssertDriverContentsAre (expectedOutput, _output);
  37. // This test has nothing to do with color - removing as it is not relevant and fragile
  38. top.Dispose ();
  39. }
  40. [Fact]
  41. [AutoInitShutdown]
  42. [Trait ("Category", "Output")]
  43. public void Colors_On_TextAlignment_Right_And_Bottom ()
  44. {
  45. var viewRight = new View
  46. {
  47. Text = "Test",
  48. Width = 6,
  49. Height = 1,
  50. TextAlignment = Alignment.End,
  51. ColorScheme = Colors.ColorSchemes ["Base"]
  52. };
  53. var viewBottom = new View
  54. {
  55. Text = "Test",
  56. TextDirection = TextDirection.TopBottom_LeftRight,
  57. Y = 1,
  58. Width = 1,
  59. Height = 6,
  60. VerticalTextAlignment = Alignment.End,
  61. ColorScheme = Colors.ColorSchemes ["Base"]
  62. };
  63. Toplevel top = new ();
  64. top.Add (viewRight, viewBottom);
  65. var rs = Application.Begin (top);
  66. ((FakeDriver)Application.Driver!).SetBufferSize (7, 7);
  67. Application.RunIteration (ref rs);
  68. TestHelpers.AssertDriverContentsWithFrameAre (
  69. """
  70. Test
  71. T
  72. e
  73. s
  74. t
  75. """,
  76. _output
  77. );
  78. TestHelpers.AssertDriverAttributesAre (
  79. """
  80. 000000
  81. 0
  82. 0
  83. 0
  84. 0
  85. 0
  86. 0
  87. """,
  88. _output,
  89. Application.Driver,
  90. Colors.ColorSchemes ["Base"]!.Normal
  91. );
  92. top.Dispose ();
  93. }
  94. [Fact]
  95. [SetupFakeDriver]
  96. public void Draw_Minimum_Full_Border_With_Empty_Viewport ()
  97. {
  98. var view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single };
  99. Assert.True (view.NeedsLayout);
  100. Assert.True (view.NeedsDraw);
  101. view.Layout ();
  102. Assert.Equal (new (0, 0, 2, 2), view.Frame);
  103. Assert.Equal (Rectangle.Empty, view.Viewport);
  104. Assert.True (view.NeedsDraw);
  105. view.Draw ();
  106. TestHelpers.AssertDriverContentsWithFrameAre (
  107. """
  108. ┌┐
  109. └┘
  110. """,
  111. _output
  112. );
  113. }
  114. [Fact]
  115. [SetupFakeDriver]
  116. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Bottom ()
  117. {
  118. var view = new View { Width = 2, Height = 1, BorderStyle = LineStyle.Single };
  119. view.Border!.Thickness = new (1, 1, 1, 0);
  120. view.BeginInit ();
  121. view.EndInit ();
  122. view.SetRelativeLayout (Application.Screen.Size);
  123. Assert.Equal (new (0, 0, 2, 1), view.Frame);
  124. Assert.Equal (Rectangle.Empty, view.Viewport);
  125. view.Draw ();
  126. TestHelpers.AssertDriverContentsWithFrameAre ("──", _output);
  127. }
  128. [Fact]
  129. [SetupFakeDriver]
  130. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Left ()
  131. {
  132. var view = new View { Width = 1, Height = 2, BorderStyle = LineStyle.Single };
  133. view.Border!.Thickness = new (0, 1, 1, 1);
  134. view.BeginInit ();
  135. view.EndInit ();
  136. view.SetRelativeLayout (Application.Screen.Size);
  137. Assert.Equal (new (0, 0, 1, 2), view.Frame);
  138. Assert.Equal (Rectangle.Empty, view.Viewport);
  139. view.Draw ();
  140. TestHelpers.AssertDriverContentsWithFrameAre (
  141. """
  142. """,
  143. _output
  144. );
  145. }
  146. [Fact]
  147. [SetupFakeDriver]
  148. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Right ()
  149. {
  150. var view = new View { Width = 1, Height = 2, BorderStyle = LineStyle.Single };
  151. view.Border!.Thickness = new (1, 1, 0, 1);
  152. view.BeginInit ();
  153. view.EndInit ();
  154. view.SetRelativeLayout (Application.Screen.Size);
  155. Assert.Equal (new (0, 0, 1, 2), view.Frame);
  156. Assert.Equal (Rectangle.Empty, view.Viewport);
  157. view.Draw ();
  158. TestHelpers.AssertDriverContentsWithFrameAre (
  159. """
  160. """,
  161. _output
  162. );
  163. }
  164. [Fact]
  165. [SetupFakeDriver]
  166. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Top ()
  167. {
  168. var view = new View { Width = 2, Height = 1, BorderStyle = LineStyle.Single };
  169. view.Border!.Thickness = new (1, 0, 1, 1);
  170. view.BeginInit ();
  171. view.EndInit ();
  172. view.SetRelativeLayout (Application.Screen.Size);
  173. Assert.Equal (new (0, 0, 2, 1), view.Frame);
  174. Assert.Equal (Rectangle.Empty, view.Viewport);
  175. view.Draw ();
  176. TestHelpers.AssertDriverContentsWithFrameAre (
  177. "││",
  178. _output
  179. );
  180. }
  181. [Fact]
  182. [AutoInitShutdown]
  183. public void Draw_Negative_Viewport_Horizontal_With_New_Lines ()
  184. {
  185. var subView = new View
  186. {
  187. Id = "subView",
  188. X = 1,
  189. Width = 1,
  190. Height = 7,
  191. Text = """
  192. s
  193. u
  194. b
  195. V
  196. i
  197. e
  198. w
  199. """
  200. };
  201. var view = new View
  202. {
  203. Id = "view", Width = 2, Height = 20, Text = """
  204. 0
  205. 1
  206. 2
  207. 3
  208. 4
  209. 5
  210. 6
  211. 7
  212. 8
  213. 9
  214. 0
  215. 1
  216. 2
  217. 3
  218. 4
  219. 5
  220. 6
  221. 7
  222. 8
  223. 9
  224. """
  225. };
  226. view.Add (subView);
  227. var content = new View { Id = "content", Width = 20, Height = 20 };
  228. content.Add (view);
  229. var container = new View
  230. {
  231. Id = "container",
  232. X = 1,
  233. Y = 1,
  234. Width = 5,
  235. Height = 5
  236. };
  237. container.Add (content);
  238. Toplevel top = new ();
  239. top.Add (container);
  240. var rs = Application.Begin (top);
  241. top.Draw ();
  242. TestHelpers.AssertDriverContentsWithFrameAre (
  243. """
  244. 0s
  245. 1u
  246. 2b
  247. 3V
  248. 4i
  249. """,
  250. _output
  251. );
  252. content.X = -1;
  253. Application.LayoutAndDraw ();
  254. TestHelpers.AssertDriverContentsWithFrameAre (
  255. """
  256. s
  257. u
  258. b
  259. V
  260. i
  261. """,
  262. _output
  263. );
  264. content.X = -2;
  265. Application.LayoutAndDraw ();
  266. TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
  267. content.X = 0;
  268. content.Y = -1;
  269. Application.LayoutAndDraw ();
  270. TestHelpers.AssertDriverContentsWithFrameAre (
  271. """
  272. 1u
  273. 2b
  274. 3V
  275. 4i
  276. 5e
  277. """,
  278. _output
  279. );
  280. content.Y = -6;
  281. Application.LayoutAndDraw ();
  282. TestHelpers.AssertDriverContentsWithFrameAre (
  283. """
  284. 6w
  285. 7
  286. 8
  287. 9
  288. 0
  289. """,
  290. _output
  291. );
  292. content.Y = -19;
  293. Application.LayoutAndDraw ();
  294. TestHelpers.AssertDriverContentsWithFrameAre (
  295. """
  296. 9
  297. """,
  298. _output
  299. );
  300. content.Y = -20;
  301. Application.LayoutAndDraw ();
  302. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  303. content.X = -2;
  304. content.Y = 0;
  305. Application.LayoutAndDraw ();
  306. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  307. top.Dispose ();
  308. }
  309. [Fact]
  310. [AutoInitShutdown]
  311. public void Draw_Negative_Viewport_Horizontal_Without_New_Lines ()
  312. {
  313. // BUGBUG: This previously assumed the default height of a View was 1.
  314. var subView = new View
  315. {
  316. Id = "subView",
  317. Y = 1,
  318. Width = 7,
  319. Height = 1,
  320. Text = "subView"
  321. };
  322. var view = new View { Id = "view", Width = 20, Height = 2, Text = "01234567890123456789" };
  323. view.Add (subView);
  324. var content = new View { Id = "content", Width = 20, Height = 20 };
  325. content.Add (view);
  326. var container = new View
  327. {
  328. Id = "container",
  329. X = 1,
  330. Y = 1,
  331. Width = 5,
  332. Height = 5
  333. };
  334. container.Add (content);
  335. Toplevel top = new ();
  336. top.Add (container);
  337. // BUGBUG: v2 - it's bogus to reference .Frame before BeginInit. And why is the clip being set anyway???
  338. top.SubviewsLaidOut += Top_LayoutComplete;
  339. Application.Begin (top);
  340. Application.LayoutAndDraw ();
  341. TestHelpers.AssertDriverContentsWithFrameAre (
  342. """
  343. 01234
  344. subVi
  345. """,
  346. _output
  347. );
  348. content.X = -1;
  349. Application.LayoutAndDraw ();
  350. TestHelpers.AssertDriverContentsWithFrameAre (
  351. """
  352. 12345
  353. ubVie
  354. """,
  355. _output
  356. );
  357. content.Y = -1;
  358. Application.LayoutAndDraw ();
  359. TestHelpers.AssertDriverContentsWithFrameAre (
  360. """
  361. ubVie
  362. """,
  363. _output
  364. );
  365. content.Y = -2;
  366. Application.LayoutAndDraw ();
  367. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  368. content.X = -20;
  369. content.Y = 0;
  370. Application.LayoutAndDraw ();
  371. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  372. top.Dispose ();
  373. return;
  374. void Top_LayoutComplete (object? sender, LayoutEventArgs e) { Application.Driver!.Clip = new (container.Frame); }
  375. }
  376. [Fact]
  377. [AutoInitShutdown]
  378. public void Draw_Negative_Viewport_Vertical ()
  379. {
  380. var subView = new View
  381. {
  382. Id = "subView",
  383. X = 1,
  384. Width = 1,
  385. Height = 7,
  386. Text = "subView",
  387. TextDirection = TextDirection.TopBottom_LeftRight
  388. };
  389. var view = new View
  390. {
  391. Id = "view",
  392. Width = 2,
  393. Height = 20,
  394. Text = "01234567890123456789",
  395. TextDirection = TextDirection.TopBottom_LeftRight
  396. };
  397. view.Add (subView);
  398. var content = new View { Id = "content", Width = 20, Height = 20 };
  399. content.Add (view);
  400. var container = new View
  401. {
  402. Id = "container",
  403. X = 1,
  404. Y = 1,
  405. Width = 5,
  406. Height = 5
  407. };
  408. container.Add (content);
  409. Toplevel top = new ();
  410. top.Add (container);
  411. Application.Begin (top);
  412. Application.LayoutAndDraw ();
  413. TestHelpers.AssertDriverContentsWithFrameAre (
  414. """
  415. 0s
  416. 1u
  417. 2b
  418. 3V
  419. 4i
  420. """,
  421. _output
  422. );
  423. content.X = -1;
  424. Application.LayoutAndDraw ();
  425. TestHelpers.AssertDriverContentsWithFrameAre (
  426. """
  427. s
  428. u
  429. b
  430. V
  431. i
  432. """,
  433. _output
  434. );
  435. content.X = -2;
  436. Application.LayoutAndDraw ();
  437. TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
  438. content.X = 0;
  439. content.Y = -1;
  440. Application.LayoutAndDraw ();
  441. TestHelpers.AssertDriverContentsWithFrameAre (
  442. """
  443. 1u
  444. 2b
  445. 3V
  446. 4i
  447. 5e
  448. """,
  449. _output
  450. );
  451. content.Y = -6;
  452. Application.LayoutAndDraw ();
  453. TestHelpers.AssertDriverContentsWithFrameAre (
  454. """
  455. 6w
  456. 7
  457. 8
  458. 9
  459. 0
  460. """,
  461. _output
  462. );
  463. content.Y = -19;
  464. Application.LayoutAndDraw ();
  465. TestHelpers.AssertDriverContentsWithFrameAre (
  466. """
  467. 9
  468. """,
  469. _output
  470. );
  471. content.Y = -20;
  472. Application.LayoutAndDraw ();
  473. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  474. content.X = -2;
  475. content.Y = 0;
  476. Application.LayoutAndDraw ();
  477. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  478. top.Dispose ();
  479. }
  480. [Theory]
  481. [SetupFakeDriver]
  482. [InlineData ("𝔽𝕆𝕆𝔹𝔸R")]
  483. [InlineData ("a𐐀b")]
  484. public void DrawHotString_NonBmp (string expected)
  485. {
  486. var view = new View { Width = 10, Height = 1 };
  487. view.DrawHotString (expected, Attribute.Default, Attribute.Default);
  488. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  489. }
  490. // TODO: The tests below that use Label should use View instead.
  491. [Fact]
  492. [AutoInitShutdown]
  493. public void Non_Bmp_ConsoleWidth_ColumnWidth_Equal_Two ()
  494. {
  495. var us = "\U0001d539";
  496. var r = (Rune)0x1d539;
  497. Assert.Equal ("𝔹", us);
  498. Assert.Equal ("𝔹", r.ToString ());
  499. Assert.Equal (us, r.ToString ());
  500. Assert.Equal (1, us.GetColumns ());
  501. Assert.Equal (1, r.GetColumns ());
  502. var win = new Window { Title = us };
  503. var view = new Label { Text = r.ToString () };
  504. var tf = new TextField { Text = us, Y = 1, Width = 3 };
  505. win.Add (view, tf);
  506. Toplevel top = new ();
  507. top.Add (win);
  508. Application.Begin (top);
  509. ((FakeDriver)Application.Driver!).SetBufferSize (10, 4);
  510. var expected = """
  511. ┌┤𝔹├─────┐
  512. │𝔹 │
  513. │𝔹 │
  514. └────────┘
  515. """;
  516. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  517. TestHelpers.AssertDriverContentsAre (expected, _output);
  518. top.Dispose ();
  519. // This test has nothing to do with color - removing as it is not relevant and fragile
  520. }
  521. [Fact]
  522. [TestRespondersDisposed]
  523. public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
  524. {
  525. Application.Init (new FakeDriver ());
  526. Toplevel top = new ();
  527. var view = new View { X = -2, Text = "view" };
  528. top.Add (view);
  529. Application.Iteration += (s, a) =>
  530. {
  531. Assert.Equal (-2, view.X);
  532. Application.RequestStop ();
  533. };
  534. try
  535. {
  536. Application.Run (top);
  537. }
  538. catch (IndexOutOfRangeException ex)
  539. {
  540. // After the fix this exception will not be caught.
  541. Assert.IsType<IndexOutOfRangeException> (ex);
  542. }
  543. top.Dispose ();
  544. // Shutdown must be called to safely clean up Application if Init has been called
  545. Application.Shutdown ();
  546. }
  547. [Fact]
  548. [AutoInitShutdown]
  549. public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame ()
  550. {
  551. var label = new Label { Text = "At 0,0" };
  552. var view = new DerivedView
  553. {
  554. X = 2,
  555. Y = 2,
  556. Width = 30,
  557. Height = 2,
  558. Text = "A text with some long width\n and also with two lines."
  559. };
  560. Toplevel top = new ();
  561. top.Add (label, view);
  562. RunState runState = Application.Begin (top);
  563. Application.RunIteration (ref runState);
  564. TestHelpers.AssertDriverContentsWithFrameAre (
  565. @"
  566. At 0,0
  567. A text with some long width
  568. and also with two lines. "
  569. ,
  570. _output
  571. );
  572. view.Frame = new (3, 3, 10, 1);
  573. Assert.Equal (new (3, 3, 10, 1), view.Frame);
  574. Assert.Equal (new (0, 0, 10, 1), view.Viewport);
  575. Assert.Equal (new (0, 0, 10, 1), view._needsDrawRect);
  576. //Application.Refresh();
  577. top.Draw ();
  578. TestHelpers.AssertDriverContentsWithFrameAre (
  579. @"
  580. At 0,0
  581. A text wit",
  582. _output
  583. );
  584. Application.End (runState);
  585. top.Dispose ();
  586. }
  587. [Fact]
  588. [AutoInitShutdown]
  589. public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim ()
  590. {
  591. var label = new Label { Text = "At 0,0" };
  592. var view = new DerivedView
  593. {
  594. X = 2,
  595. Y = 2,
  596. Width = 30,
  597. Height = 2,
  598. Text = "A text with some long width\n and also with two lines."
  599. };
  600. Toplevel top = new ();
  601. top.Add (label, view);
  602. RunState runState = Application.Begin (top);
  603. top.Draw ();
  604. TestHelpers.AssertDriverContentsWithFrameAre (
  605. @"
  606. At 0,0
  607. A text with some long width
  608. and also with two lines. "
  609. ,
  610. _output
  611. );
  612. view.X = 3;
  613. view.Y = 3;
  614. view.Width = 10;
  615. view.Height = 1;
  616. Assert.Equal (new (3, 3, 10, 1), view.Frame);
  617. Assert.Equal (new (0, 0, 10, 1), view.Viewport);
  618. Assert.Equal (new (0, 0, 10, 1), view._needsDrawRect);
  619. View.SetClipToScreen ();
  620. top.Draw ();
  621. TestHelpers.AssertDriverContentsWithFrameAre (
  622. @"
  623. At 0,0
  624. A text wit"
  625. ,
  626. _output
  627. );
  628. Application.End (runState);
  629. top.Dispose ();
  630. }
  631. [Fact]
  632. [AutoInitShutdown]
  633. public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame ()
  634. {
  635. var label = new Label { Text = "At 0,0" };
  636. var view = new DerivedView
  637. {
  638. X = 2,
  639. Y = 2,
  640. Width = 30,
  641. Height = 2,
  642. Text = "A text with some long width\n and also with two lines."
  643. };
  644. Toplevel top = new ();
  645. top.Add (label, view);
  646. RunState runState = Application.Begin (top);
  647. Application.RunIteration (ref runState);
  648. TestHelpers.AssertDriverContentsWithFrameAre (
  649. @"
  650. At 0,0
  651. A text with some long width
  652. and also with two lines. "
  653. ,
  654. _output
  655. );
  656. view.Frame = new (1, 1, 10, 1);
  657. Assert.Equal (new (1, 1, 10, 1), view.Frame);
  658. Assert.Equal (new (0, 0, 10, 1), view.Viewport);
  659. Assert.Equal (new (0, 0, 10, 1), view._needsDrawRect);
  660. top.Draw ();
  661. TestHelpers.AssertDriverContentsWithFrameAre (
  662. @"
  663. At 0,0
  664. A text wit"
  665. ,
  666. _output
  667. );
  668. Application.End (runState);
  669. top.Dispose ();
  670. }
  671. [Fact]
  672. [AutoInitShutdown]
  673. public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim ()
  674. {
  675. var label = new Label { Text = "At 0,0" };
  676. var view = new DerivedView
  677. {
  678. X = 2,
  679. Y = 2,
  680. Width = 30,
  681. Height = 2,
  682. Text = "A text with some long width\n and also with two lines."
  683. };
  684. Toplevel top = new ();
  685. top.Add (label, view);
  686. RunState runState = Application.Begin (top);
  687. top.Draw ();
  688. TestHelpers.AssertDriverContentsWithFrameAre (
  689. @"
  690. At 0,0
  691. A text with some long width
  692. and also with two lines. "
  693. ,
  694. _output
  695. );
  696. view.X = 1;
  697. view.Y = 1;
  698. view.Width = 10;
  699. view.Height = 1;
  700. Assert.Equal (new (1, 1, 10, 1), view.Frame);
  701. Assert.Equal (new (0, 0, 10, 1), view.Viewport);
  702. Assert.Equal (new (0, 0, 10, 1), view._needsDrawRect);
  703. View.SetClipToScreen ();
  704. top.Draw ();
  705. TestHelpers.AssertDriverContentsWithFrameAre (
  706. @"
  707. At 0,0
  708. A text wit"
  709. ,
  710. _output
  711. );
  712. Application.End (runState);
  713. top.Dispose ();
  714. }
  715. public class DerivedView : View
  716. {
  717. public DerivedView () { CanFocus = true; }
  718. public bool IsKeyDown { get; set; }
  719. public bool IsKeyPress { get; set; }
  720. public bool IsKeyUp { get; set; }
  721. public override string Text { get; set; }
  722. protected override bool OnDrawingContent ()
  723. {
  724. var idx = 0;
  725. // BUGBUG: v2 - this should use Viewport, not Frame
  726. for (var r = 0; r < Frame.Height; r++)
  727. {
  728. for (var c = 0; c < Frame.Width; c++)
  729. {
  730. if (idx < Text.Length)
  731. {
  732. char rune = Text [idx];
  733. if (rune != '\n')
  734. {
  735. AddRune (c, r, (Rune)Text [idx]);
  736. }
  737. idx++;
  738. if (rune == '\n')
  739. {
  740. break;
  741. }
  742. }
  743. }
  744. }
  745. ClearNeedsDraw ();
  746. return true;
  747. }
  748. protected override bool OnKeyDown (Key keyEvent)
  749. {
  750. IsKeyDown = true;
  751. return true;
  752. }
  753. public override bool OnKeyUp (Key keyEvent)
  754. {
  755. IsKeyUp = true;
  756. return true;
  757. }
  758. protected override bool OnKeyDownNotHandled (Key keyEvent)
  759. {
  760. IsKeyPress = true;
  761. return true;
  762. }
  763. }
  764. }