Buttons.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using System.Text;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Terminal.Gui;
  7. namespace UICatalog.Scenarios {
  8. [ScenarioMetadata (Name: "Buttons", Description: "Demonstrates all sorts of Buttons.")]
  9. [ScenarioCategory ("Controls")]
  10. [ScenarioCategory ("Layout")]
  11. public 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 += (s,e) => Application.RequestStop ();
  32. Win.Add (defaultButton);
  33. var swapButton = new Button (50, 0, "Swap Default (Absolute Layout)");
  34. swapButton.Clicked += (s,e) => {
  35. defaultButton.IsDefault = !defaultButton.IsDefault;
  36. swapButton.IsDefault = !swapButton.IsDefault;
  37. };
  38. Win.Add (swapButton);
  39. static void DoMessage (Button button, string txt)
  40. {
  41. button.Clicked += (s,e) => {
  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 Application.TopReady += () => Application.TopRedraw (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 += (s,e) => 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 += (s,e) => 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 interesting test case because `moveBtn` and below are laid out relative to this one!
  95. removeButton.Clicked += (s,e) => {
  96. // Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
  97. //Win.Remove (removeButton);
  98. removeButton.Visible = false;
  99. };
  100. var computedFrame = new FrameView ("Computed Layout") {
  101. X = 0,
  102. Y = Pos.Bottom (removeButton) + 1,
  103. Width = Dim.Percent (50),
  104. Height = 5
  105. };
  106. Win.Add (computedFrame);
  107. // Demonstrates how changing the View.Frame property can move Views
  108. var moveBtn = new Button ("Move This \u263b Button _via Pos") {
  109. X = 0,
  110. Y = Pos.Center () - 1,
  111. Width = 30,
  112. ColorScheme = Colors.Error,
  113. };
  114. moveBtn.Clicked += (s,e) => {
  115. moveBtn.X = moveBtn.Frame.X + 5;
  116. // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
  117. //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
  118. };
  119. computedFrame.Add (moveBtn);
  120. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  121. var sizeBtn = new Button ("Size This \u263a Button _via Pos") {
  122. X = 0,
  123. Y = Pos.Center () + 1,
  124. Width = 30,
  125. ColorScheme = Colors.Error,
  126. };
  127. sizeBtn.Clicked += (s,e) => {
  128. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  129. //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
  130. };
  131. computedFrame.Add (sizeBtn);
  132. var absoluteFrame = new FrameView ("Absolute Layout") {
  133. X = Pos.Right (computedFrame),
  134. Y = Pos.Bottom (removeButton) + 1,
  135. Width = Dim.Fill (),
  136. Height = 5
  137. };
  138. Win.Add (absoluteFrame);
  139. // Demonstrates how changing the View.Frame property can move Views
  140. var moveBtnA = new Button (0, 0, "Move This Button via Frame") {
  141. ColorScheme = Colors.Error,
  142. };
  143. moveBtnA.Clicked += (s,e) => {
  144. moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
  145. };
  146. absoluteFrame.Add (moveBtnA);
  147. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  148. var sizeBtnA = new Button (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
  149. ColorScheme = Colors.Error,
  150. };
  151. sizeBtnA.Clicked += (s,e) => {
  152. sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
  153. };
  154. absoluteFrame.Add (sizeBtnA);
  155. var label = new Label ("Text Alignment (changes the four buttons above): ") {
  156. X = 2,
  157. Y = Pos.Bottom (computedFrame) + 1,
  158. };
  159. Win.Add (label);
  160. var radioGroup = new RadioGroup (new string [] { "Left", "Right", "Centered", "Justified" }) {
  161. X = 4,
  162. Y = Pos.Bottom (label) + 1,
  163. SelectedItem = 2,
  164. };
  165. Win.Add (radioGroup);
  166. // Demo changing hotkey
  167. string MoveHotkey (string txt)
  168. {
  169. // Remove the '_'
  170. var runes = txt.ToRuneList ();
  171. var i = runes.IndexOf ((Rune)'_');
  172. string start = "";
  173. if (i > -1) {
  174. start = StringExtensions.ToString (runes.GetRange (0, i));
  175. }
  176. txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1)));
  177. runes = txt.ToRuneList ();
  178. // Move over one or go to start
  179. i++;
  180. if (i >= runes.Count) {
  181. i = 0;
  182. }
  183. // Slip in the '_'
  184. start = StringExtensions.ToString (runes.GetRange (0, i));
  185. return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i));
  186. }
  187. var mhkb = "Click to Change th_is Button's Hotkey";
  188. var moveHotKeyBtn = new Button (mhkb) {
  189. X = 2,
  190. Y = Pos.Bottom (radioGroup) + 1,
  191. Width = Dim.Width (computedFrame) - 2,
  192. ColorScheme = Colors.TopLevel,
  193. };
  194. moveHotKeyBtn.Clicked += (s,e) => {
  195. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  196. };
  197. Win.Add (moveHotKeyBtn);
  198. var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
  199. var moveUnicodeHotKeyBtn = new Button (muhkb) {
  200. X = Pos.Left (absoluteFrame) + 1,
  201. Y = Pos.Bottom (radioGroup) + 1,
  202. Width = Dim.Width (absoluteFrame) - 2, // BUGBUG: Not always the width isn't calculated correctly.
  203. ColorScheme = Colors.TopLevel,
  204. };
  205. moveUnicodeHotKeyBtn.Clicked += (s,e) => {
  206. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  207. };
  208. Win.Add (moveUnicodeHotKeyBtn);
  209. radioGroup.SelectedItemChanged += (s, args) => {
  210. switch (args.SelectedItem) {
  211. case 0:
  212. moveBtn.TextAlignment = TextAlignment.Left;
  213. sizeBtn.TextAlignment = TextAlignment.Left;
  214. moveBtnA.TextAlignment = TextAlignment.Left;
  215. sizeBtnA.TextAlignment = TextAlignment.Left;
  216. moveHotKeyBtn.TextAlignment = TextAlignment.Left;
  217. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
  218. break;
  219. case 1:
  220. moveBtn.TextAlignment = TextAlignment.Right;
  221. sizeBtn.TextAlignment = TextAlignment.Right;
  222. moveBtnA.TextAlignment = TextAlignment.Right;
  223. sizeBtnA.TextAlignment = TextAlignment.Right;
  224. moveHotKeyBtn.TextAlignment = TextAlignment.Right;
  225. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
  226. break;
  227. case 2:
  228. moveBtn.TextAlignment = TextAlignment.Centered;
  229. sizeBtn.TextAlignment = TextAlignment.Centered;
  230. moveBtnA.TextAlignment = TextAlignment.Centered;
  231. sizeBtnA.TextAlignment = TextAlignment.Centered;
  232. moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
  233. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
  234. break;
  235. case 3:
  236. moveBtn.TextAlignment = TextAlignment.Justified;
  237. sizeBtn.TextAlignment = TextAlignment.Justified;
  238. moveBtnA.TextAlignment = TextAlignment.Justified;
  239. sizeBtnA.TextAlignment = TextAlignment.Justified;
  240. moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
  241. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
  242. break;
  243. }
  244. };
  245. Application.Top.Ready += (s,e) => radioGroup.Refresh ();
  246. }
  247. }
  248. }