DFMultiSignatureControl.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. using InABox.Core;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Controls;
  7. using System.Windows.Media.Effects;
  8. using System.Windows.Media.Imaging;
  9. using System.Windows.Media;
  10. using System.Windows;
  11. using InABox.WPF;
  12. namespace InABox.DynamicGrid
  13. {
  14. public class DFMultiSignatureControl : DynamicFormFieldControl<DFLayoutMultiSignaturePad, DFLayoutMultiSignaturePadProperties, Dictionary<string, byte[]>, Dictionary<string, byte[]>?>
  15. {
  16. private Grid Grid = null!; // Late-initialised
  17. private Grid Images = null!; // Late-initialised
  18. private bool Enabled = true;
  19. static DFMultiSignatureControl()
  20. {
  21. IsEnabledProperty.OverrideMetadata(
  22. typeof(DFMultiSignatureControl),
  23. new UIPropertyMetadata(
  24. true,
  25. ControlIsEnabledChanged));
  26. }
  27. private static void ControlIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  28. {
  29. var control = (DFMultiSignatureControl)obj;
  30. control.IsEnabled = true;
  31. control.Enabled = (bool)e.NewValue;
  32. }
  33. protected override FrameworkElement Create()
  34. {
  35. Grid = new Grid();
  36. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  37. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  38. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  39. Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  40. Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
  41. var imagesScroll = new ScrollViewer
  42. {
  43. HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
  44. VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
  45. Background = new SolidColorBrush(Colors.Gray)
  46. };
  47. Images = new Grid { Height = 150 };
  48. Images.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  49. Images.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
  50. imagesScroll.Content = Images;
  51. var clearButton = new Button
  52. {
  53. Content = "Clear",
  54. Margin = new Thickness(0, 5, 0, 0),
  55. Width = 60,
  56. Height = 35
  57. };
  58. clearButton.Click += MultiSignatureClear_Click;
  59. var addButton = new Button
  60. {
  61. Content = "Add",
  62. Margin = new Thickness(0, 5, 0, 0),
  63. Width = 60,
  64. Height = 35
  65. };
  66. addButton.Click += MultiSignatureAdd_Click;
  67. imagesScroll.SetGridPosition(0, 0, 1, 3);
  68. clearButton.SetGridPosition(1, 0, 1, 1);
  69. addButton.SetGridPosition(1, 2, 1, 1);
  70. Grid.Children.Add(imagesScroll);
  71. Grid.Children.Add(clearButton);
  72. Grid.Children.Add(addButton);
  73. return Grid;
  74. }
  75. private void AddMultiSignature(BitmapSource? source, string name)
  76. {
  77. var image = new Image();
  78. if (source != null)
  79. {
  80. image.Source = source;
  81. var label = new Label
  82. {
  83. Content = name.ToUpper(),
  84. VerticalContentAlignment = VerticalAlignment.Center,
  85. VerticalAlignment = VerticalAlignment.Stretch,
  86. HorizontalContentAlignment = HorizontalAlignment.Center
  87. };
  88. var column = Images.ColumnDefinitions.Count;
  89. var menu = new ContextMenu();
  90. menu.AddItem("Remove Signature", null, image, MultiSignatureRemove_Click);
  91. image.ContextMenuOpening += (sender, args) =>
  92. {
  93. if (!Enabled) args.Handled = true;
  94. };
  95. Images.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  96. image.ContextMenu = menu;
  97. label.ContextMenu = menu;
  98. image.SetGridPosition(0, column, 1, 1);
  99. label.SetGridPosition(1, column, 1, 1);
  100. Images.Children.Add(image);
  101. Images.Children.Add(label);
  102. }
  103. }
  104. private void MultiSignatureAdd_Click(object sender, RoutedEventArgs e)
  105. {
  106. var window = new SignaturePadWindow(null, true);
  107. if (window.ShowDialog() == true)
  108. {
  109. var sigName = window.SignatureName.ToUpper().Trim();
  110. if (string.IsNullOrWhiteSpace(sigName))
  111. {
  112. MessageBox.Show("Name cannot be empty!");
  113. }
  114. else if (Images.Children.Cast<UIElement>().Any(x => x is Label lbl && (string)lbl.Content == sigName))
  115. {
  116. MessageBox.Show("A signature with that name already exists!");
  117. }
  118. else
  119. {
  120. AddMultiSignature(window.Image, window.SignatureName);
  121. ChangeField();
  122. }
  123. }
  124. }
  125. private void MultiSignatureRemove_Click(Image image)
  126. {
  127. var imageColumn = Grid.GetColumn(image);
  128. var removes = new List<UIElement>();
  129. foreach (var child in Images.Children)
  130. {
  131. if (child is UIElement el)
  132. {
  133. var column = Grid.GetColumn(el);
  134. if (column == imageColumn)
  135. removes.Add(el);
  136. else if (column > imageColumn)
  137. Grid.SetColumn(el, column - 1);
  138. }
  139. }
  140. foreach (var element in removes)
  141. {
  142. Images.Children.Remove(element);
  143. }
  144. ChangeField();
  145. }
  146. private void MultiSignatureClear_Click(object sender, RoutedEventArgs e)
  147. {
  148. if (Images.Children.Count > 0)
  149. {
  150. Images.Children.Clear();
  151. ChangeField();
  152. }
  153. }
  154. public override Dictionary<string, byte[]>? GetSerializedValue()
  155. {
  156. return GetValue();
  157. }
  158. public override void SetSerializedValue(Dictionary<string, byte[]>? value)
  159. {
  160. SetValue(value);
  161. }
  162. public override Dictionary<string, byte[]> GetValue()
  163. {
  164. var columns = Images.Children.Cast<UIElement>().GroupBy(x => Grid.GetColumn(x));
  165. var data = new Dictionary<string, byte[]>();
  166. foreach (var column in columns)
  167. {
  168. if (column.FirstOrDefault(x => x is Image) is Image image
  169. && column.FirstOrDefault(x => x is Label) is Label label)
  170. {
  171. var imgData = EmbeddedImageUtilities.SaveImageToBytes(image, false, new PngBitmapEncoder());
  172. if (imgData != null && label.Content is string str)
  173. {
  174. data.Add(str, imgData);
  175. }
  176. }
  177. }
  178. return data;
  179. }
  180. public override void SetValue(Dictionary<string, byte[]>? value)
  181. {
  182. Images.Children.Clear();
  183. if (value is IDictionary<string, byte[]> data)
  184. {
  185. foreach (var (name, imgData) in data)
  186. {
  187. AddMultiSignature(ImageUtils.BitmapImageFromBytes(imgData), name);
  188. }
  189. }
  190. }
  191. protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  192. {
  193. base.OnPropertyChanged(e);
  194. if (e.Property == IsEnabledProperty)
  195. {
  196. Grid.RowDefinitions[1].Height = (bool)e.NewValue
  197. ? GridLength.Auto
  198. : new GridLength(0);
  199. }
  200. }
  201. protected override bool IsEmpty() => Images.Children.Count == 0;
  202. }
  203. }