SignaturePad.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using System;
  2. using System.Threading.Tasks;
  3. using Xamarin.Forms;
  4. using System.IO;
  5. using Syncfusion.XForms.SignaturePad;
  6. using comal.timesheets.CustomControls;
  7. namespace comal.timesheets
  8. {
  9. public delegate void NameAdded(string s);
  10. public delegate void NameRemoved(string s);
  11. class SignaturePad : Frame
  12. {
  13. private SfSignaturePad Pad = new SfSignaturePad();
  14. public string Name = "";
  15. public string Data = "";
  16. public bool StrokeAdded = false;
  17. public event NameAdded OnNameAdded;
  18. public event NameRemoved OnNameRemoved;
  19. private Entry entry = new Entry();
  20. Grid SignatureGrid = new Grid() { Margin = 0, Padding = 0 };
  21. EmbeddedImageCapture hiddenEmbeddedImageCapture = new EmbeddedImageCapture() { HeightRequest = 180, IsVisible = false, IsEnabled = false };
  22. public SignaturePad()
  23. {
  24. Padding = 4;
  25. Pad = new SfSignaturePad();
  26. Pad.BackgroundColor = Color.White;
  27. Pad.MinimumHeightRequest = 200;
  28. Pad.MinimumStrokeWidth = 0.2;
  29. Pad.MaximumStrokeWidth = 17;
  30. Pad.StrokeCompleted += Pad_StrokeCompleted;
  31. entry = new Entry
  32. {
  33. Placeholder = "Add Name",
  34. HorizontalOptions = LayoutOptions.FillAndExpand,
  35. Margin = new Thickness(1, 1, 0, 1),
  36. BackgroundColor = Color.White,
  37. VerticalOptions = LayoutOptions.Center
  38. };
  39. entry.TextChanged += (object sender, TextChangedEventArgs e) =>
  40. {
  41. entry.Text = entry.Text.ToUpper().Trim();
  42. Name = entry.Text;
  43. };
  44. Button lookupButton = new Button()
  45. {
  46. Text = "...",
  47. VerticalOptions = LayoutOptions.Center,
  48. FontAttributes = FontAttributes.Bold,
  49. CornerRadius = 5,
  50. Padding = 1,
  51. Margin = new Thickness(0, 1, 0, 1),
  52. };
  53. lookupButton.Clicked += (object sender, EventArgs e) =>
  54. {
  55. EmployeeSelectionPage page = new EmployeeSelectionPage();
  56. page.OnItemSelected += () =>
  57. {
  58. entry.Text = page.employee.Name.ToUpper();
  59. OnNameAdded?.Invoke(entry.Text);
  60. };
  61. Navigation.PushAsync(page);
  62. };
  63. Button clearButton = new Button()
  64. {
  65. Text = "Clear",
  66. HorizontalOptions = LayoutOptions.FillAndExpand,
  67. VerticalOptions = LayoutOptions.End,
  68. Margin = new Thickness(0, 1, 1, 1),
  69. BackgroundColor = Color.FromHex("#15C7C1"),
  70. FontAttributes = FontAttributes.Bold,
  71. TextColor = Color.White,
  72. CornerRadius = 5,
  73. Padding = 1
  74. };
  75. clearButton.Clicked += (object sender, EventArgs e) =>
  76. {
  77. Pad.Clear();
  78. hiddenEmbeddedImageCapture.ClearItems();
  79. hiddenEmbeddedImageCapture.IsVisible = false;
  80. Pad.IsVisible = true;
  81. ClearName();
  82. Data = "";
  83. StrokeAdded = false;
  84. };
  85. Grid.SetColumn(entry, 0);
  86. Grid.SetColumn(lookupButton, 1);
  87. Grid.SetColumn(clearButton, 2);
  88. Grid buttonsGrid = new Grid { Margin = 0, Padding = 0, VerticalOptions = LayoutOptions.End };
  89. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) });
  90. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(35, GridUnitType.Absolute) });
  91. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  92. buttonsGrid.Children.Add(entry);
  93. buttonsGrid.Children.Add(lookupButton);
  94. buttonsGrid.Children.Add(clearButton);
  95. SignatureGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(200, GridUnitType.Absolute) });
  96. Grid.SetRow(Pad, 0);
  97. Grid.SetRow(hiddenEmbeddedImageCapture, 0);
  98. SignatureGrid.Children.Add(hiddenEmbeddedImageCapture);
  99. SignatureGrid.Children.Add(Pad);
  100. SignatureGrid.Children.Add(buttonsGrid);
  101. CornerRadius = 10;
  102. BorderColor = Color.FromHex("#15C7C1");
  103. Content = SignatureGrid;
  104. }
  105. private void Pad_StrokeCompleted(object sender, EventArgs e)
  106. {
  107. StrokeAdded = true;
  108. }
  109. public void ClearName()
  110. {
  111. OnNameRemoved?.Invoke(entry.Text);
  112. entry.Text = "";
  113. }
  114. public void SaveSignature()
  115. {
  116. if (Data == null || string.IsNullOrWhiteSpace(Data))
  117. {
  118. Pad.Save();
  119. if (Pad.ImageSource != null)
  120. {
  121. Data = ImageSourceToBase64(Pad.ImageSource);
  122. }
  123. }
  124. }
  125. public void PopulateSignature(byte[] data)
  126. {
  127. Pad.IsVisible = false;
  128. hiddenEmbeddedImageCapture.IsVisible = true;
  129. hiddenEmbeddedImageCapture.DataToImage(data);
  130. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  131. Data = ImageSourceToBase64(src);
  132. StrokeAdded = true;
  133. }
  134. public void PopulateName(string s)
  135. {
  136. entry.Text = s;
  137. }
  138. private string ImageSourceToBase64(ImageSource source)
  139. {
  140. StreamImageSource streamImageSource = (StreamImageSource)source;
  141. System.Threading.CancellationToken cancellationToken = System.Threading.CancellationToken.None;
  142. Task<Stream> task = streamImageSource.Stream(cancellationToken);
  143. Stream stream = task.Result;
  144. byte[] bytes = new byte[stream.Length];
  145. stream.Read(bytes, 0, bytes.Length);
  146. string s = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
  147. return s;
  148. }
  149. }
  150. }