AdornmentEditor.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #nullable enable
  2. using System;
  3. using Terminal.Gui;
  4. namespace UICatalog.Scenarios;
  5. /// <summary>
  6. /// Provides a composable UI for editing the settings of an Adornment.
  7. /// </summary>
  8. public class AdornmentEditor : EditorBase
  9. {
  10. private readonly ColorPicker16 _backgroundColorPicker = new ()
  11. {
  12. Title = "_BG",
  13. BoxWidth = 1,
  14. BoxHeight = 1,
  15. BorderStyle = LineStyle.Single,
  16. SuperViewRendersLineCanvas = true
  17. };
  18. private readonly ColorPicker16 _foregroundColorPicker = new ()
  19. {
  20. Title = "_FG",
  21. BoxWidth = 1,
  22. BoxHeight = 1,
  23. BorderStyle = LineStyle.Single,
  24. SuperViewRendersLineCanvas = true
  25. };
  26. private CheckBox? _diagThicknessCheckBox;
  27. private CheckBox? _diagRulerCheckBox;
  28. private Adornment? _adornment;
  29. public Adornment? AdornmentToEdit
  30. {
  31. get => _adornment;
  32. set
  33. {
  34. Enabled = value is { };
  35. if (value == _adornment)
  36. {
  37. return;
  38. }
  39. _adornment = value;
  40. if (_adornment is null)
  41. {
  42. return;
  43. }
  44. if (IsInitialized)
  45. {
  46. _topEdit!.Value = _adornment.Thickness.Top;
  47. _leftEdit!.Value = _adornment.Thickness.Left;
  48. _bottomEdit!.Value = _adornment.Thickness.Bottom;
  49. _rightEdit!.Value = _adornment.Thickness.Right;
  50. _adornment.Initialized += (sender, args) =>
  51. {
  52. ColorScheme? cs = _adornment.ColorScheme;
  53. _foregroundColorPicker.SelectedColor = _adornment.GetNormalColor ().Foreground.GetClosestNamedColor16 ();
  54. _backgroundColorPicker.SelectedColor = _adornment.GetNormalColor ().Background.GetClosestNamedColor16 ();
  55. };
  56. }
  57. OnAdornmentChanged ();
  58. }
  59. }
  60. public event EventHandler<EventArgs>? AdornmentChanged;
  61. public void OnAdornmentChanged () { AdornmentChanged?.Invoke (this, EventArgs.Empty); }
  62. /// <inheritdoc/>
  63. protected override void OnViewToEditChanged () { AdornmentToEdit = ViewToEdit as Adornment; }
  64. private NumericUpDown<int>? _topEdit;
  65. private NumericUpDown<int>? _leftEdit;
  66. private NumericUpDown<int>? _bottomEdit;
  67. private NumericUpDown<int>? _rightEdit;
  68. public AdornmentEditor ()
  69. {
  70. CanFocus = true;
  71. Initialized += AdornmentEditor_Initialized;
  72. }
  73. private void AdornmentEditor_Initialized (object? sender, EventArgs e)
  74. {
  75. _topEdit = new ()
  76. {
  77. X = Pos.Center (), Y = 0,
  78. Format = "{0, 2}"
  79. };
  80. _topEdit.ValueChanging += Top_ValueChanging;
  81. Add (_topEdit);
  82. _leftEdit = new ()
  83. {
  84. X = Pos.Left (_topEdit) - Pos.Func (() => _topEdit.Text.Length) - 2, Y = Pos.Bottom (_topEdit),
  85. Format = _topEdit.Format
  86. };
  87. _leftEdit.ValueChanging += Left_ValueChanging;
  88. Add (_leftEdit);
  89. _rightEdit = new ()
  90. {
  91. X = Pos.Right (_leftEdit) + 5, Y = Pos.Bottom (_topEdit),
  92. Format = _topEdit.Format
  93. };
  94. _rightEdit.ValueChanging += Right_ValueChanging;
  95. Add (_rightEdit);
  96. _bottomEdit = new ()
  97. {
  98. X = Pos.Center (), Y = Pos.Bottom (_leftEdit),
  99. Format = _topEdit.Format
  100. };
  101. _bottomEdit.ValueChanging += Bottom_ValueChanging;
  102. Add (_bottomEdit);
  103. var copyTop = new Button
  104. {
  105. X = Pos.Center (), Y = Pos.Bottom (_bottomEdit), Text = "Cop_y Top"
  106. };
  107. copyTop.Accepting += (s, e) =>
  108. {
  109. AdornmentToEdit!.Thickness = new (_topEdit.Value);
  110. _leftEdit.Value = _rightEdit.Value = _bottomEdit.Value = _topEdit.Value;
  111. };
  112. Add (copyTop);
  113. // Foreground ColorPicker.
  114. _foregroundColorPicker.X = 0;
  115. _foregroundColorPicker.Y = Pos.Bottom (copyTop);
  116. _foregroundColorPicker.ColorChanged += ColorPickerColorChanged ();
  117. Add (_foregroundColorPicker);
  118. // Background ColorPicker.
  119. _backgroundColorPicker.X = Pos.Right (_foregroundColorPicker) - 1;
  120. _backgroundColorPicker.Y = Pos.Top (_foregroundColorPicker);
  121. _backgroundColorPicker.ColorChanged += ColorPickerColorChanged ();
  122. Add (_backgroundColorPicker);
  123. _topEdit.Value = AdornmentToEdit?.Thickness.Top ?? 0;
  124. _leftEdit.Value = AdornmentToEdit?.Thickness.Left ?? 0;
  125. _rightEdit.Value = AdornmentToEdit?.Thickness.Right ?? 0;
  126. _bottomEdit.Value = AdornmentToEdit?.Thickness.Bottom ?? 0;
  127. _diagThicknessCheckBox = new () { Text = "_Thickness Diag." };
  128. if (AdornmentToEdit is { })
  129. {
  130. _diagThicknessCheckBox.CheckedState =
  131. AdornmentToEdit.Diagnostics.FastHasFlags (ViewDiagnosticFlags.Thickness) ? CheckState.Checked : CheckState.UnChecked;
  132. }
  133. else
  134. {
  135. _diagThicknessCheckBox.CheckedState = Diagnostics.FastHasFlags (ViewDiagnosticFlags.Thickness) ? CheckState.Checked : CheckState.UnChecked;
  136. }
  137. _diagThicknessCheckBox.CheckedStateChanging += (s, e) =>
  138. {
  139. if (e.NewValue == CheckState.Checked)
  140. {
  141. AdornmentToEdit!.Diagnostics |= ViewDiagnosticFlags.Thickness;
  142. }
  143. else
  144. {
  145. AdornmentToEdit!.Diagnostics &= ~ViewDiagnosticFlags.Thickness;
  146. }
  147. };
  148. Add (_diagThicknessCheckBox);
  149. _diagThicknessCheckBox.Y = Pos.Bottom (_backgroundColorPicker);
  150. _diagRulerCheckBox = new () { Text = "_Ruler" };
  151. if (AdornmentToEdit is { })
  152. {
  153. _diagRulerCheckBox.CheckedState = AdornmentToEdit.Diagnostics.FastHasFlags (ViewDiagnosticFlags.Ruler) ? CheckState.Checked : CheckState.UnChecked;
  154. }
  155. else
  156. {
  157. _diagRulerCheckBox.CheckedState = Diagnostics.FastHasFlags (ViewDiagnosticFlags.Ruler) ? CheckState.Checked : CheckState.UnChecked;
  158. }
  159. _diagRulerCheckBox.CheckedStateChanging += (s, e) =>
  160. {
  161. if (e.NewValue == CheckState.Checked)
  162. {
  163. AdornmentToEdit!.Diagnostics |= ViewDiagnosticFlags.Ruler;
  164. }
  165. else
  166. {
  167. AdornmentToEdit!.Diagnostics &= ~ViewDiagnosticFlags.Ruler;
  168. }
  169. };
  170. Add (_diagRulerCheckBox);
  171. _diagRulerCheckBox.Y = Pos.Bottom (_diagThicknessCheckBox);
  172. }
  173. private EventHandler<ColorEventArgs> ColorPickerColorChanged ()
  174. {
  175. return (o, a) =>
  176. {
  177. if (AdornmentToEdit is null)
  178. {
  179. return;
  180. }
  181. AdornmentToEdit.ColorScheme = new (AdornmentToEdit.ColorScheme ?? AdornmentToEdit.Parent?.ColorScheme)
  182. {
  183. Normal = new (_foregroundColorPicker.SelectedColor, _backgroundColorPicker.SelectedColor)
  184. };
  185. };
  186. }
  187. private void Top_ValueChanging (object? sender, CancelEventArgs<int> e)
  188. {
  189. if (e.NewValue < 0 || AdornmentToEdit is null)
  190. {
  191. e.Cancel = true;
  192. return;
  193. }
  194. AdornmentToEdit.Thickness = new (AdornmentToEdit.Thickness.Left, e.NewValue, AdornmentToEdit.Thickness.Right, AdornmentToEdit.Thickness.Bottom);
  195. }
  196. private void Left_ValueChanging (object? sender, CancelEventArgs<int> e)
  197. {
  198. if (e.NewValue < 0 || AdornmentToEdit is null)
  199. {
  200. e.Cancel = true;
  201. return;
  202. }
  203. AdornmentToEdit.Thickness = new (e.NewValue, AdornmentToEdit.Thickness.Top, AdornmentToEdit.Thickness.Right, AdornmentToEdit.Thickness.Bottom);
  204. }
  205. private void Right_ValueChanging (object? sender, CancelEventArgs<int> e)
  206. {
  207. if (e.NewValue < 0 || AdornmentToEdit is null)
  208. {
  209. e.Cancel = true;
  210. return;
  211. }
  212. AdornmentToEdit.Thickness = new (AdornmentToEdit.Thickness.Left, AdornmentToEdit.Thickness.Top, e.NewValue, AdornmentToEdit.Thickness.Bottom);
  213. }
  214. private void Bottom_ValueChanging (object? sender, CancelEventArgs<int> e)
  215. {
  216. if (e.NewValue < 0 || AdornmentToEdit is null)
  217. {
  218. e.Cancel = true;
  219. return;
  220. }
  221. AdornmentToEdit.Thickness = new (AdornmentToEdit.Thickness.Left, AdornmentToEdit.Thickness.Top, AdornmentToEdit.Thickness.Right, e.NewValue);
  222. }
  223. }