Frames.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. using System;
  2. using System.Linq;
  3. using Terminal.Gui;
  4. namespace UICatalog.Scenarios {
  5. [ScenarioMetadata (Name: "Frames Demo", Description: "Demonstrates Margin, Border, and Padding on Views.")]
  6. [ScenarioCategory ("Layout")]
  7. [ScenarioCategory ("Borders")]
  8. public class Frames : Scenario {
  9. public class FrameEditor : View {
  10. private Thickness _thickness;
  11. private TextField _topEdit;
  12. private TextField _leftEdit;
  13. private TextField _rightEdit;
  14. private TextField _bottomEdit;
  15. private bool _isUpdating;
  16. private ColorPicker _foregroundColorPicker;
  17. private ColorPicker _backgroundColorPicker;
  18. public Terminal.Gui.Attribute Color { get; set; }
  19. public Thickness Thickness {
  20. get => _thickness;
  21. set {
  22. if (_isUpdating) {
  23. return;
  24. }
  25. _thickness = value;
  26. ThicknessChanged?.Invoke (this, new ThicknessEventArgs () { Thickness = Thickness });
  27. if (IsInitialized) {
  28. _isUpdating = true;
  29. if (_topEdit.Text != _thickness.Top.ToString ()) {
  30. _topEdit.Text = _thickness.Top.ToString ();
  31. }
  32. if (_leftEdit.Text != _thickness.Left.ToString ()) {
  33. _leftEdit.Text = _thickness.Left.ToString ();
  34. }
  35. if (_rightEdit.Text != _thickness.Right.ToString ()) {
  36. _rightEdit.Text = _thickness.Right.ToString ();
  37. }
  38. if (_bottomEdit.Text != _thickness.Bottom.ToString ()) {
  39. _bottomEdit.Text = _thickness.Bottom.ToString ();
  40. }
  41. _isUpdating = false;
  42. }
  43. }
  44. }
  45. public event EventHandler<ThicknessEventArgs> ThicknessChanged;
  46. public event EventHandler<Terminal.Gui.Attribute> AttributeChanged;
  47. public FrameEditor ()
  48. {
  49. Margin.Thickness = new Thickness (0);
  50. BorderStyle = LineStyle.Double;
  51. Initialized += FrameEditor_Initialized; ;
  52. }
  53. void FrameEditor_Initialized (object sender, EventArgs e)
  54. {
  55. var editWidth = 3;
  56. _topEdit = new TextField ("") {
  57. X = Pos.Center (),
  58. Y = 0,
  59. Width = editWidth
  60. };
  61. _topEdit.TextChanging += Edit_TextChanging;
  62. Add (_topEdit);
  63. _leftEdit = new TextField ("") {
  64. X = Pos.Left (_topEdit) - editWidth,
  65. Y = Pos.Bottom (_topEdit),
  66. Width = editWidth
  67. };
  68. _leftEdit.TextChanging += Edit_TextChanging;
  69. Add (_leftEdit);
  70. _rightEdit = new TextField ("") {
  71. X = Pos.Right (_topEdit),
  72. Y = Pos.Bottom (_topEdit),
  73. Width = editWidth
  74. };
  75. _rightEdit.TextChanging += Edit_TextChanging;
  76. Add (_rightEdit);
  77. _bottomEdit = new TextField ("") {
  78. X = Pos.Center (),
  79. Y = Pos.Bottom (_leftEdit),
  80. Width = editWidth
  81. };
  82. _bottomEdit.TextChanging += Edit_TextChanging;
  83. Add (_bottomEdit);
  84. var copyTop = new Button ("Copy Top") {
  85. X = Pos.Center () + 1,
  86. Y = Pos.Bottom (_bottomEdit)
  87. };
  88. copyTop.Clicked += (s, e) => {
  89. Thickness = new Thickness (Thickness.Top);
  90. if (string.IsNullOrEmpty (_topEdit.Text)) {
  91. _topEdit.Text = "0";
  92. }
  93. _bottomEdit.Text = _leftEdit.Text = _rightEdit.Text = _topEdit.Text;
  94. };
  95. Add (copyTop);
  96. // Foreground ColorPicker.
  97. _foregroundColorPicker = new ColorPicker () {
  98. Title = "FG",
  99. BoxWidth = 1,
  100. BoxHeight = 1,
  101. X = -1,
  102. Y = Pos.Bottom (copyTop) + 1,
  103. BorderStyle = LineStyle.Single,
  104. SuperViewRendersLineCanvas = true
  105. };
  106. _foregroundColorPicker.ColorChanged += (o, a) =>
  107. AttributeChanged?.Invoke (this,
  108. new Attribute (_foregroundColorPicker.SelectedColor, _backgroundColorPicker.SelectedColor));
  109. Add (_foregroundColorPicker);
  110. // Background ColorPicker.
  111. _backgroundColorPicker = new ColorPicker () {
  112. Title = "BG",
  113. BoxWidth = 1,
  114. BoxHeight = 1,
  115. X = Pos.Right (_foregroundColorPicker) - 1,
  116. Y = Pos.Top (_foregroundColorPicker),
  117. BorderStyle = LineStyle.Single,
  118. SuperViewRendersLineCanvas = true
  119. };
  120. _backgroundColorPicker.ColorChanged += (o, a) =>
  121. AttributeChanged?.Invoke (this,
  122. new Terminal.Gui.Attribute (
  123. _foregroundColorPicker.SelectedColor,
  124. _backgroundColorPicker.SelectedColor));
  125. Add (_backgroundColorPicker);
  126. _topEdit.Text = $"{Thickness.Top}";
  127. _leftEdit.Text = $"{Thickness.Left}";
  128. _rightEdit.Text = $"{Thickness.Right}";
  129. _bottomEdit.Text = $"{Thickness.Bottom}";
  130. LayoutSubviews ();
  131. Height = GetFramesThickness ().Vertical + 4 + 4;
  132. Width = GetFramesThickness ().Horizontal + _foregroundColorPicker.Frame.Width * 2 - 3;
  133. }
  134. private void Edit_TextChanging (object sender, TextChangingEventArgs e)
  135. {
  136. try {
  137. if (string.IsNullOrEmpty (e.NewText.ToString ())) {
  138. e.Cancel = true;
  139. ((TextField)sender).Text = "0";
  140. return;
  141. }
  142. switch (sender.ToString ()) {
  143. case var s when s == _topEdit.ToString ():
  144. Thickness = new Thickness (Thickness.Left,
  145. int.Parse (e.NewText), Thickness.Right,
  146. Thickness.Bottom);
  147. break;
  148. case var s when s == _leftEdit.ToString ():
  149. Thickness = new Thickness (int.Parse (e.NewText),
  150. Thickness.Top, Thickness.Right,
  151. Thickness.Bottom);
  152. break;
  153. case var s when s == _rightEdit.ToString ():
  154. Thickness = new Thickness (Thickness.Left,
  155. Thickness.Top, int.Parse (e.NewText),
  156. Thickness.Bottom);
  157. break;
  158. case var s when s == _bottomEdit.ToString ():
  159. Thickness = new Thickness (Thickness.Left,
  160. Thickness.Top, Thickness.Right,
  161. int.Parse (e.NewText));
  162. break;
  163. }
  164. } catch {
  165. if (!string.IsNullOrEmpty(e.NewText)) {
  166. e.Cancel = true;
  167. }
  168. }
  169. }
  170. }
  171. public class FramesEditor : Window {
  172. private View _viewToEdit;
  173. private FrameEditor _marginEditor;
  174. private FrameEditor _borderEditor;
  175. private FrameEditor _paddingEditor;
  176. public FramesEditor (string title, View viewToEdit)
  177. {
  178. this._viewToEdit = viewToEdit;
  179. viewToEdit.Margin.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Toplevel"]);
  180. _marginEditor = new FrameEditor () {
  181. X = 0,
  182. Y = 0,
  183. Title = "Margin",
  184. Thickness = viewToEdit.Margin.Thickness,
  185. SuperViewRendersLineCanvas = true
  186. };
  187. _marginEditor.ThicknessChanged += Editor_ThicknessChanged;
  188. _marginEditor.AttributeChanged += Editor_AttributeChanged; ;
  189. Add (_marginEditor);
  190. viewToEdit.Border.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Base"]);
  191. _borderEditor = new FrameEditor () {
  192. X = Pos.Left (_marginEditor),
  193. Y = Pos.Bottom (_marginEditor),
  194. Title = "Border",
  195. Thickness = viewToEdit.Border.Thickness,
  196. SuperViewRendersLineCanvas = true
  197. };
  198. _borderEditor.ThicknessChanged += Editor_ThicknessChanged;
  199. _borderEditor.AttributeChanged += Editor_AttributeChanged;
  200. Add (_borderEditor);
  201. viewToEdit.Padding.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Error"]);
  202. var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast<LineStyle> ().ToList ();
  203. var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
  204. e => e.ToString ()).ToArray ()) {
  205. X = Pos.Right (_borderEditor) - 1,
  206. Y = Pos.Top (_borderEditor),
  207. SelectedItem = (int)viewToEdit.Border.BorderStyle,
  208. BorderStyle = LineStyle.Double,
  209. Title = "Border Style",
  210. SuperViewRendersLineCanvas = true
  211. };
  212. Add (rbBorderStyle);
  213. rbBorderStyle.SelectedItemChanged += (s, e) => {
  214. var prevBorderStyle = viewToEdit.BorderStyle;
  215. viewToEdit.Border.BorderStyle = (LineStyle)e.SelectedItem;
  216. if (viewToEdit.Border.BorderStyle == LineStyle.None) {
  217. viewToEdit.Border.Thickness = new Thickness (0);
  218. } else if (prevBorderStyle == LineStyle.None && viewToEdit.Border.BorderStyle != LineStyle.None) {
  219. viewToEdit.Border.Thickness = new Thickness (1);
  220. }
  221. _borderEditor.Thickness = new Thickness (viewToEdit.Border.Thickness.Left, viewToEdit.Border.Thickness.Top,
  222. viewToEdit.Border.Thickness.Right, viewToEdit.Border.Thickness.Bottom);
  223. viewToEdit.SetNeedsDisplay ();
  224. };
  225. var ckbTitle = new CheckBox ("Show Title") {
  226. BorderStyle = LineStyle.Double,
  227. X = Pos.Left (_borderEditor),
  228. Y = Pos.Bottom (_borderEditor) - 1,
  229. Width = Dim.Width (_borderEditor),
  230. Checked = true,
  231. SuperViewRendersLineCanvas = true
  232. };
  233. Add (ckbTitle);
  234. _paddingEditor = new FrameEditor () {
  235. X = Pos.Left (_borderEditor),
  236. Y = Pos.Bottom (rbBorderStyle),
  237. Title = "Padding",
  238. Thickness = viewToEdit.Padding.Thickness,
  239. SuperViewRendersLineCanvas = true
  240. };
  241. _paddingEditor.ThicknessChanged += Editor_ThicknessChanged;
  242. _paddingEditor.AttributeChanged += Editor_AttributeChanged;
  243. Add (_paddingEditor);
  244. viewToEdit.X = Pos.Right (rbBorderStyle);
  245. viewToEdit.Y = 0;
  246. viewToEdit.Width = Dim.Fill ();
  247. viewToEdit.Height = Dim.Fill ();
  248. Add (viewToEdit);
  249. viewToEdit.LayoutComplete += (s, e) => {
  250. if (ckbTitle.Checked == true) {
  251. viewToEdit.Title = viewToEdit.ToString ();
  252. } else {
  253. viewToEdit.Title = string.Empty;
  254. }
  255. };
  256. Title = title;
  257. }
  258. private void Editor_AttributeChanged (object sender, Terminal.Gui.Attribute attr)
  259. {
  260. switch (sender.ToString ()) {
  261. case var s when s == _marginEditor.ToString ():
  262. _viewToEdit.Margin.ColorScheme = new ColorScheme (_viewToEdit.Margin.ColorScheme) { Normal = attr };
  263. break;
  264. case var s when s == _borderEditor.ToString ():
  265. _viewToEdit.Border.ColorScheme = new ColorScheme (_viewToEdit.Border.ColorScheme) { Normal = attr };
  266. break;
  267. case var s when s == _paddingEditor.ToString ():
  268. _viewToEdit.Padding.ColorScheme = new ColorScheme (_viewToEdit.Padding.ColorScheme) { Normal = attr };
  269. break;
  270. }
  271. }
  272. private void Editor_ThicknessChanged (object sender, ThicknessEventArgs e)
  273. {
  274. try {
  275. switch (sender.ToString ()) {
  276. case var s when s == _marginEditor.ToString ():
  277. _viewToEdit.Margin.Thickness = e.Thickness;
  278. break;
  279. case var s when s == _borderEditor.ToString ():
  280. _viewToEdit.Border.Thickness = e.Thickness;
  281. break;
  282. case var s when s == _paddingEditor.ToString ():
  283. _viewToEdit.Padding.Thickness = e.Thickness;
  284. break;
  285. }
  286. } catch {
  287. switch (sender.ToString ()) {
  288. case var s when s == _marginEditor.ToString ():
  289. _viewToEdit.Margin.Thickness = e.PreviousThickness;
  290. break;
  291. case var s when s == _borderEditor.ToString ():
  292. _viewToEdit.Border.Thickness = e.PreviousThickness;
  293. break;
  294. case var s when s == _paddingEditor.ToString ():
  295. _viewToEdit.Padding.Thickness = e.PreviousThickness;
  296. break;
  297. }
  298. }
  299. }
  300. }
  301. public override void Init ()
  302. {
  303. Application.Init ();
  304. ConfigurationManager.Themes.Theme = Theme;
  305. ConfigurationManager.Apply ();
  306. Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
  307. var view = new Window ();
  308. var tf1 = new TextField ("TextField") { Width = 10 };
  309. var button = new Button ("Press me!") {
  310. X = Pos.Center (),
  311. Y = Pos.Center (),
  312. };
  313. button.Clicked += (s, e) => MessageBox.Query (20, 7, "Hi", $"Am I a {view.GetType ().Name}?", "Yes", "No");
  314. var label = new Label ($"I'm a {view.GetType ().Name}") {
  315. X = Pos.Center (),
  316. Y = Pos.Center () - 1,
  317. };
  318. var tf2 = new Button ("Button") {
  319. X = Pos.AnchorEnd (10),
  320. Y = Pos.AnchorEnd (1),
  321. Width = 10
  322. };
  323. var tv = new Label () {
  324. Y = Pos.AnchorEnd (2),
  325. Width = 25,
  326. Height = Dim.Fill (),
  327. Text = "Label\nY=AnchorEnd(2),Height=Dim.Fill()"
  328. };
  329. view.Margin.Thickness = new Thickness (3);
  330. view.Padding.Thickness = new Thickness (1);
  331. view.Add (tf1, button, label, tf2, tv);
  332. var editor = new FramesEditor (
  333. $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
  334. view);
  335. Application.Run (editor);
  336. Application.Shutdown ();
  337. }
  338. public override void Run ()
  339. {
  340. }
  341. }
  342. }