WideGlyphs.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #nullable enable
  2. using System.Text;
  3. namespace UICatalog.Scenarios;
  4. [ScenarioMetadata ("WideGlyphs", "Demonstrates wide glyphs with overlapped views & clipping")]
  5. [ScenarioCategory ("Unicode")]
  6. [ScenarioCategory ("Drawing")]
  7. public sealed class WideGlyphs : Scenario
  8. {
  9. private Rune [,]? _codepoints;
  10. public override void Main ()
  11. {
  12. // Init
  13. Application.Init ();
  14. // Setup - Create a top-level application window and configure it.
  15. Window appWindow = new ()
  16. {
  17. Title = GetQuitKeyAndName (),
  18. BorderStyle = LineStyle.None
  19. };
  20. // Build the array of codepoints once when subviews are laid out
  21. appWindow.SubViewsLaidOut += (s, _) =>
  22. {
  23. View? view = s as View;
  24. if (view is null)
  25. {
  26. return;
  27. }
  28. // Only rebuild if size changed or array is null
  29. if (_codepoints is null ||
  30. _codepoints.GetLength (0) != view.Viewport.Height ||
  31. _codepoints.GetLength (1) != view.Viewport.Width)
  32. {
  33. _codepoints = new Rune [view.Viewport.Height, view.Viewport.Width];
  34. for (int r = 0; r < view.Viewport.Height; r++)
  35. {
  36. for (int c = 0; c < view.Viewport.Width; c += 2)
  37. {
  38. _codepoints [r, c] = GetRandomWideCodepoint ();
  39. }
  40. }
  41. }
  42. };
  43. // Fill the window with the pre-built codepoints array
  44. // For detailed documentation on the draw code flow from Application.Run to this event,
  45. // see WideGlyphs.DrawFlow.md in this directory
  46. appWindow.DrawingContent += (s, _) =>
  47. {
  48. View? view = s as View;
  49. if (view is null || _codepoints is null)
  50. {
  51. return;
  52. }
  53. // Traverse the Viewport, using the pre-built array
  54. for (int r = 0; r < view.Viewport.Height && r < _codepoints.GetLength (0); r++)
  55. {
  56. for (int c = 0; c < view.Viewport.Width && c < _codepoints.GetLength (1); c += 2)
  57. {
  58. Rune codepoint = _codepoints [r, c];
  59. if (codepoint != default (Rune))
  60. {
  61. view.AddRune (c, r, codepoint);
  62. }
  63. }
  64. }
  65. };
  66. Line verticalLineAtEven = new ()
  67. {
  68. X = 10,
  69. Orientation = Orientation.Vertical,
  70. Length = Dim.Fill ()
  71. };
  72. appWindow.Add (verticalLineAtEven);
  73. Line verticalLineAtOdd = new ()
  74. {
  75. X = 25,
  76. Orientation = Orientation.Vertical,
  77. Length = Dim.Fill ()
  78. };
  79. appWindow.Add (verticalLineAtOdd);
  80. View arrangeableViewAtEven = new ()
  81. {
  82. CanFocus = true,
  83. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
  84. X = 30,
  85. Y = 5,
  86. Width = 15,
  87. Height = 5,
  88. //BorderStyle = LineStyle.Dashed,
  89. };
  90. // Proves it's not LineCanvas related
  91. arrangeableViewAtEven!.Border!.Thickness = new (1);
  92. arrangeableViewAtEven.Border.Add(new View () { Height = Dim.Auto(), Width = Dim.Auto(), Text = "Even" });
  93. appWindow.Add (arrangeableViewAtEven);
  94. View arrangeableViewAtOdd = new ()
  95. {
  96. CanFocus = true,
  97. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
  98. X = 31,
  99. Y = 11,
  100. Width = 15,
  101. Height = 5,
  102. BorderStyle = LineStyle.Dashed,
  103. };
  104. appWindow.Add (arrangeableViewAtOdd);
  105. var superView = new View
  106. {
  107. CanFocus = true,
  108. X = 30, // on an even column to start
  109. Y = Pos.Center (),
  110. Width = Dim.Auto () + 4,
  111. Height = Dim.Auto () + 1,
  112. BorderStyle = LineStyle.Single,
  113. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
  114. };
  115. Rune codepoint = Glyphs.Apple;
  116. superView.DrawingContent += (s, e) =>
  117. {
  118. var view = s as View;
  119. for (var r = 0; r < view!.Viewport.Height; r++)
  120. {
  121. for (var c = 0; c < view.Viewport.Width; c += 2)
  122. {
  123. if (codepoint != default (Rune))
  124. {
  125. view.AddRune (c, r, codepoint);
  126. }
  127. }
  128. }
  129. e.DrawContext?.AddDrawnRectangle (view.Viewport);
  130. e.Cancel = true;
  131. };
  132. appWindow.Add (superView);
  133. var viewWithBorderAtX0 = new View
  134. {
  135. Text = "viewWithBorderAtX0",
  136. BorderStyle = LineStyle.Dashed,
  137. X = 0,
  138. Y = 1,
  139. Width = Dim.Auto (),
  140. Height = 3
  141. };
  142. var viewWithBorderAtX1 = new View
  143. {
  144. Text = "viewWithBorderAtX1",
  145. BorderStyle = LineStyle.Dashed,
  146. X = 1,
  147. Y = Pos.Bottom (viewWithBorderAtX0) + 1,
  148. Width = Dim.Auto (),
  149. Height = 3
  150. };
  151. var viewWithBorderAtX2 = new View
  152. {
  153. Text = "viewWithBorderAtX2",
  154. BorderStyle = LineStyle.Dashed,
  155. X = 2,
  156. Y = Pos.Bottom (viewWithBorderAtX1) + 1,
  157. Width = Dim.Auto (),
  158. Height = 3
  159. };
  160. superView.Add (viewWithBorderAtX0, viewWithBorderAtX1, viewWithBorderAtX2);
  161. // Run - Start the application.
  162. Application.Run (appWindow);
  163. appWindow.Dispose ();
  164. // Shutdown - Calling Application.Shutdown is required.
  165. Application.Shutdown ();
  166. }
  167. private Rune GetRandomWideCodepoint ()
  168. {
  169. Random random = new ();
  170. int codepoint = random.Next (0x4E00, 0x9FFF);
  171. return new (codepoint);
  172. }
  173. }