Text.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using Terminal.Gui;
  7. using Terminal.Gui.TextValidateProviders;
  8. namespace UICatalog.Scenarios;
  9. [ScenarioMetadata ("Text Input Controls", "Tests all text input controls")]
  10. [ScenarioCategory ("Controls")]
  11. [ScenarioCategory ("Mouse and Keyboard")]
  12. [ScenarioCategory ("Text and Formatting")]
  13. public class Text : Scenario
  14. {
  15. private Label _labelMirroringTimeField;
  16. private TimeField _timeField;
  17. public override void Setup ()
  18. {
  19. // TextField is a simple, single-line text input control
  20. var label = new Label { Text = "_TextField:" };
  21. Win.Add (label);
  22. var textField = new TextField
  23. {
  24. X = Pos.Right (label) + 1,
  25. Y = 0,
  26. Width = Dim.Percent (50) - 1,
  27. Text = "TextField with test text. Unicode shouldn't 𝔹Aℝ𝔽!"
  28. };
  29. var singleWordGenerator = new SingleWordSuggestionGenerator ();
  30. textField.Autocomplete.SuggestionGenerator = singleWordGenerator;
  31. textField.TextChanging += TextField_TextChanging;
  32. void TextField_TextChanging (object sender, StateEventArgs<string> e)
  33. {
  34. singleWordGenerator.AllSuggestions = Regex.Matches (e.NewValue, "\\w+")
  35. .Select (s => s.Value)
  36. .Distinct ()
  37. .ToList ();
  38. }
  39. Win.Add (textField);
  40. var labelMirroringTextField = new Label
  41. {
  42. X = Pos.Right (textField) + 1,
  43. Y = Pos.Top (textField),
  44. Width = Dim.Fill (1) - 1,
  45. Height = 1,
  46. Text = textField.Text
  47. };
  48. Win.Add (labelMirroringTextField);
  49. textField.TextChanged += (s, prev) => { labelMirroringTextField.Text = textField.Text; };
  50. // TextView is a rich (as in functionality, not formatting) text editing control
  51. label = new() { Text = "T_extView:", Y = Pos.Bottom (label) + 1 };
  52. Win.Add (label);
  53. var textView = new TextView
  54. {
  55. X = Pos.Right (label) + 1,
  56. Y = Pos.Top (label),
  57. Width = Dim.Percent (50) - 1,
  58. Height = Dim.Percent (20)
  59. };
  60. textView.Text = "TextView with some more test text. Unicode shouldn't 𝔹Aℝ𝔽!";
  61. textView.DrawContent += TextView_DrawContent;
  62. // This shows how to enable autocomplete in TextView.
  63. void TextView_DrawContent (object sender, DrawEventArgs e)
  64. {
  65. singleWordGenerator.AllSuggestions = Regex.Matches (textView.Text, "\\w+")
  66. .Select (s => s.Value)
  67. .Distinct ()
  68. .ToList ();
  69. }
  70. Win.Add (textView);
  71. var labelMirroringTextView = new Label
  72. {
  73. X = Pos.Right (textView) + 1,
  74. Y = Pos.Top (textView),
  75. Width = Dim.Fill (1) - 1,
  76. Height = Dim.Height (textView) - 1
  77. };
  78. Win.Add (labelMirroringTextView);
  79. // Use ContentChanged to detect if the user has typed something in a TextView.
  80. // The TextChanged property is only fired if the TextView.Text property is
  81. // explicitly set
  82. textView.ContentsChanged += (s, a) =>
  83. {
  84. labelMirroringTextView.Enabled = !labelMirroringTextView.Enabled;
  85. labelMirroringTextView.Text = textView.Text;
  86. };
  87. // By default TextView is a multi-line control. It can be forced to
  88. // single-line mode.
  89. var chxMultiline = new CheckBox
  90. {
  91. X = Pos.Left (textView), Y = Pos.Bottom (textView), Checked = textView.Multiline, Text = "_Multiline"
  92. };
  93. Win.Add (chxMultiline);
  94. var chxWordWrap = new CheckBox
  95. {
  96. X = Pos.Right (chxMultiline) + 2,
  97. Y = Pos.Top (chxMultiline),
  98. Checked = textView.WordWrap,
  99. Text = "_Word Wrap"
  100. };
  101. chxWordWrap.Toggled += (s, e) => textView.WordWrap = (bool)e.NewValue;
  102. Win.Add (chxWordWrap);
  103. // TextView captures Tabs (so users can enter /t into text) by default;
  104. // This means using Tab to navigate doesn't work by default. This shows
  105. // how to turn tab capture off.
  106. var chxCaptureTabs = new CheckBox
  107. {
  108. X = Pos.Right (chxWordWrap) + 2,
  109. Y = Pos.Top (chxWordWrap),
  110. Checked = textView.AllowsTab,
  111. Text = "_Capture Tabs"
  112. };
  113. chxMultiline.Toggled += (s, e) =>
  114. {
  115. textView.Multiline = (bool)e.NewValue;
  116. if (!textView.Multiline && (bool)chxWordWrap.Checked)
  117. {
  118. chxWordWrap.Checked = false;
  119. }
  120. if (!textView.Multiline && (bool)chxCaptureTabs.Checked)
  121. {
  122. chxCaptureTabs.Checked = false;
  123. }
  124. };
  125. Key keyTab = textView.KeyBindings.GetKeyFromCommands (Command.Tab);
  126. Key keyBackTab = textView.KeyBindings.GetKeyFromCommands (Command.BackTab);
  127. chxCaptureTabs.Toggled += (s, e) =>
  128. {
  129. if (e.NewValue == true)
  130. {
  131. textView.KeyBindings.Add (keyTab, Command.Tab);
  132. textView.KeyBindings.Add (keyBackTab, Command.BackTab);
  133. }
  134. else
  135. {
  136. textView.KeyBindings.Remove (keyTab);
  137. textView.KeyBindings.Remove (keyBackTab);
  138. }
  139. textView.AllowsTab = (bool)e.NewValue;
  140. };
  141. Win.Add (chxCaptureTabs);
  142. // Hex editor
  143. label = new() { Text = "_HexView:", Y = Pos.Bottom (chxMultiline) + 1 };
  144. Win.Add (label);
  145. var hexEditor =
  146. new HexView (
  147. new MemoryStream (Encoding.UTF8.GetBytes ("HexEditor Unicode that shouldn't 𝔹Aℝ𝔽!"))
  148. )
  149. {
  150. X = Pos.Right (label) + 1, Y = Pos.Bottom (chxMultiline) + 1, Width = Dim.Percent (50) - 1, Height = Dim.Percent (30)
  151. };
  152. Win.Add (hexEditor);
  153. var labelMirroringHexEditor = new Label
  154. {
  155. X = Pos.Right (hexEditor) + 1,
  156. Y = Pos.Top (hexEditor),
  157. Width = Dim.Fill (1) - 1,
  158. Height = Dim.Height (hexEditor) - 1
  159. };
  160. byte [] array = ((MemoryStream)hexEditor.Source).ToArray ();
  161. labelMirroringHexEditor.Text = Encoding.UTF8.GetString (array, 0, array.Length);
  162. hexEditor.Edited += (s, kv) =>
  163. {
  164. hexEditor.ApplyEdits ();
  165. byte [] array = ((MemoryStream)hexEditor.Source).ToArray ();
  166. labelMirroringHexEditor.Text = Encoding.UTF8.GetString (array, 0, array.Length);
  167. };
  168. Win.Add (labelMirroringHexEditor);
  169. // DateField
  170. label = new() { Text = "_DateField:", Y = Pos.Bottom (hexEditor) + 1 };
  171. Win.Add (label);
  172. var dateField = new DateField (DateTime.Now) { X = Pos.Right (label) + 1, Y = Pos.Bottom (hexEditor) + 1, Width = 20 };
  173. Win.Add (dateField);
  174. var labelMirroringDateField = new Label
  175. {
  176. X = Pos.Right (dateField) + 1,
  177. Y = Pos.Top (dateField),
  178. Width = Dim.Width (dateField),
  179. Height = Dim.Height (dateField),
  180. Text = dateField.Text
  181. };
  182. Win.Add (labelMirroringDateField);
  183. dateField.TextChanged += (s, prev) => { labelMirroringDateField.Text = dateField.Text; };
  184. // TimeField
  185. label = new() { Text = "T_imeField:", Y = Pos.Top (dateField), X = Pos.Right (labelMirroringDateField) + 5 };
  186. Win.Add (label);
  187. _timeField = new()
  188. {
  189. X = Pos.Right (label) + 1,
  190. Y = Pos.Top (dateField),
  191. Width = 20,
  192. IsShortFormat = false,
  193. Time = DateTime.Now.TimeOfDay
  194. };
  195. Win.Add (_timeField);
  196. _labelMirroringTimeField = new()
  197. {
  198. X = Pos.Right (_timeField) + 1,
  199. Y = Pos.Top (_timeField),
  200. Width = Dim.Width (_timeField),
  201. Height = Dim.Height (_timeField),
  202. Text = _timeField.Text
  203. };
  204. Win.Add (_labelMirroringTimeField);
  205. _timeField.TimeChanged += TimeChanged;
  206. // MaskedTextProvider - uses .NET MaskedTextProvider
  207. var netProviderLabel = new Label
  208. {
  209. X = Pos.Left (dateField),
  210. Y = Pos.Bottom (dateField) + 1,
  211. Text = "_NetMaskedTextProvider [ 999 000 LLL >LLL |AAA aaa ]:"
  212. };
  213. Win.Add (netProviderLabel);
  214. var netProvider = new NetMaskedTextProvider ("999 000 LLL >LLL |AAA aaa");
  215. var netProviderField = new TextValidateField
  216. {
  217. X = Pos.Right (netProviderLabel) + 1, Y = Pos.Y (netProviderLabel), Provider = netProvider
  218. };
  219. Win.Add (netProviderField);
  220. var labelMirroringNetProviderField = new Label
  221. {
  222. X = Pos.Right (netProviderField) + 1,
  223. Y = Pos.Top (netProviderField),
  224. Width = Dim.Width (netProviderField),
  225. Height = Dim.Height (netProviderField),
  226. Text = netProviderField.Text
  227. };
  228. Win.Add (labelMirroringNetProviderField);
  229. netProviderField.Provider.TextChanged += (s, prev) => { labelMirroringNetProviderField.Text = netProviderField.Text; };
  230. // TextRegexProvider - Regex provider implemented by Terminal.Gui
  231. var regexProvider = new Label
  232. {
  233. X = Pos.Left (netProviderLabel),
  234. Y = Pos.Bottom (netProviderLabel) + 1,
  235. Text = "Text_RegexProvider [ ^([0-9]?[0-9]?[0-9]|1000)$ ]:"
  236. };
  237. Win.Add (regexProvider);
  238. var provider2 = new TextRegexProvider ("^([0-9]?[0-9]?[0-9]|1000)$") { ValidateOnInput = false };
  239. var regexProviderField = new TextValidateField
  240. {
  241. X = Pos.Right (regexProvider) + 1,
  242. Y = Pos.Y (regexProvider),
  243. Width = 30,
  244. TextAlignment = Alignment.Center,
  245. Provider = provider2
  246. };
  247. Win.Add (regexProviderField);
  248. var labelMirroringRegexProviderField = new Label
  249. {
  250. X = Pos.Right (regexProviderField) + 1,
  251. Y = Pos.Top (regexProviderField),
  252. Width = Dim.Width (regexProviderField),
  253. Height = Dim.Height (regexProviderField),
  254. Text = regexProviderField.Text
  255. };
  256. Win.Add (labelMirroringRegexProviderField);
  257. regexProviderField.Provider.TextChanged += (s, prev) => { labelMirroringRegexProviderField.Text = regexProviderField.Text; };
  258. var labelAppendAutocomplete = new Label
  259. {
  260. Y = Pos.Y (regexProviderField) + 2, X = 1, Text = "_Append Autocomplete:"
  261. };
  262. var appendAutocompleteTextField = new TextField
  263. {
  264. X = Pos.Right (labelAppendAutocomplete) + 1, Y = Pos.Top (labelAppendAutocomplete), Width = Dim.Fill ()
  265. };
  266. appendAutocompleteTextField.Autocomplete = new AppendAutocomplete (appendAutocompleteTextField);
  267. appendAutocompleteTextField.Autocomplete.SuggestionGenerator = new SingleWordSuggestionGenerator
  268. {
  269. AllSuggestions = new()
  270. {
  271. "fish",
  272. "flipper",
  273. "fin",
  274. "fun",
  275. "the",
  276. "at",
  277. "there",
  278. "some",
  279. "my",
  280. "of",
  281. "be",
  282. "use",
  283. "her",
  284. "than",
  285. "and",
  286. "this",
  287. "an",
  288. "would",
  289. "first",
  290. "have",
  291. "each",
  292. "make",
  293. "water",
  294. "to",
  295. "from",
  296. "which",
  297. "like",
  298. "been",
  299. "in",
  300. "or",
  301. "she",
  302. "him",
  303. "call",
  304. "is",
  305. "one",
  306. "do",
  307. "into",
  308. "who",
  309. "you",
  310. "had",
  311. "how",
  312. "time",
  313. "oil",
  314. "that",
  315. "by",
  316. "their",
  317. "has",
  318. "its",
  319. "it",
  320. "word",
  321. "if",
  322. "look",
  323. "now",
  324. "he",
  325. "but",
  326. "will",
  327. "two",
  328. "find",
  329. "was",
  330. "not",
  331. "up",
  332. "more",
  333. "long",
  334. "for",
  335. "what",
  336. "other",
  337. "write",
  338. "down",
  339. "on",
  340. "all",
  341. "about",
  342. "go",
  343. "day",
  344. "are",
  345. "were",
  346. "out",
  347. "see",
  348. "did",
  349. "as",
  350. "we",
  351. "many",
  352. "number",
  353. "get",
  354. "with",
  355. "when",
  356. "then",
  357. "no",
  358. "come",
  359. "his",
  360. "your",
  361. "them",
  362. "way",
  363. "made",
  364. "they",
  365. "can",
  366. "these",
  367. "could",
  368. "may",
  369. "said",
  370. "so",
  371. "people",
  372. "part"
  373. }
  374. };
  375. Win.Add (labelAppendAutocomplete);
  376. Win.Add (appendAutocompleteTextField);
  377. }
  378. private void TimeChanged (object sender, DateTimeEventArgs<TimeSpan> e) { _labelMirroringTimeField.Text = _timeField.Text; }
  379. }