PosEditor.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #nullable enable
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using Terminal.Gui;
  7. namespace UICatalog.Scenarios;
  8. /// <summary>
  9. /// Provides an editor UI for the Margin, Border, and Padding of a View.
  10. /// </summary>
  11. public class PosEditor : EditorBase
  12. {
  13. public PosEditor ()
  14. {
  15. Title = "Pos";
  16. Initialized += PosEditor_Initialized;
  17. }
  18. private int _value;
  19. private RadioGroup? _posRadioGroup;
  20. private TextField? _valueEdit;
  21. protected override void OnUpdateSettings ()
  22. {
  23. Enabled = ViewToEdit is not Adornment;
  24. if (ViewToEdit is null)
  25. {
  26. return;
  27. }
  28. Pos? pos;
  29. if (Dimension == Dimension.Width)
  30. {
  31. pos = ViewToEdit.X;
  32. }
  33. else
  34. {
  35. pos = ViewToEdit.Y;
  36. }
  37. try
  38. {
  39. _posRadioGroup!.SelectedItem = _posNames.IndexOf (_posNames.First (s => pos.ToString ().Contains (s)));
  40. }
  41. catch (InvalidOperationException e)
  42. {
  43. // This is a hack to work around the fact that the Pos enum doesn't have an "Align" value yet
  44. Debug.WriteLine ($"{e}");
  45. }
  46. _valueEdit!.Enabled = false;
  47. switch (pos)
  48. {
  49. case PosPercent percent:
  50. _valueEdit.Enabled = true;
  51. _value = percent.Percent;
  52. _valueEdit!.Text = _value.ToString ();
  53. break;
  54. case PosAbsolute absolute:
  55. _valueEdit.Enabled = true;
  56. _value = absolute.Position;
  57. _valueEdit!.Text = _value.ToString ();
  58. break;
  59. case PosFunc func:
  60. _valueEdit.Enabled = true;
  61. _value = func.Fn ();
  62. _valueEdit!.Text = _value.ToString ();
  63. break;
  64. default:
  65. _valueEdit!.Text = pos.ToString ();
  66. break;
  67. }
  68. }
  69. public Dimension Dimension { get; set; }
  70. private void PosEditor_Initialized (object? sender, EventArgs e)
  71. {
  72. var label = new Label
  73. {
  74. X = 0, Y = 0,
  75. Text = $"{Title}:"
  76. };
  77. Add (label);
  78. _posRadioGroup = new () { X = 0, Y = Pos.Bottom (label), RadioLabels = _radioItems };
  79. _posRadioGroup.SelectedItemChanged += OnRadioGroupOnSelectedItemChanged;
  80. _valueEdit = new ()
  81. {
  82. X = Pos.Right (label) + 1,
  83. Y = 0,
  84. Width = Dim.Func (() => _radioItems.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
  85. Text = $"{_value}"
  86. };
  87. _valueEdit.Accepting += (s, args) =>
  88. {
  89. try
  90. {
  91. _value = int.Parse (_valueEdit.Text);
  92. PosChanged ();
  93. }
  94. catch
  95. {
  96. // ignored
  97. }
  98. args.Cancel = true;
  99. };
  100. Add (_valueEdit);
  101. Add (_posRadioGroup);
  102. }
  103. private void OnRadioGroupOnSelectedItemChanged (object? s, SelectedItemChangedArgs selected) { PosChanged (); }
  104. // These need to have same order
  105. private readonly List<string> _posNames = ["Absolute", "Align", "AnchorEnd", "Center", "Func", "Percent"];
  106. private readonly string [] _radioItems = ["Absolute(n)", "Align", "AnchorEnd", "Center", "Func(()=>n)", "Percent(n)"];
  107. private void PosChanged ()
  108. {
  109. if (ViewToEdit == null || UpdatingSettings)
  110. {
  111. return;
  112. }
  113. try
  114. {
  115. Pos? pos = _posRadioGroup!.SelectedItem switch
  116. {
  117. 0 => Pos.Absolute (_value),
  118. 1 => Pos.Align (Alignment.Start),
  119. 2 => new PosAnchorEnd (),
  120. 3 => Pos.Center (),
  121. 4 => Pos.Func (() => _value),
  122. 5 => Pos.Percent (_value),
  123. _ => Dimension == Dimension.Width ? ViewToEdit.X : ViewToEdit.Y
  124. };
  125. if (Dimension == Dimension.Width)
  126. {
  127. ViewToEdit.X = pos;
  128. }
  129. else
  130. {
  131. ViewToEdit.Y = pos;
  132. }
  133. SetNeedsLayout ();
  134. }
  135. catch (Exception e)
  136. {
  137. MessageBox.ErrorQuery ("Exception", e.Message, "Ok");
  138. }
  139. }
  140. }