TextStyles.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #nullable enable
  2. using Terminal.Gui;
  3. namespace UICatalog.Scenarios;
  4. [ScenarioMetadata ("Text Styles", "Shows Attribute.TextStyles including bold, italic, etc...")]
  5. [ScenarioCategory ("Text and Formatting")]
  6. [ScenarioCategory ("Colors")]
  7. public sealed class TestStyles : Scenario
  8. {
  9. private CheckBox? _drawDirectly;
  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. Id = "appWindow",
  18. Title = GetQuitKeyAndName ()
  19. };
  20. //appWindow.ContentSizeTracksViewport = false;
  21. appWindow.VerticalScrollBar.AutoShow = true;
  22. appWindow.HorizontalScrollBar.AutoShow = true;
  23. appWindow.SubViewsLaidOut += (sender, _) =>
  24. {
  25. if (sender is View sendingView)
  26. {
  27. sendingView.SetContentSize (new Size(sendingView.GetContentSize().Width, sendingView.GetHeightRequiredForSubViews()));
  28. }
  29. };
  30. appWindow.DrawingContent += OnAppWindowOnDrawingContent;
  31. appWindow.DrawingSubViews += OnAppWindowOnDrawingSubviews;
  32. _drawDirectly = new ()
  33. {
  34. Title = "_Draw styled text directly using DrawingContent vs. Buttons",
  35. CheckedState = CheckState.UnChecked
  36. };
  37. appWindow.Add (_drawDirectly);
  38. AddButtons (appWindow);
  39. // Run - Start the application.
  40. Application.Run (appWindow);
  41. appWindow.Dispose ();
  42. // Shutdown - Calling Application.Shutdown is required.
  43. Application.Shutdown ();
  44. }
  45. private void AddButtons (Window appWindow)
  46. {
  47. var y = 1;
  48. TextStyle [] allStyles = Enum.GetValues (typeof (TextStyle))
  49. .Cast<TextStyle> ()
  50. .Where (style => style != TextStyle.None)
  51. .ToArray ();
  52. // Add individual flags as labels
  53. foreach (TextStyle style in allStyles)
  54. {
  55. y++;
  56. var button = new Button
  57. {
  58. X = 0,
  59. Y = y,
  60. Title = $"{Enum.GetName (typeof (TextStyle), style)}",
  61. Visible = _drawDirectly!.CheckedState != CheckState.Checked
  62. };
  63. button.GettingAttributeForRole += (sender, args) =>
  64. {
  65. if (sender is not Button buttonSender)
  66. {
  67. return;
  68. }
  69. args.NewValue = args.NewValue with { Style = style };
  70. args.Cancel = true;
  71. };
  72. appWindow.Add (button);
  73. }
  74. // Add a blank line
  75. y += 1;
  76. // Generate all combinations of TextStyle (excluding individual flags)
  77. int totalCombinations = 1 << allStyles.Length; // 2^n combinations
  78. for (var i = 1; i < totalCombinations; i++) // Start from 1 to skip "None"
  79. {
  80. var combination = (TextStyle)0;
  81. List<string> styleNames = [];
  82. for (var bit = 0; bit < allStyles.Length; bit++)
  83. {
  84. if ((i & (1 << bit)) != 0)
  85. {
  86. combination |= allStyles [bit];
  87. styleNames.Add (Enum.GetName (typeof (TextStyle), allStyles [bit])!);
  88. }
  89. }
  90. // Skip individual flags
  91. if (styleNames.Count == 1)
  92. {
  93. continue;
  94. }
  95. y++;
  96. var button = new Button
  97. {
  98. X = 0,
  99. Y = y,
  100. Text = $"[{string.Join (" | ", styleNames)}]",
  101. Visible = _drawDirectly!.CheckedState != CheckState.Checked
  102. };
  103. button.GettingAttributeForRole += (_, args) =>
  104. {
  105. args.NewValue = args.NewValue with { Style = combination };
  106. args.Cancel = true;
  107. };
  108. appWindow.Add (button);
  109. }
  110. }
  111. private void OnAppWindowOnDrawingSubviews (object? sender, DrawEventArgs e)
  112. {
  113. if (sender is not View sendingVioew)
  114. {
  115. return;
  116. }
  117. foreach (Button view in sendingVioew.SubViews.OfType<Button> ())
  118. {
  119. view.Visible = _drawDirectly!.CheckedState != CheckState.Checked;
  120. }
  121. e.Cancel = false;
  122. }
  123. private void OnAppWindowOnDrawingContent (object? sender, DrawEventArgs args)
  124. {
  125. if (sender is View { } sendingView && _drawDirectly!.CheckedState == CheckState.Checked)
  126. {
  127. int y = 2 - args.NewViewport.Y; // Start drawing below the checkbox
  128. TextStyle [] allStyles = Enum.GetValues (typeof (TextStyle))
  129. .Cast<TextStyle> ()
  130. .Where (style => style != TextStyle.None)
  131. .ToArray ();
  132. // Draw individual flags, one per line
  133. foreach (TextStyle style in allStyles)
  134. {
  135. string text = Enum.GetName (typeof (TextStyle), style)!;
  136. sendingView.Move (0, y);
  137. var attr = new Attribute (sendingView.GetAttributeForRole (VisualRole.Normal))
  138. {
  139. Style = style
  140. };
  141. sendingView.SetAttribute (attr);
  142. sendingView.AddStr (text);
  143. y++; // Move to the next line
  144. }
  145. // Add a blank line
  146. y++;
  147. // Generate all combinations of TextStyle (excluding individual flags)
  148. int totalCombinations = 1 << allStyles.Length; // 2^n combinations
  149. for (var i = 1; i < totalCombinations; i++) // Start from 1 to skip "None"
  150. {
  151. var combination = (TextStyle)0;
  152. List<string> styleNames = [];
  153. for (var bit = 0; bit < allStyles.Length; bit++)
  154. {
  155. if ((i & (1 << bit)) != 0)
  156. {
  157. combination |= allStyles [bit];
  158. styleNames.Add (Enum.GetName (typeof (TextStyle), allStyles [bit])!);
  159. }
  160. }
  161. // Skip individual flags
  162. if (styleNames.Count == 1)
  163. {
  164. continue;
  165. }
  166. var text = $"[{string.Join (" | ", styleNames)}]";
  167. sendingView.Move (00, y);
  168. var attr = new Attribute (sendingView.GetAttributeForRole (VisualRole.Normal))
  169. {
  170. Style = combination
  171. };
  172. sendingView.SetAttribute (attr);
  173. sendingView.AddStr (text);
  174. y++; // Move to the next line
  175. }
  176. args.Cancel = true;
  177. }
  178. }
  179. }