Buttons.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. using NStack;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Terminal.Gui;
  7. namespace UICatalog {
  8. [ScenarioMetadata (Name: "Buttons", Description: "Demonstrates all sorts of Buttons")]
  9. [ScenarioCategory ("Controls")]
  10. [ScenarioCategory ("Layout")]
  11. class Buttons : Scenario {
  12. public override void Setup ()
  13. {
  14. // Add a label & text field so we can demo IsDefault
  15. var editLabel = new Label ("TextField (to demo IsDefault):") {
  16. X = 0,
  17. Y = 0,
  18. };
  19. Win.Add (editLabel);
  20. // Add a TextField using Absolute layout.
  21. var edit = new TextField (31, 0, 15, "");
  22. Win.Add (edit);
  23. // This is the default button (IsDefault = true); if user presses ENTER in the TextField
  24. // the scenario will quit
  25. var defaultButton = new Button ("_Quit") {
  26. X = Pos.Center (),
  27. //TODO: Change to use Pos.AnchorEnd()
  28. Y = Pos.Bottom (Win) - 3,
  29. IsDefault = true,
  30. };
  31. defaultButton.Clicked += () => Application.RequestStop ();
  32. Win.Add (defaultButton);
  33. var swapButton = new Button (50, 0, "Swap Default (Absolute Layout)");
  34. swapButton.Clicked += () => {
  35. defaultButton.IsDefault = !defaultButton.IsDefault;
  36. swapButton.IsDefault = !swapButton.IsDefault;
  37. };
  38. Win.Add (swapButton);
  39. static void DoMessage (Button button, ustring txt)
  40. {
  41. button.Clicked += () => {
  42. var btnText = button.Text.ToString ();
  43. MessageBox.Query ("Message", $"Did you click {txt}?", "Yes", "No");
  44. };
  45. }
  46. var colorButtonsLabel = new Label ("Color Buttons:") {
  47. X = 0,
  48. Y = Pos.Bottom (editLabel) + 1,
  49. };
  50. Win.Add (colorButtonsLabel);
  51. //View prev = colorButtonsLabel;
  52. //With this method there is no need to call Top.Ready += () => Top.Redraw (Top.Bounds);
  53. var x = Pos.Right (colorButtonsLabel) + 2;
  54. foreach (var colorScheme in Colors.ColorSchemes) {
  55. var colorButton = new Button ($"{colorScheme.Key}") {
  56. ColorScheme = colorScheme.Value,
  57. //X = Pos.Right (prev) + 2,
  58. X = x,
  59. Y = Pos.Y (colorButtonsLabel),
  60. };
  61. DoMessage (colorButton, colorButton.Text);
  62. Win.Add (colorButton);
  63. //prev = colorButton;
  64. x += colorButton.Frame.Width + 2;
  65. }
  66. Button button;
  67. Win.Add (button = new Button ("A super long _Button that will probably expose a bug in clipping or wrapping of text. Will it?") {
  68. X = 2,
  69. Y = Pos.Bottom (colorButtonsLabel) + 1,
  70. });
  71. DoMessage (button, button.Text);
  72. // Note the 'N' in 'Newline' will be the hotkey
  73. Win.Add (button = new Button ("a Newline\nin the button") {
  74. X = 2,
  75. Y = Pos.Bottom (button) + 1,
  76. });
  77. button.Clicked += () => MessageBox.Query ("Message", "Question?", "Yes", "No");
  78. var textChanger = new Button ("Te_xt Changer") {
  79. X = 2,
  80. Y = Pos.Bottom (button) + 1,
  81. };
  82. Win.Add (textChanger);
  83. textChanger.Clicked += () => textChanger.Text += "!";
  84. Win.Add (button = new Button ("Lets see if this will move as \"Text Changer\" grows") {
  85. X = Pos.Right (textChanger) + 2,
  86. Y = Pos.Y (textChanger),
  87. });
  88. var removeButton = new Button ("Remove this button") {
  89. X = 2,
  90. Y = Pos.Bottom (button) + 1,
  91. ColorScheme = Colors.Error
  92. };
  93. Win.Add (removeButton);
  94. // This in intresting test case because `moveBtn` and below are laid out relative to this one!
  95. removeButton.Clicked += () => Win.Remove (removeButton);
  96. var computedFrame = new FrameView ("Computed Layout") {
  97. X = 0,
  98. Y = Pos.Bottom (removeButton) + 1,
  99. Width = Dim.Percent (50),
  100. Height = 5
  101. };
  102. Win.Add (computedFrame);
  103. // Demonstrates how changing the View.Frame property can move Views
  104. var moveBtn = new Button ("Move This \u263b Button _via Pos") {
  105. X = 0,
  106. Y = Pos.Center () - 1,
  107. Width = 30,
  108. ColorScheme = Colors.Error,
  109. };
  110. moveBtn.Clicked += () => {
  111. moveBtn.X = moveBtn.Frame.X + 5;
  112. // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
  113. //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
  114. };
  115. computedFrame.Add (moveBtn);
  116. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  117. var sizeBtn = new Button ("Size This \u263a Button _via Pos") {
  118. X = 0,
  119. Y = Pos.Center () + 1,
  120. Width = 30,
  121. ColorScheme = Colors.Error,
  122. };
  123. sizeBtn.Clicked += () => {
  124. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  125. //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
  126. };
  127. computedFrame.Add (sizeBtn);
  128. var absoluteFrame = new FrameView ("Absolute Layout") {
  129. X = Pos.Right (computedFrame),
  130. Y = Pos.Bottom (removeButton) + 1,
  131. Width = Dim.Fill (),
  132. Height = 5
  133. };
  134. Win.Add (absoluteFrame);
  135. // Demonstrates how changing the View.Frame property can move Views
  136. var moveBtnA = new Button (0, 0, "Move This Button via Frame") {
  137. ColorScheme = Colors.Error,
  138. };
  139. moveBtnA.Clicked += () => {
  140. moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
  141. };
  142. absoluteFrame.Add (moveBtnA);
  143. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  144. var sizeBtnA = new Button (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
  145. ColorScheme = Colors.Error,
  146. };
  147. sizeBtnA.Clicked += () => {
  148. sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
  149. };
  150. absoluteFrame.Add (sizeBtnA);
  151. var label = new Label ("Text Alignment (changes the four buttons above): ") {
  152. X = 2,
  153. Y = Pos.Bottom (computedFrame) + 1,
  154. };
  155. Win.Add (label);
  156. var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
  157. X = 4,
  158. Y = Pos.Bottom (label) + 1,
  159. SelectedItem = 2,
  160. };
  161. Win.Add (radioGroup);
  162. // Demo changing hotkey
  163. ustring MoveHotkey (ustring txt)
  164. {
  165. // Remove the '_'
  166. var runes = txt.ToRuneList ();
  167. var i = runes.IndexOf ('_');
  168. ustring start = "";
  169. if (i > -1) {
  170. start = ustring.Make (runes.GetRange (0, i));
  171. }
  172. txt = start + ustring.Make (runes.GetRange (i + 1, runes.Count - (i + 1)));
  173. runes = txt.ToRuneList ();
  174. // Move over one or go to start
  175. i++;
  176. if (i >= runes.Count) {
  177. i = 0;
  178. }
  179. // Slip in the '_'
  180. start = ustring.Make (runes.GetRange (0, i));
  181. return start + ustring.Make ('_') + ustring.Make (runes.GetRange (i, runes.Count - i));
  182. }
  183. var mhkb = "Click to Change th_is Button's Hotkey";
  184. var moveHotKeyBtn = new Button (mhkb) {
  185. X = 2,
  186. Y = Pos.Bottom (radioGroup) + 1,
  187. Width = Dim.Width (computedFrame) - 2,
  188. ColorScheme = Colors.TopLevel,
  189. };
  190. moveHotKeyBtn.Clicked += () => {
  191. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  192. };
  193. Win.Add (moveHotKeyBtn);
  194. var muhkb = ustring.Make (" ~  s  gui.cs   master ↑10 = Сохранить");
  195. var moveUnicodeHotKeyBtn = new Button (muhkb) {
  196. X = Pos.Left (absoluteFrame) + 1,
  197. Y = Pos.Bottom (radioGroup) + 1,
  198. Width = Dim.Width (absoluteFrame) - 2, // BUGBUG: Not always the width isn't calculated correctly.
  199. ColorScheme = Colors.TopLevel,
  200. };
  201. moveUnicodeHotKeyBtn.Clicked += () => {
  202. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  203. };
  204. Win.Add (moveUnicodeHotKeyBtn);
  205. radioGroup.SelectedItemChanged += (args) => {
  206. switch (args.SelectedItem) {
  207. case 0:
  208. moveBtn.TextAlignment = TextAlignment.Left;
  209. sizeBtn.TextAlignment = TextAlignment.Left;
  210. moveBtnA.TextAlignment = TextAlignment.Left;
  211. sizeBtnA.TextAlignment = TextAlignment.Left;
  212. moveHotKeyBtn.TextAlignment = TextAlignment.Left;
  213. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
  214. break;
  215. case 1:
  216. moveBtn.TextAlignment = TextAlignment.Right;
  217. sizeBtn.TextAlignment = TextAlignment.Right;
  218. moveBtnA.TextAlignment = TextAlignment.Right;
  219. sizeBtnA.TextAlignment = TextAlignment.Right;
  220. moveHotKeyBtn.TextAlignment = TextAlignment.Right;
  221. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
  222. break;
  223. case 2:
  224. moveBtn.TextAlignment = TextAlignment.Centered;
  225. sizeBtn.TextAlignment = TextAlignment.Centered;
  226. moveBtnA.TextAlignment = TextAlignment.Centered;
  227. sizeBtnA.TextAlignment = TextAlignment.Centered;
  228. moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
  229. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
  230. break;
  231. case 3:
  232. moveBtn.TextAlignment = TextAlignment.Justified;
  233. sizeBtn.TextAlignment = TextAlignment.Justified;
  234. moveBtnA.TextAlignment = TextAlignment.Justified;
  235. sizeBtnA.TextAlignment = TextAlignment.Justified;
  236. moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
  237. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
  238. break;
  239. }
  240. };
  241. }
  242. }
  243. }