DimEditor.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 DimEditor : EditorBase
  8. {
  9. public DimEditor ()
  10. {
  11. Title = "Dim";
  12. Initialized += DimEditor_Initialized;
  13. }
  14. private int _value;
  15. private OptionSelector? _dimOptionSelector;
  16. private TextField? _valueEdit;
  17. /// <inheritdoc/>
  18. protected override void OnViewToEditChanged ()
  19. {
  20. if (ViewToEdit is { })
  21. {
  22. ViewToEdit.SubViewsLaidOut += (_, _) => { OnUpdateLayoutSettings (); };
  23. }
  24. }
  25. protected override void OnUpdateLayoutSettings ()
  26. {
  27. Enabled = ViewToEdit is not Adornment;
  28. if (ViewToEdit is null)
  29. {
  30. return;
  31. }
  32. Dim dim = Dimension == Dimension.Width ? ViewToEdit.Width : ViewToEdit.Height;
  33. try
  34. {
  35. _dimOptionSelector!.Value = _dimNames.IndexOf (_dimNames.First (s => dim.ToString ().StartsWith (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 (dim)
  44. {
  45. case DimAbsolute absolute:
  46. _valueEdit.Enabled = true;
  47. _value = absolute.Size;
  48. _valueEdit!.Text = _value.ToString ();
  49. break;
  50. case DimFill fill:
  51. var margin = fill.Margin as DimAbsolute;
  52. _valueEdit.Enabled = margin is { };
  53. _value = margin?.Size ?? 0;
  54. _valueEdit!.Text = _value.ToString ();
  55. break;
  56. case DimFunc func:
  57. _valueEdit.Enabled = true;
  58. _value = func.Fn (null);
  59. _valueEdit!.Text = _value.ToString ();
  60. break;
  61. case DimPercent percent:
  62. _valueEdit.Enabled = true;
  63. _value = percent.Percentage;
  64. _valueEdit!.Text = _value.ToString ();
  65. break;
  66. default:
  67. _valueEdit!.Text = dim.ToString ();
  68. break;
  69. }
  70. }
  71. public Dimension Dimension { get; set; }
  72. private void DimEditor_Initialized (object? sender, EventArgs e)
  73. {
  74. var label = new Label
  75. {
  76. X = 0, Y = 0,
  77. Text = $"{Title}:"
  78. };
  79. Add (label);
  80. _dimOptionSelector = new () { X = 0, Y = Pos.Bottom (label), Labels = _optionLabels };
  81. _dimOptionSelector.ValueChanged += OnOptionSelectorOnValueChanged;
  82. _valueEdit = new ()
  83. {
  84. X = Pos.Right (label) + 1,
  85. Y = 0,
  86. Width = Dim.Func (_ => _optionLabels.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
  87. Text = $"{_value}"
  88. };
  89. _valueEdit.Accepting += (_, args) =>
  90. {
  91. try
  92. {
  93. _value = int.Parse (_valueEdit.Text);
  94. DimChanged ();
  95. }
  96. catch
  97. {
  98. // ignored
  99. }
  100. args.Handled = true;
  101. };
  102. Add (_valueEdit);
  103. Add (_dimOptionSelector);
  104. }
  105. private void OnOptionSelectorOnValueChanged (object? s, EventArgs<int?> selected) { DimChanged (); }
  106. // These need to have same order
  107. private readonly List<string> _dimNames = ["Absolute", "Auto", "Fill", "Func", "Percent"];
  108. private readonly string [] _optionLabels = ["Absolute(n)", "Auto", "Fill(n)", "Func(()=>n)", "Percent(n)"];
  109. private void DimChanged ()
  110. {
  111. if (ViewToEdit == null || UpdatingLayoutSettings)
  112. {
  113. return;
  114. }
  115. try
  116. {
  117. Dim dim = _dimOptionSelector!.Value switch
  118. {
  119. 0 => Dim.Absolute (_value),
  120. 1 => Dim.Auto (),
  121. 2 => Dim.Fill (_value),
  122. 3 => Dim.Func (_ => _value),
  123. 4 => Dim.Percent (_value),
  124. _ => Dimension == Dimension.Width ? ViewToEdit.Width : ViewToEdit.Height
  125. };
  126. if (Dimension == Dimension.Width)
  127. {
  128. ViewToEdit.Width = dim;
  129. }
  130. else
  131. {
  132. ViewToEdit.Height = dim;
  133. }
  134. }
  135. catch (Exception e)
  136. {
  137. MessageBox.ErrorQuery (App, "Exception", e.Message, "Ok");
  138. }
  139. }
  140. }