PosEditor.cs 4.6 KB

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