DFOptionControl.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using InABox.Core;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Media;
  10. namespace InABox.DynamicGrid
  11. {
  12. public interface IOptionControl
  13. {
  14. public string? GetValue();
  15. public void SetValue(string value);
  16. public bool IsEmpty();
  17. }
  18. public class ButtonsOptionControl : Grid, IOptionControl
  19. {
  20. private Action OnChanged;
  21. private class OptionButton : Border
  22. {
  23. public string Option { get; set; }
  24. private bool _selected { get; set; }
  25. public bool Selected
  26. {
  27. get => _selected;
  28. set
  29. {
  30. _selected = value;
  31. if (value == true)
  32. {
  33. Background = new SolidColorBrush(Colors.LightGray);
  34. }
  35. else if (value == false)
  36. {
  37. Background = new SolidColorBrush(Colors.DarkGray);
  38. }
  39. }
  40. }
  41. public OptionButton(string option, bool selected)
  42. {
  43. Option = option;
  44. Selected = selected;
  45. }
  46. }
  47. public ButtonsOptionControl(string[] options, Action onChanged)
  48. {
  49. OnChanged = onChanged;
  50. foreach (var option in options)
  51. {
  52. ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  53. var button = new OptionButton(option, false);
  54. var label = new Label()
  55. {
  56. Content = option.Replace("\r", "").Replace("\n", "")
  57. };
  58. label.HorizontalContentAlignment = HorizontalAlignment.Center;
  59. label.VerticalContentAlignment = VerticalAlignment.Center;
  60. button.Child = label;
  61. button.Margin = new Thickness(
  62. Children.Count == 0 ? 0.0F : 2.5F,
  63. 0.0F,
  64. Children.Count == options.Length - 1 ? 0.0F : 2.5F,
  65. 0.0F
  66. );
  67. button.Padding = new Thickness(5.0F, 0.0F, 5.0F, 0.0F);
  68. button.MouseUp += Button_MouseUp;
  69. button.SetValue(ColumnProperty, Children.Count);
  70. Children.Add(button);
  71. }
  72. }
  73. private void Button_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
  74. {
  75. SelectButton((OptionButton)sender);
  76. OnChanged();
  77. }
  78. private void SelectButton(OptionButton button)
  79. {
  80. foreach (var child in Children)
  81. {
  82. if (child is OptionButton childButton && childButton != button)
  83. {
  84. childButton.Selected = false;
  85. }
  86. }
  87. button.Selected = true;
  88. }
  89. public string? GetValue()
  90. {
  91. foreach (var child in Children)
  92. {
  93. if (child is OptionButton button)
  94. {
  95. if (button.Selected)
  96. {
  97. return button.Option;
  98. }
  99. }
  100. }
  101. return null;
  102. }
  103. public void SetValue(string value)
  104. {
  105. foreach (var child in Children)
  106. {
  107. if (child is OptionButton button)
  108. {
  109. if (button.Option == value)
  110. {
  111. SelectButton(button);
  112. }
  113. }
  114. }
  115. }
  116. public bool IsEmpty() => GetValue() == null;
  117. }
  118. public class RadioOptionControl : Grid, IOptionControl
  119. {
  120. private Action OnChanged;
  121. public RadioOptionControl(string[] options, Action onChanged)
  122. {
  123. OnChanged = onChanged;
  124. foreach (var option in options)
  125. {
  126. ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  127. var button = new RadioButton();
  128. button.Content = option.Replace("\r", "").Replace("\n", "");
  129. button.Margin = new Thickness(
  130. Children.Count == 0 ? 0.0F : 2.5F,
  131. 0.0F,
  132. Children.Count == options.Length - 1 ? 0.0F : 2.5F,
  133. 0.0F
  134. );
  135. button.VerticalContentAlignment = VerticalAlignment.Center;
  136. button.Padding = new Thickness(5.0F, 0.0F, 5.0F, 0.0F);
  137. button.SetValue(ColumnProperty, Children.Count);
  138. button.Tag = option;
  139. button.Checked += Button_Checked;
  140. button.Unchecked += Button_Checked;
  141. Children.Add(button);
  142. }
  143. }
  144. private void Button_Checked(object sender, RoutedEventArgs e)
  145. {
  146. OnChanged();
  147. }
  148. public string? GetValue()
  149. {
  150. foreach (var child in Children)
  151. {
  152. if (child is RadioButton radio)
  153. {
  154. if (radio.IsChecked == true)
  155. {
  156. return radio.Tag as string;
  157. }
  158. }
  159. }
  160. return null;
  161. }
  162. public void SetValue(string value)
  163. {
  164. foreach (var child in Children)
  165. {
  166. if (child is RadioButton radio)
  167. {
  168. if ((string)radio.Tag == value)
  169. {
  170. radio.IsChecked = true;
  171. }
  172. }
  173. }
  174. }
  175. public bool IsEmpty() => GetValue() == null;
  176. }
  177. public class ComboBoxOptionControl : ComboBox, IOptionControl
  178. {
  179. private readonly Action OnChanged;
  180. public ComboBoxOptionControl(string[] options, Action onChanged)
  181. {
  182. SetResourceReference(StyleProperty, typeof(ComboBox));
  183. OnChanged = onChanged;
  184. foreach (var option in options)
  185. Items.Add(option);
  186. VerticalContentAlignment = VerticalAlignment.Center;
  187. SelectionChanged += ComboBoxOptionControl_SelectionChanged;
  188. }
  189. private void ComboBoxOptionControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
  190. {
  191. OnChanged();
  192. }
  193. public string? GetValue()
  194. {
  195. return SelectedValue as string;
  196. }
  197. public void SetValue(string value)
  198. {
  199. SelectedValue = value;
  200. }
  201. public bool IsEmpty() => GetValue() == null;
  202. }
  203. public class CheckBoxOptionControl : CheckBox, IOptionControl
  204. {
  205. private readonly Action OnChanged;
  206. private readonly string TrueValue;
  207. private readonly string FalseValue;
  208. public CheckBoxOptionControl(string trueValue, string falseValue, Action onChanged)
  209. {
  210. OnChanged = onChanged;
  211. TrueValue = trueValue;
  212. FalseValue = falseValue;
  213. IsThreeState = false;
  214. HorizontalContentAlignment = HorizontalAlignment.Center;
  215. VerticalContentAlignment = VerticalAlignment.Center;
  216. Checked += CheckBoxOptionControl_Checked;
  217. Unchecked += CheckBoxOptionControl_Checked;
  218. }
  219. private void CheckBoxOptionControl_Checked(object sender, RoutedEventArgs e)
  220. {
  221. OnChanged();
  222. }
  223. public string? GetValue()
  224. {
  225. return IsChecked == true
  226. ? TrueValue
  227. : FalseValue;
  228. }
  229. public void SetValue(string value)
  230. {
  231. IsChecked = value == TrueValue;
  232. }
  233. public bool IsEmpty() => false;
  234. }
  235. public class DFOptionControl : DynamicFormFieldControl<DFLayoutOptionField, DFLayoutOptionFieldProperties, string>
  236. {
  237. private IOptionControl OptionControl = null!; // Late-initialised
  238. protected override FrameworkElement Create()
  239. {
  240. var options = string.IsNullOrWhiteSpace(Field.Properties.Options) ? new string[] { } : Field.Properties.Options.Split(',');
  241. switch (Field.Properties.OptionType)
  242. {
  243. case DFLayoutOptionType.Buttons:
  244. return SetControl(new ButtonsOptionControl(options, ChangeField));
  245. case DFLayoutOptionType.Radio:
  246. return SetControl(new RadioOptionControl(options, ChangeField));
  247. }
  248. return SetControl(new ComboBoxOptionControl(options, ChangeField));
  249. }
  250. private T SetControl<T>(T value)
  251. where T : FrameworkElement, IOptionControl
  252. {
  253. OptionControl = value;
  254. return value;
  255. }
  256. public override string GetValue() => OptionControl.GetValue() ?? "";
  257. public override void SetValue(string? value) => OptionControl.SetValue(value ?? "");
  258. protected override bool IsEmpty() => OptionControl.IsEmpty();
  259. }
  260. }