PosEditor.cs 4.6 KB

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