Buttons.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Text;
  5. using JetBrains.Annotations;
  6. namespace UICatalog.Scenarios;
  7. [ScenarioMetadata ("Buttons", "Demonstrates all sorts of Buttons.")]
  8. [ScenarioCategory ("Controls")]
  9. [ScenarioCategory ("Layout")]
  10. public class Buttons : Scenario
  11. {
  12. public override void Main ()
  13. {
  14. Application.Init ();
  15. Window main = new ()
  16. {
  17. Title = GetQuitKeyAndName ()
  18. };
  19. // Add a label & text field so we can demo IsDefault
  20. var editLabel = new Label { X = 0, Y = 0, Text = "TextField (to demo IsDefault):" };
  21. main.Add (editLabel);
  22. // Add a TextField using Absolute layout.
  23. var edit = new TextField { X = 31, Width = 15, HotKey = Key.Y.WithAlt };
  24. main.Add (edit);
  25. // This is the default button (IsDefault = true); if user presses ENTER in the TextField
  26. // the scenario will quit
  27. var defaultButton = new Button { X = Pos.Center (), Y = Pos.AnchorEnd (), IsDefault = true, Text = "_Quit" };
  28. main.Add (defaultButton);
  29. // Note we handle Accept on main, not defaultButton
  30. main.Accepting += (s, e) => Application.RequestStop ();
  31. var swapButton = new Button
  32. {
  33. X = 50,
  34. Width = 45,
  35. Height = 3,
  36. Text = "S_wap Default (Size = 45, 3)",
  37. SchemeName = "Error"
  38. };
  39. swapButton.Accepting += (s, e) =>
  40. {
  41. e.Handled = !swapButton.IsDefault;
  42. defaultButton.IsDefault = !defaultButton.IsDefault;
  43. swapButton.IsDefault = !swapButton.IsDefault;
  44. };
  45. defaultButton.Accepting += (s, e) =>
  46. {
  47. e.Handled = !defaultButton.IsDefault;
  48. if (e.Handled)
  49. {
  50. MessageBox.ErrorQuery ((s as View)?.App, "Error", "This button is no longer the Quit button; the Swap Default button is.", "_Ok");
  51. }
  52. };
  53. main.Add (swapButton);
  54. static void DoMessage (Button button, string txt)
  55. {
  56. button.Accepting += (s, e) =>
  57. {
  58. string btnText = button.Text;
  59. MessageBox.Query ((s as View)?.App, "Message", $"Did you click {txt}?", "Yes", "No");
  60. e.Handled = true;
  61. };
  62. }
  63. var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " };
  64. main.Add (colorButtonsLabel);
  65. View prev = colorButtonsLabel;
  66. foreach (KeyValuePair<string, Scheme> scheme in SchemeManager.GetSchemesForCurrentTheme ())
  67. {
  68. var colorButton = new Button
  69. {
  70. X = Pos.Right (prev),
  71. Y = Pos.Y (colorButtonsLabel),
  72. Text = $"_{scheme.Key}",
  73. SchemeName = scheme.Key,
  74. };
  75. DoMessage (colorButton, colorButton.Text);
  76. main.Add (colorButton);
  77. prev = colorButton;
  78. }
  79. Button button;
  80. main.Add (
  81. button = new ()
  82. {
  83. X = 2,
  84. Y = Pos.Bottom (colorButtonsLabel) + 1,
  85. Text =
  86. "A super l_öng Button that will probably expose a bug in clipping or wrapping of text. Will it?"
  87. }
  88. );
  89. DoMessage (button, button.Text);
  90. // Note the 'N' in 'Newline' will be the hotkey
  91. main.Add (
  92. button = new () { X = 2, Y = Pos.Bottom (button) + 1, Height = 2, Text = "a Newline\nin the button" }
  93. );
  94. button.Accepting += (s, e) =>
  95. {
  96. MessageBox.Query ((s as View)?.App, "Message", "Question?", "Yes", "No");
  97. e.Handled = true;
  98. };
  99. var textChanger = new Button { X = 2, Y = Pos.Bottom (button) + 1, Text = "Te_xt Changer" };
  100. main.Add (textChanger);
  101. textChanger.Accepting += (s, e) =>
  102. {
  103. textChanger.Text += "!";
  104. e.Handled = true;
  105. };
  106. main.Add (
  107. button = new ()
  108. {
  109. X = Pos.Right (textChanger) + 2,
  110. Y = Pos.Y (textChanger),
  111. Text = "Lets see if this will move as \"Text Changer\" grows"
  112. }
  113. );
  114. button.Accepting += (sender, args) => { args.Handled = true; };
  115. var removeButton = new Button
  116. {
  117. X = 2, Y = Pos.Bottom (button) + 1,
  118. SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Error),
  119. Text = "Remove this button"
  120. };
  121. main.Add (removeButton);
  122. // This in interesting test case because `moveBtn` and below are laid out relative to this one!
  123. removeButton.Accepting += (s, e) =>
  124. {
  125. removeButton.Visible = false;
  126. e.Handled = true;
  127. };
  128. var computedFrame = new FrameView
  129. {
  130. X = 0,
  131. Y = Pos.Bottom (removeButton) + 1,
  132. Width = Dim.Percent (50),
  133. Height = 6,
  134. Title = "Computed Layout"
  135. };
  136. main.Add (computedFrame);
  137. // Demonstrates how changing the View.Frame property can move Views
  138. var moveBtn = new Button
  139. {
  140. X = 0,
  141. Y = Pos.Center () - 1,
  142. Width = 30,
  143. SchemeName = "Error",
  144. Text = "Move This \u263b Button v_ia Pos"
  145. };
  146. moveBtn.Accepting += (s, e) =>
  147. {
  148. moveBtn.X = moveBtn.Frame.X + 5;
  149. e.Handled = true;
  150. };
  151. computedFrame.Add (moveBtn);
  152. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  153. var sizeBtn = new Button
  154. {
  155. Y = Pos.Center () + 1,
  156. X = 0,
  157. Width = 30,
  158. Text = "Grow This \u263a Button _via Pos",
  159. SchemeName = "Error",
  160. };
  161. sizeBtn.Accepting += (s, e) =>
  162. {
  163. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  164. e.Handled = true;
  165. };
  166. computedFrame.Add (sizeBtn);
  167. var absoluteFrame = new FrameView
  168. {
  169. X = Pos.Right (computedFrame),
  170. Y = Pos.Bottom (removeButton) + 1,
  171. Width = Dim.Fill (),
  172. Height = 6,
  173. Title = "Absolute Layout"
  174. };
  175. main.Add (absoluteFrame);
  176. // Demonstrates how changing the View.Frame property can move Views
  177. var moveBtnA = new Button { SchemeName = "Error", Text = "Move This Button via Frame" };
  178. moveBtnA.Accepting += (s, e) =>
  179. {
  180. moveBtnA.Frame = new (
  181. moveBtnA.Frame.X + 5,
  182. moveBtnA.Frame.Y,
  183. moveBtnA.Frame.Width,
  184. moveBtnA.Frame.Height
  185. );
  186. e.Handled = true;
  187. };
  188. absoluteFrame.Add (moveBtnA);
  189. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  190. var sizeBtnA = new Button
  191. {
  192. Y = 2, SchemeName = "Error", Text = " ~  s  gui.cs   master ↑_10 = Сохранить"
  193. };
  194. sizeBtnA.Accepting += (s, e) =>
  195. {
  196. sizeBtnA.Frame = new (
  197. sizeBtnA.Frame.X,
  198. sizeBtnA.Frame.Y,
  199. sizeBtnA.Frame.Width + 5,
  200. sizeBtnA.Frame.Height
  201. );
  202. e.Handled = true;
  203. };
  204. absoluteFrame.Add (sizeBtnA);
  205. var label = new Label
  206. {
  207. X = 2, Y = Pos.Bottom (computedFrame) + 1,
  208. Text = "Text Ali_gnment (changes the four buttons above): "
  209. };
  210. main.Add (label);
  211. OptionSelector<Alignment> osAlignment = new ()
  212. {
  213. X = 4,
  214. Y = Pos.Bottom (label) + 1,
  215. Value = Alignment.Center,
  216. AssignHotKeys = true,
  217. Title = "_9 OptionSelector",
  218. BorderStyle = LineStyle.Dotted,
  219. // CanFocus = false
  220. };
  221. main.Add (osAlignment);
  222. // Demo changing hotkey
  223. string MoveHotkey (string txt)
  224. {
  225. // Remove the '_'
  226. List<Rune> runes = txt.ToRuneList ();
  227. int i = runes.IndexOf ((Rune)'_');
  228. var start = "";
  229. if (i > -1)
  230. {
  231. start = StringExtensions.ToString (runes.GetRange (0, i));
  232. }
  233. txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1)));
  234. runes = txt.ToRuneList ();
  235. // Move over one or go to start
  236. i++;
  237. if (i >= runes.Count)
  238. {
  239. i = 0;
  240. }
  241. // Slip in the '_'
  242. start = StringExtensions.ToString (runes.GetRange (0, i));
  243. return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i));
  244. }
  245. var mhkb = "Click to Change th_is Button's Hotkey";
  246. var moveHotKeyBtn = new Button
  247. {
  248. X = 2,
  249. Y = Pos.Bottom (osAlignment) + 1,
  250. Width = Dim.Width (computedFrame) - 2,
  251. SchemeName = "Runnable",
  252. Text = mhkb
  253. };
  254. moveHotKeyBtn.Accepting += (s, e) =>
  255. {
  256. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  257. e.Handled = true;
  258. };
  259. main.Add (moveHotKeyBtn);
  260. var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
  261. var moveUnicodeHotKeyBtn = new Button
  262. {
  263. X = Pos.Left (absoluteFrame) + 1,
  264. Y = Pos.Bottom (osAlignment) + 1,
  265. Width = Dim.Width (absoluteFrame) - 2,
  266. SchemeName = "Runnable",
  267. Text = muhkb
  268. };
  269. moveUnicodeHotKeyBtn.Accepting += (s, e) =>
  270. {
  271. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  272. e.Handled = true;
  273. };
  274. main.Add (moveUnicodeHotKeyBtn);
  275. osAlignment.ValueChanged += (s, args) =>
  276. {
  277. if (args.Value is null)
  278. {
  279. return;
  280. }
  281. Alignment newValue = args.Value.Value;
  282. moveBtn.TextAlignment = newValue;
  283. sizeBtn.TextAlignment = newValue;
  284. moveBtnA.TextAlignment = newValue;
  285. sizeBtnA.TextAlignment = newValue;
  286. moveHotKeyBtn.TextAlignment = newValue;
  287. moveUnicodeHotKeyBtn.TextAlignment = newValue;
  288. };
  289. label = new ()
  290. {
  291. X = 0,
  292. Y = Pos.Bottom (moveUnicodeHotKeyBtn) + 1,
  293. Title = "_Numeric Up/Down (press-and-hold):",
  294. };
  295. var numericUpDown = new NumericUpDown<int>
  296. {
  297. Value = 69,
  298. X = Pos.Right (label) + 1,
  299. Y = Pos.Top (label),
  300. };
  301. numericUpDown.ValueChanged += NumericUpDown_ValueChanged;
  302. void NumericUpDown_ValueChanged (object sender, EventArgs<int> e) { }
  303. main.Add (label, numericUpDown);
  304. label = new ()
  305. {
  306. X = 0,
  307. Y = Pos.Bottom (numericUpDown) + 1,
  308. Title = "_No Repeat:"
  309. };
  310. var noRepeatAcceptCount = 0;
  311. var noRepeatButton = new Button
  312. {
  313. X = Pos.Right (label) + 1,
  314. Y = Pos.Top (label),
  315. Title = $"Accept Cou_nt: {noRepeatAcceptCount}",
  316. WantContinuousButtonPressed = false
  317. };
  318. noRepeatButton.Accepting += (s, e) =>
  319. {
  320. noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}";
  321. e.Handled = true;
  322. };
  323. main.Add (label, noRepeatButton);
  324. label = new ()
  325. {
  326. X = 0,
  327. Y = Pos.Bottom (label) + 1,
  328. Title = "_Repeat (press-and-hold):"
  329. };
  330. var acceptCount = 0;
  331. var repeatButton = new Button
  332. {
  333. Id = "repeatButton",
  334. X = Pos.Right (label) + 1,
  335. Y = Pos.Top (label),
  336. Title = $"Accept Co_unt: {acceptCount}",
  337. WantContinuousButtonPressed = true
  338. };
  339. repeatButton.Accepting += (s, e) =>
  340. {
  341. repeatButton.Title = $"Accept Co_unt: {++acceptCount}";
  342. e.Handled = true;
  343. };
  344. var enableCB = new CheckBox
  345. {
  346. X = Pos.Right (repeatButton) + 1,
  347. Y = Pos.Top (repeatButton),
  348. Title = "Enabled",
  349. CheckedState = CheckState.Checked
  350. };
  351. enableCB.CheckedStateChanging += (s, e) => { repeatButton.Enabled = !repeatButton.Enabled; };
  352. main.Add (label, repeatButton, enableCB);
  353. var decNumericUpDown = new NumericUpDown<int>
  354. {
  355. Value = 911,
  356. Increment = 1,
  357. Format = "{0:X}",
  358. X = 0,
  359. Y = Pos.Bottom (enableCB) + 1,
  360. };
  361. main.Add (decNumericUpDown);
  362. Application.Run (main);
  363. main.Dispose ();
  364. Application.Shutdown ();
  365. }
  366. }