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. Clicked = () => Application.RequestStop (),
  31. };
  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. // BUGBUG: For some reason these buttons don't move to correct locations initially.
  67. // This was the only way I find to resolves this with the View prev variable.
  68. //Top.Ready += () => Top.Redraw (Top.Bounds);
  69. Button button;
  70. Win.Add (button = new Button ("A super long _Button that will probably expose a bug in clipping or wrapping of text. Will it?") {
  71. X = 2,
  72. Y = Pos.Bottom (colorButtonsLabel) + 1,
  73. });
  74. DoMessage (button, button.Text);
  75. // Note the 'N' in 'Newline' will be the hotkey
  76. Win.Add (button = new Button ("a Newline\nin the button") {
  77. X = 2,
  78. Y = Pos.Bottom (button) + 1,
  79. Clicked = () => MessageBox.Query ("Message", "Question?", "Yes", "No")
  80. });
  81. var textChanger = new Button ("Te_xt Changer") {
  82. X = 2,
  83. Y = Pos.Bottom (button) + 1,
  84. };
  85. Win.Add (textChanger);
  86. textChanger.Clicked = () => textChanger.Text += "!";
  87. Win.Add (button = new Button ("Lets see if this will move as \"Text Changer\" grows") {
  88. X = Pos.Right (textChanger) + 2,
  89. Y = Pos.Y (textChanger),
  90. });
  91. var removeButton = new Button ("Remove this button") {
  92. X = 2,
  93. Y = Pos.Bottom (button) + 1,
  94. ColorScheme = Colors.Error
  95. };
  96. Win.Add (removeButton);
  97. // This in intresting test case because `moveBtn` and below are laid out relative to this one!
  98. removeButton.Clicked = () => Win.Remove (removeButton);
  99. var computedFrame = new FrameView ("Computed Layout") {
  100. X = 0,
  101. Y = Pos.Bottom (removeButton) + 1,
  102. Width = Dim.Percent (50),
  103. Height = 5
  104. };
  105. Win.Add (computedFrame);
  106. // Demonstrates how changing the View.Frame property can move Views
  107. var moveBtn = new Button ("Move This \u263b Button _via Pos") {
  108. X = 0,
  109. Y = Pos.Center () - 1,
  110. Width = 30,
  111. ColorScheme = Colors.Error,
  112. };
  113. moveBtn.Clicked = () => {
  114. moveBtn.X = moveBtn.Frame.X + 5;
  115. // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
  116. //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
  117. };
  118. computedFrame.Add (moveBtn);
  119. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  120. var sizeBtn = new Button ("Size This \u263a Button _via Pos") {
  121. X = 0,
  122. Y = Pos.Center () + 1,
  123. Width = 30,
  124. ColorScheme = Colors.Error,
  125. };
  126. sizeBtn.Clicked = () => {
  127. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  128. //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
  129. };
  130. computedFrame.Add (sizeBtn);
  131. var absoluteFrame = new FrameView ("Absolute Layout") {
  132. X = Pos.Right (computedFrame),
  133. Y = Pos.Bottom (removeButton) + 1,
  134. Width = Dim.Fill (),
  135. Height = 5
  136. };
  137. Win.Add (absoluteFrame);
  138. // Demonstrates how changing the View.Frame property can move Views
  139. var moveBtnA = new Button (0, 0, "Move This Button via Frame") {
  140. ColorScheme = Colors.Error,
  141. };
  142. moveBtnA.Clicked = () => {
  143. moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
  144. };
  145. absoluteFrame.Add (moveBtnA);
  146. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  147. var sizeBtnA = new Button (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
  148. ColorScheme = Colors.Error,
  149. };
  150. sizeBtnA.Clicked = () => {
  151. sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
  152. };
  153. absoluteFrame.Add (sizeBtnA);
  154. var label = new Label ("Text Alignment (changes the four buttons above): ") {
  155. X = 2,
  156. Y = Pos.Bottom (computedFrame) + 1,
  157. };
  158. Win.Add (label);
  159. var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
  160. X = 4,
  161. Y = Pos.Bottom (label) + 1,
  162. SelectedItem = 2,
  163. };
  164. Win.Add (radioGroup);
  165. // Demo changing hotkey
  166. ustring MoveHotkey (ustring txt)
  167. {
  168. // Remove the '_'
  169. var i = txt.IndexOf ('_');
  170. ustring start = "";
  171. if (i > -1)
  172. start = txt [0, i];
  173. txt = start + txt [i + 1, txt.RuneCount];
  174. // Move over one or go to start
  175. i++;
  176. if (i >= txt.RuneCount) {
  177. i = 0;
  178. }
  179. // Slip in the '_'
  180. start = txt [0, i];
  181. txt = start + ustring.Make ('_') + txt [i, txt.RuneCount];
  182. return txt;
  183. }
  184. var mhkb = "Click to Change th_is Button's Hotkey";
  185. var moveHotKeyBtn = new Button (mhkb) {
  186. X = 2,
  187. Y = Pos.Bottom (radioGroup) + 1,
  188. Width = mhkb.Length + 10,
  189. ColorScheme = Colors.TopLevel,
  190. };
  191. moveHotKeyBtn.Clicked = () => {
  192. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  193. };
  194. Win.Add (moveHotKeyBtn);
  195. var muhkb = ustring.Make(" ~  s  gui.cs   master ↑10 = Сохранить");
  196. var moveUnicodeHotKeyBtn = new Button (muhkb) {
  197. X = Pos.Left (absoluteFrame) + 1,
  198. Y = Pos.Bottom (radioGroup) + 1,
  199. Width = muhkb.RuneCount + 30,
  200. ColorScheme = Colors.TopLevel,
  201. };
  202. moveUnicodeHotKeyBtn.Clicked = () => {
  203. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  204. };
  205. Win.Add (moveUnicodeHotKeyBtn);
  206. radioGroup.SelectedItemChanged += (args) => {
  207. switch (args.SelectedItem) {
  208. case 0:
  209. moveBtn.TextAlignment = TextAlignment.Left;
  210. sizeBtn.TextAlignment = TextAlignment.Left;
  211. moveBtnA.TextAlignment = TextAlignment.Left;
  212. sizeBtnA.TextAlignment = TextAlignment.Left;
  213. moveHotKeyBtn.TextAlignment = TextAlignment.Left;
  214. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
  215. break;
  216. case 1:
  217. moveBtn.TextAlignment = TextAlignment.Right;
  218. sizeBtn.TextAlignment = TextAlignment.Right;
  219. moveBtnA.TextAlignment = TextAlignment.Right;
  220. sizeBtnA.TextAlignment = TextAlignment.Right;
  221. moveHotKeyBtn.TextAlignment = TextAlignment.Right;
  222. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
  223. break;
  224. case 2:
  225. moveBtn.TextAlignment = TextAlignment.Centered;
  226. sizeBtn.TextAlignment = TextAlignment.Centered;
  227. moveBtnA.TextAlignment = TextAlignment.Centered;
  228. sizeBtnA.TextAlignment = TextAlignment.Centered;
  229. moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
  230. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
  231. break;
  232. case 3:
  233. moveBtn.TextAlignment = TextAlignment.Justified;
  234. sizeBtn.TextAlignment = TextAlignment.Justified;
  235. moveBtnA.TextAlignment = TextAlignment.Justified;
  236. sizeBtnA.TextAlignment = TextAlignment.Justified;
  237. moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
  238. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
  239. break;
  240. }
  241. };
  242. }
  243. }
  244. }