DigitalFormEmbeddedMedia.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Text.RegularExpressions;
  5. using System.Threading.Tasks;
  6. using InABox.Core;
  7. using InABox.Mobile;
  8. using Xamarin.CommunityToolkit.Converters;
  9. using Xamarin.Forms;
  10. namespace PRS.Mobile
  11. {
  12. public abstract class DigitalFormEmbeddedMedia<T, TProperties> : Grid, IDigitalFormField<T,TProperties, DFLayoutEmbeddedMediaValue>
  13. where T : DFLayoutField<TProperties>, new()
  14. where TProperties : DFLayoutFieldProperties<DFLayoutEmbeddedMediaValue>, new()
  15. {
  16. protected abstract bool IsVideo { get; }
  17. private readonly MobileCard _card;
  18. private readonly Image _image;
  19. private readonly MobileButton _cameraButton;
  20. private readonly MobileButton _libraryButton;
  21. private readonly MobileButton _clearButton;
  22. private T _definition;
  23. public T Definition
  24. {
  25. get => _definition;
  26. set
  27. {
  28. _definition = value;
  29. Initialize(value ?? new T());
  30. }
  31. }
  32. private DFLayoutEmbeddedMediaValue _value = new();
  33. public DFLayoutEmbeddedMediaValue Value
  34. {
  35. get => _value;
  36. set
  37. {
  38. _value = value;
  39. UpdateUI();
  40. }
  41. }
  42. protected abstract byte[] CreateThumbnail(byte[] data, float maxwidth = 200, float maxheight = 200);
  43. private void UpdateUI()
  44. {
  45. if ((_value?.Thumbnail?.Any() == false) && (_value?.Data?.Any() != true))
  46. _value.Thumbnail = CreateThumbnail(_value.Data);
  47. _image.Source = _value?.Thumbnail?.Any() == true
  48. ? ImageSource.FromStream(() => new MemoryStream(_value.Thumbnail))
  49. : null;
  50. }
  51. public bool IsEmpty => Value.Data?.Any() != true;
  52. private bool _readOnly;
  53. public bool ReadOnly
  54. {
  55. get => _readOnly;
  56. set
  57. {
  58. _readOnly = value;
  59. UpdateStatus();
  60. }
  61. }
  62. public void Deserialize(string serialized)
  63. {
  64. _value.Load(serialized);
  65. UpdateUI();
  66. }
  67. public string Serialize()
  68. {
  69. if (_value == null)
  70. return new DFLayoutEmbeddedMediaValue().ToString();
  71. if ((_value.Data?.Any() == true) && (_value.ID == Guid.Empty))
  72. _value.ID = DigitalFormDocumentFactory.SaveDocument(_value.Data);
  73. return _value?.ToString() ?? "";
  74. }
  75. public event DigitalFormViewChangedHandler ValueChanged;
  76. protected DigitalFormEmbeddedMedia()
  77. {
  78. HeightRequest = 250;
  79. ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  80. ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
  81. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
  82. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
  83. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
  84. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
  85. _card = new MobileCard()
  86. {
  87. Padding = 5
  88. };
  89. SetRow(_card, 0);
  90. SetColumn(_card, 0);
  91. SetRowSpan(_card, 4);
  92. Children.Add(_card);
  93. _image = new Image()
  94. {
  95. Aspect = Aspect.AspectFit
  96. };
  97. _image.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(Image_Tapped) });
  98. _card.Content = _image;
  99. _cameraButton = new MobileButton
  100. {
  101. Image = "camera",
  102. ImageSize = new Size(25, 25),
  103. Orientation = StackOrientation.Vertical,
  104. CornerRadius = 5,
  105. WidthRequest = 40,
  106. HeightRequest = 40,
  107. };
  108. SetRow(_cameraButton, 0);
  109. SetColumn(_cameraButton, 1);
  110. _cameraButton.Clicked += CameraButton_Clicked;
  111. Children.Add(_cameraButton);
  112. _libraryButton = new MobileButton
  113. {
  114. Image = "gallery",
  115. ImageSize = new Size(25, 25),
  116. Orientation = StackOrientation.Vertical,
  117. CornerRadius = 5,
  118. WidthRequest = 40,
  119. HeightRequest = 40,
  120. };
  121. SetRow(_libraryButton, 1);
  122. SetColumn(_libraryButton, 1);
  123. _libraryButton.Clicked += LibraryButton_Clicked;
  124. Children.Add(_libraryButton);
  125. _clearButton = new MobileButton
  126. {
  127. Image = "cross",
  128. ImageSize = new Size(25, 25),
  129. Orientation = StackOrientation.Vertical,
  130. CornerRadius = 5,
  131. WidthRequest = 40,
  132. HeightRequest = 40,
  133. };
  134. SetRow(_clearButton, 3);
  135. SetColumn(_clearButton, 1);
  136. _clearButton.Clicked += ClearButton_Clicked;
  137. Children.Add(_clearButton);
  138. }
  139. private void Image_Tapped()
  140. {
  141. if (_value == null)
  142. return;
  143. if (_value.Data?.Any() == true)
  144. Navigation.PushAsync(new ImageViewerPage(_value.Data));
  145. else
  146. {
  147. if (_value.ID != Guid.Empty)
  148. {
  149. DigitalFormDocumentFactory.LoadDocument(
  150. _value.ID,
  151. data =>
  152. {
  153. Device.BeginInvokeOnMainThread(() =>
  154. {
  155. _value.Data = data;
  156. Navigation.PushAsync(new ImageViewerPage(data));
  157. });
  158. }
  159. );
  160. }
  161. }
  162. }
  163. private void ClearButton_Clicked(object sender, MobileButtonClickEventArgs args)
  164. {
  165. _value.ID = Guid.Empty;
  166. _value.Thumbnail = null;
  167. _value.Data = null;
  168. UpdateUI();
  169. }
  170. protected abstract Task<MobileDocument> CaptureMedia();
  171. protected abstract Task<MobileDocument> SelectMedia();
  172. private async void CameraButton_Clicked(object sender, MobileButtonClickEventArgs args)
  173. {
  174. var doc = await CaptureMedia();
  175. if (doc != null)
  176. {
  177. _value.ID = Guid.Empty;
  178. _value.Thumbnail = CreateThumbnail(doc.Data);
  179. _value.Data = doc.Data;
  180. }
  181. Device.BeginInvokeOnMainThread(UpdateUI);
  182. }
  183. private async void LibraryButton_Clicked(object sender, MobileButtonClickEventArgs args)
  184. {
  185. var doc = await SelectMedia();
  186. if (doc != null)
  187. {
  188. _value.ID = Guid.Empty;
  189. _value.Thumbnail = CreateThumbnail(doc.Data);
  190. _value.Data = doc.Data;
  191. }
  192. Device.BeginInvokeOnMainThread(UpdateUI);
  193. }
  194. private void Initialize(T definition)
  195. {
  196. UpdateStatus();
  197. }
  198. protected abstract bool DisableLibrary { get; }
  199. protected abstract bool Secure { get; }
  200. protected abstract bool Required { get; }
  201. private void UpdateStatus()
  202. {
  203. _cameraButton.Image = IsVideo ? ImageSource.FromFile("camcorder") : ImageSource.FromFile("camera");
  204. _libraryButton.Image = IsVideo ? ImageSource.FromFile("videolibrary") : ImageSource.FromFile("photolibrary");
  205. _libraryButton.IsEnabled = !DisableLibrary;
  206. bool enabled = !_readOnly && !Secure;
  207. _cameraButton.IsEnabled = enabled;
  208. _libraryButton.IsEnabled = enabled && !DisableLibrary;
  209. var colors = DigitalFormUtils.GetColors(!enabled, Required, false);
  210. _card.BackgroundColor = colors.Background;
  211. _card.BorderColor = colors.Border;
  212. colors = DigitalFormUtils.GetColors(!enabled, Required, true);
  213. _cameraButton.BackgroundColor = colors.Background;
  214. _cameraButton.BorderColor = colors.Border;
  215. _libraryButton.BackgroundColor = colors.Background;
  216. _libraryButton.BorderColor = colors.Border;
  217. _clearButton.BackgroundColor = colors.Background;
  218. _clearButton.BorderColor = colors.Border;
  219. }
  220. }
  221. }