DigitalFormEmbeddedMedia.cs 11 KB

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