Program.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #nullable enable
  2. // Example demonstrating how to make ANY View runnable without implementing IRunnable
  3. using Terminal.Gui.App;
  4. using Terminal.Gui.Drawing;
  5. using Terminal.Gui.ViewBase;
  6. using Terminal.Gui.Views;
  7. // Example metadata
  8. [assembly: Terminal.Gui.Examples.ExampleMetadata ("Runnable Wrapper Example", "Shows how to wrap any View to make it runnable without implementing IRunnable")]
  9. [assembly: Terminal.Gui.Examples.ExampleCategory ("API Patterns")]
  10. [assembly: Terminal.Gui.Examples.ExampleCategory ("Views")]
  11. [assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:200", "t", "e", "s", "t", "Esc"], Order = 1)]
  12. [assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:200", "Enter", "Esc"], Order = 2)]
  13. [assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:200", "Enter", "Esc"], Order = 3)]
  14. [assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:200", "Enter", "Esc"], Order = 4)]
  15. [assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:200", "Enter", "Esc"], Order = 5)]
  16. IApplication app = Application.Create (example: true);
  17. app.Init ();
  18. // Example 1: Use extension method with result extraction
  19. var textField = new TextField { Width = 40, Text = "Default text" };
  20. textField.Title = "Enter your name";
  21. textField.BorderStyle = LineStyle.Single;
  22. RunnableWrapper<TextField, string> textRunnable = textField.AsRunnable (tf => tf.Text);
  23. app.Run (textRunnable);
  24. if (textRunnable.Result is { } name)
  25. {
  26. MessageBox.Query (app, "Result", $"You entered: {name}", "OK");
  27. }
  28. else
  29. {
  30. MessageBox.Query (app, "Result", "Canceled", "OK");
  31. }
  32. textRunnable.Dispose ();
  33. // Example 2: Use IApplication.RunView() for one-liner
  34. Color selectedColor = app.RunView (
  35. new ColorPicker
  36. {
  37. Title = "Pick a Color",
  38. BorderStyle = LineStyle.Single
  39. },
  40. cp => cp.SelectedColor);
  41. MessageBox.Query (app, "Result", $"Selected color: {selectedColor}", "OK");
  42. // Example 3: FlagSelector with typed enum result
  43. FlagSelector<SelectorStyles> flagSelector = new()
  44. {
  45. Title = "Choose Styles",
  46. BorderStyle = LineStyle.Single
  47. };
  48. RunnableWrapper<FlagSelector<SelectorStyles>, SelectorStyles?> flagsRunnable = flagSelector.AsRunnable (fs => fs.Value);
  49. app.Run (flagsRunnable);
  50. MessageBox.Query (app, "Result", $"Selected styles: {flagsRunnable.Result}", "OK");
  51. flagsRunnable.Dispose ();
  52. // Example 4: Any View without result extraction
  53. var label = new Label
  54. {
  55. Text = "Press Esc to continue...",
  56. X = Pos.Center (),
  57. Y = Pos.Center ()
  58. };
  59. RunnableWrapper<Label, object> labelRunnable = label.AsRunnable ();
  60. app.Run (labelRunnable);
  61. // Can still access the wrapped view
  62. MessageBox.Query (app, "Result", $"Label text was: {labelRunnable.WrappedView.Text}", "OK");
  63. labelRunnable.Dispose ();
  64. // Example 5: Complex custom View made runnable
  65. View formView = CreateCustomForm ();
  66. RunnableWrapper<View, FormData> formRunnable = formView.AsRunnable (ExtractFormData);
  67. app.Run (formRunnable);
  68. if (formRunnable.Result is { } formData)
  69. {
  70. MessageBox.Query (
  71. app,
  72. "Form Results",
  73. $"Name: {formData.Name}\nAge: {formData.Age}\nAgreed: {formData.Agreed}",
  74. "OK");
  75. }
  76. formRunnable.Dispose ();
  77. app.Dispose ();
  78. // Helper method to create a custom form
  79. View CreateCustomForm ()
  80. {
  81. var form = new View
  82. {
  83. Title = "User Information",
  84. BorderStyle = LineStyle.Single,
  85. Width = 50,
  86. Height = 10
  87. };
  88. var nameField = new TextField
  89. {
  90. Id = "nameField",
  91. X = 10,
  92. Y = 1,
  93. Width = 30
  94. };
  95. var ageField = new TextField
  96. {
  97. Id = "ageField",
  98. X = 10,
  99. Y = 3,
  100. Width = 10
  101. };
  102. var agreeCheckbox = new CheckBox
  103. {
  104. Id = "agreeCheckbox",
  105. Title = "I agree to terms",
  106. X = 10,
  107. Y = 5
  108. };
  109. var okButton = new Button
  110. {
  111. Title = "OK",
  112. X = Pos.Center (),
  113. Y = 7,
  114. IsDefault = true
  115. };
  116. okButton.Accepting += (s, e) =>
  117. {
  118. form.App?.RequestStop ();
  119. e.Handled = true;
  120. };
  121. form.Add (new Label { Text = "Name:", X = 2, Y = 1 });
  122. form.Add (nameField);
  123. form.Add (new Label { Text = "Age:", X = 2, Y = 3 });
  124. form.Add (ageField);
  125. form.Add (agreeCheckbox);
  126. form.Add (okButton);
  127. return form;
  128. }
  129. // Helper method to extract data from the custom form
  130. FormData ExtractFormData (View form)
  131. {
  132. var nameField = form.SubViews.FirstOrDefault (v => v.Id == "nameField") as TextField;
  133. var ageField = form.SubViews.FirstOrDefault (v => v.Id == "ageField") as TextField;
  134. var agreeCheckbox = form.SubViews.FirstOrDefault (v => v.Id == "agreeCheckbox") as CheckBox;
  135. return new()
  136. {
  137. Name = nameField?.Text ?? string.Empty,
  138. Age = int.TryParse (ageField?.Text, out int age) ? age : 0,
  139. Agreed = agreeCheckbox?.CheckedState == CheckState.Checked
  140. };
  141. }
  142. // Result type for custom form
  143. internal record FormData
  144. {
  145. public string Name { get; init; } = string.Empty;
  146. public int Age { get; init; }
  147. public bool Agreed { get; init; }
  148. }