WideGlyphs.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. // Add Editors
  21. AdornmentsEditor adornmentsEditor = new ()
  22. {
  23. BorderStyle = LineStyle.Single,
  24. X = Pos.AnchorEnd (),
  25. AutoSelectViewToEdit = true,
  26. AutoSelectAdornments = false,
  27. ShowViewIdentifier = true
  28. };
  29. adornmentsEditor.ExpanderButton.Accepting += (sender, args) =>
  30. {
  31. //adornmentsEditor.ExpanderButton.Collapsed = args.NewValue;
  32. };
  33. appWindow.Add (adornmentsEditor);
  34. ViewportSettingsEditor viewportSettingsEditor = new ()
  35. {
  36. BorderStyle = LineStyle.Single,
  37. Y = Pos.AnchorEnd (),
  38. X = Pos.AnchorEnd (),
  39. AutoSelectViewToEdit = true,
  40. };
  41. appWindow.Add (viewportSettingsEditor);
  42. // Build the array of codepoints once when subviews are laid out
  43. appWindow.SubViewsLaidOut += (s, _) =>
  44. {
  45. View? view = s as View;
  46. if (view is null)
  47. {
  48. return;
  49. }
  50. // Only rebuild if size changed or array is null
  51. if (_codepoints is null ||
  52. _codepoints.GetLength (0) != view.Viewport.Height ||
  53. _codepoints.GetLength (1) != view.Viewport.Width)
  54. {
  55. _codepoints = new Rune [view.Viewport.Height, view.Viewport.Width];
  56. for (int r = 0; r < view.Viewport.Height; r++)
  57. {
  58. for (int c = 0; c < view.Viewport.Width; c += 2)
  59. {
  60. _codepoints [r, c] = GetRandomWideCodepoint ();
  61. }
  62. }
  63. }
  64. };
  65. // Fill the window with the pre-built codepoints array
  66. // For detailed documentation on the draw code flow from Application.Run to this event,
  67. // see WideGlyphs.DrawFlow.md in this directory
  68. appWindow.DrawingContent += (s, e) =>
  69. {
  70. View? view = s as View;
  71. if (view is null || _codepoints is null)
  72. {
  73. return;
  74. }
  75. // Traverse the Viewport, using the pre-built array
  76. for (int r = 0; r < view.Viewport.Height && r < _codepoints.GetLength (0); r++)
  77. {
  78. for (int c = 0; c < view.Viewport.Width && c < _codepoints.GetLength (1); c += 2)
  79. {
  80. Rune codepoint = _codepoints [r, c];
  81. if (codepoint != default (Rune))
  82. {
  83. view.AddRune (c, r, codepoint);
  84. }
  85. }
  86. }
  87. e.DrawContext?.AddDrawnRectangle (view.Viewport);
  88. };
  89. Line verticalLineAtEven = new ()
  90. {
  91. X = 10,
  92. Orientation = Orientation.Vertical,
  93. Length = Dim.Fill ()
  94. };
  95. appWindow.Add (verticalLineAtEven);
  96. Line verticalLineAtOdd = new ()
  97. {
  98. X = 25,
  99. Orientation = Orientation.Vertical,
  100. Length = Dim.Fill ()
  101. };
  102. appWindow.Add (verticalLineAtOdd);
  103. View arrangeableViewAtEven = new ()
  104. {
  105. CanFocus = true,
  106. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
  107. X = 30,
  108. Y = 5,
  109. Width = 15,
  110. Height = 5,
  111. //BorderStyle = LineStyle.Dashed
  112. };
  113. // Proves it's not LineCanvas related
  114. arrangeableViewAtEven!.Border!.Thickness = new (1);
  115. arrangeableViewAtEven.Border.Add (new View () { Height = Dim.Auto (), Width = Dim.Auto (), Text = "Even" });
  116. appWindow.Add (arrangeableViewAtEven);
  117. View arrangeableViewAtOdd = new ()
  118. {
  119. CanFocus = true,
  120. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
  121. X = 31,
  122. Y = 11,
  123. Width = 15,
  124. Height = 5,
  125. BorderStyle = LineStyle.Dashed,
  126. };
  127. appWindow.Add (arrangeableViewAtOdd);
  128. var superView = new View
  129. {
  130. CanFocus = true,
  131. X = 30, // on an even column to start
  132. Y = Pos.Center (),
  133. Width = Dim.Auto (),
  134. Height = Dim.Auto (),
  135. BorderStyle = LineStyle.Single,
  136. Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
  137. };
  138. Rune codepoint = Glyphs.Apple;
  139. superView.DrawingContent += (s, e) =>
  140. {
  141. var view = s as View;
  142. for (var r = 0; r < view!.Viewport.Height; r++)
  143. {
  144. for (var c = 0; c < view.Viewport.Width; c += 2)
  145. {
  146. if (codepoint != default (Rune))
  147. {
  148. view.AddRune (c, r, codepoint);
  149. }
  150. }
  151. }
  152. e.DrawContext?.AddDrawnRectangle (view.Viewport);
  153. e.Cancel = true;
  154. };
  155. appWindow.Add (superView);
  156. var viewWithBorderAtX0 = new View
  157. {
  158. Text = "viewWithBorderAtX0",
  159. BorderStyle = LineStyle.Dashed,
  160. X = 0,
  161. Y = 1,
  162. Width = Dim.Auto (),
  163. Height = 3
  164. };
  165. var viewWithBorderAtX1 = new View
  166. {
  167. Text = "viewWithBorderAtX1",
  168. BorderStyle = LineStyle.Dashed,
  169. X = 1,
  170. Y = Pos.Bottom (viewWithBorderAtX0) + 1,
  171. Width = Dim.Auto (),
  172. Height = 3
  173. };
  174. var viewWithBorderAtX2 = new View
  175. {
  176. Text = "viewWithBorderAtX2",
  177. BorderStyle = LineStyle.Dashed,
  178. X = 2,
  179. Y = Pos.Bottom (viewWithBorderAtX1) + 1,
  180. Width = Dim.Auto (),
  181. Height = 3
  182. };
  183. superView.Add (viewWithBorderAtX0, viewWithBorderAtX1, viewWithBorderAtX2);
  184. // Run - Start the application.
  185. Application.Run (appWindow);
  186. appWindow.Dispose ();
  187. // Shutdown - Calling Application.Shutdown is required.
  188. Application.Shutdown ();
  189. }
  190. private Rune GetRandomWideCodepoint ()
  191. {
  192. Random random = new ();
  193. int codepoint = random.Next (0x4E00, 0x9FFF);
  194. return new (codepoint);
  195. }
  196. }