|
|
@@ -0,0 +1,264 @@
|
|
|
+using Avalonia;
|
|
|
+using Avalonia.Controls;
|
|
|
+using Avalonia.Controls.Primitives;
|
|
|
+using Avalonia.Controls.Templates;
|
|
|
+using Avalonia.Layout;
|
|
|
+using Avalonia.Media;
|
|
|
+using Comal.Classes.SecurityDescriptors;
|
|
|
+using CommunityToolkit.Mvvm.Input;
|
|
|
+using InABox.Avalonia;
|
|
|
+using InABox.Avalonia.Converters;
|
|
|
+using InABox.Avalonia.Dialogs;
|
|
|
+using InABox.Core;
|
|
|
+using ReactiveUI;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Reactive.Linq;
|
|
|
+using System.Reactive.Subjects;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace PRS.Avalonia.DigitalForms;
|
|
|
+
|
|
|
+internal partial class DFMultiSignatureFieldControl : DigitalFormFieldControl<DFLayoutMultiSignaturePad, DFLayoutMultiSignaturePadProperties, Dictionary<string, byte[]>, Dictionary<string, byte[]>?>
|
|
|
+{
|
|
|
+ private Grid Grid = null!; // Late-initialised
|
|
|
+ private ColumnDefinition ButtonColumn = null!;
|
|
|
+ private Border Border = null!; // Late-initialised
|
|
|
+ private bool _isEnabled = true;
|
|
|
+
|
|
|
+ private Dictionary<string, byte[]> _value = new();
|
|
|
+ private Subject<IEnumerable<KeyValuePair<string, byte[]>>> _items = new();
|
|
|
+
|
|
|
+ protected override Control Create()
|
|
|
+ {
|
|
|
+ Grid = new Grid();
|
|
|
+ Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
|
|
|
+ ButtonColumn = new ColumnDefinition { Width = GridLength.Auto };
|
|
|
+ Grid.ColumnDefinitions.Add(ButtonColumn);
|
|
|
+
|
|
|
+ Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
|
|
+ Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
|
|
+ Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
|
|
|
+ Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
|
|
+
|
|
|
+ var images = new ItemsControl
|
|
|
+ {
|
|
|
+ ItemsPanel = new FuncTemplate<Panel?>(() => new StackPanel
|
|
|
+ {
|
|
|
+ Orientation = Orientation.Horizontal
|
|
|
+ }),
|
|
|
+ ItemTemplate = new FuncDataTemplate<KeyValuePair<string, byte[]>>((value, namescope) =>
|
|
|
+ {
|
|
|
+ var grid = new Grid();
|
|
|
+ grid.AddRow(GridUnitType.Star);
|
|
|
+ grid.AddRow(GridUnitType.Auto);
|
|
|
+
|
|
|
+ grid.AddColumn(GridUnitType.Star);
|
|
|
+ grid.AddColumn(GridUnitType.Auto);
|
|
|
+
|
|
|
+ var image = new Image
|
|
|
+ {
|
|
|
+ Width = 200,
|
|
|
+ Source = ByteArrayToImageSourceConverter.Instance.Convert(value.Value),
|
|
|
+ Margin = new(10)
|
|
|
+ };
|
|
|
+
|
|
|
+ var label = new Label
|
|
|
+ {
|
|
|
+ Content = value.Key,
|
|
|
+ HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
|
+ HorizontalContentAlignment = HorizontalAlignment.Center
|
|
|
+ };
|
|
|
+
|
|
|
+ var button = new Button
|
|
|
+ {
|
|
|
+ Content = new Image
|
|
|
+ {
|
|
|
+ Source = Images.cross
|
|
|
+ }.WithClass("Small"),
|
|
|
+ CommandParameter = value.Key,
|
|
|
+ Command = DeleteSignatureCommand
|
|
|
+ };
|
|
|
+ button.Classes.Add("Standard");
|
|
|
+
|
|
|
+ grid.AddChild(image, 0, 0, colSpan: 2);
|
|
|
+ grid.AddChild(label, 1, 0);
|
|
|
+ grid.AddChild(button, 1, 1);
|
|
|
+
|
|
|
+ var border = new Border();
|
|
|
+ border.Classes.Add("Standard");
|
|
|
+ border.Child = grid;
|
|
|
+ border.Background = new SolidColorBrush(Colors.White);
|
|
|
+ return border;
|
|
|
+ }),
|
|
|
+ [!ItemsControl.ItemsSourceProperty] = _items.Select(x => x.ToArray()).ToBinding()
|
|
|
+ };
|
|
|
+ _items.OnNext(_value);
|
|
|
+
|
|
|
+ var imagesScroll = new ScrollViewer
|
|
|
+ {
|
|
|
+ HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
|
|
|
+ VerticalScrollBarVisibility = ScrollBarVisibility.Disabled
|
|
|
+ };
|
|
|
+
|
|
|
+ imagesScroll.Content = images;
|
|
|
+
|
|
|
+ Border = new Border
|
|
|
+ {
|
|
|
+ };
|
|
|
+ Border.Classes.Add("Standard");
|
|
|
+ Border.Child = imagesScroll;
|
|
|
+
|
|
|
+ var addButton = new Button
|
|
|
+ {
|
|
|
+ Content = new Image
|
|
|
+ {
|
|
|
+ Source = Images.plus,
|
|
|
+ Width = 25,
|
|
|
+ Height = 25,
|
|
|
+ },
|
|
|
+ Command = AddCommand
|
|
|
+ };
|
|
|
+ addButton.Classes.Add("Standard");
|
|
|
+
|
|
|
+ var selectButton = new Button
|
|
|
+ {
|
|
|
+ Content = new Image
|
|
|
+ {
|
|
|
+ Source = Images.photolibrary,
|
|
|
+ Width = 25,
|
|
|
+ Height = 25,
|
|
|
+ },
|
|
|
+ Command = SelectCommand
|
|
|
+ };
|
|
|
+ selectButton.Classes.Add("Standard");
|
|
|
+
|
|
|
+ var clearButton = new Button
|
|
|
+ {
|
|
|
+ Content = new Image
|
|
|
+ {
|
|
|
+ Source = Images.cross,
|
|
|
+ Width = 25,
|
|
|
+ Height = 25,
|
|
|
+ },
|
|
|
+ Command = ClearCommand
|
|
|
+ };
|
|
|
+ clearButton.Classes.Add("Standard");
|
|
|
+
|
|
|
+ Grid.AddChild(Border, 0, 0, rowSpan: 4);
|
|
|
+ Grid.AddChild(addButton, 0, 1);
|
|
|
+ Grid.AddChild(selectButton, 1, 1);
|
|
|
+ Grid.AddChild(clearButton, 3, 1);
|
|
|
+
|
|
|
+ return Grid;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Update()
|
|
|
+ {
|
|
|
+ _items.OnNext(_value);
|
|
|
+ }
|
|
|
+
|
|
|
+ [RelayCommand]
|
|
|
+ private void Add()
|
|
|
+ {
|
|
|
+ Navigation.Navigate<DFSignaturePadEditorViewModel>(model =>
|
|
|
+ {
|
|
|
+ model.ValidateName = ValidateName;
|
|
|
+ model.SignatureSaved = SignatureSaved;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SignatureSaved(string name, byte[]? signature)
|
|
|
+ {
|
|
|
+ if (signature is null) return;
|
|
|
+
|
|
|
+ _value.Add(name.ToUpper(), signature);
|
|
|
+ Update();
|
|
|
+ ChangeField();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<bool> ValidateName(string name)
|
|
|
+ {
|
|
|
+ if (name.IsNullOrWhiteSpace())
|
|
|
+ {
|
|
|
+ await MessageDialog.ShowMessage("Name must not be empty.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else if (_value.ContainsKey(name.ToUpper()))
|
|
|
+ {
|
|
|
+ await MessageDialog.ShowMessage("This name has already been added.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [RelayCommand]
|
|
|
+ private void Select()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ [RelayCommand]
|
|
|
+ private void Clear()
|
|
|
+ {
|
|
|
+ _value.Clear();
|
|
|
+ Update();
|
|
|
+ ChangeField();
|
|
|
+ }
|
|
|
+
|
|
|
+ [RelayCommand]
|
|
|
+ private void DeleteSignature(string key)
|
|
|
+ {
|
|
|
+ _value.Remove(key);
|
|
|
+ Update();
|
|
|
+ ChangeField();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override Dictionary<string, byte[]>? GetSerializedValue()
|
|
|
+ {
|
|
|
+ return _value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override Dictionary<string, byte[]> GetValue()
|
|
|
+ {
|
|
|
+ return _value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void SetSerializedValue(Dictionary<string, byte[]>? value)
|
|
|
+ {
|
|
|
+ _value.Clear();
|
|
|
+ if(value is not null)
|
|
|
+ {
|
|
|
+ _value.AddRange(value);
|
|
|
+ }
|
|
|
+ Update();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void SetValue(Dictionary<string, byte[]>? value)
|
|
|
+ {
|
|
|
+ SetSerializedValue(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override bool IsEmpty() => _value.Count == 0;
|
|
|
+
|
|
|
+ public override void SetBackground(IBrush brush, bool defaultColour)
|
|
|
+ {
|
|
|
+ Border.Background = brush;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void SetEnabled(bool enabled)
|
|
|
+ {
|
|
|
+ ButtonColumn.Width = enabled ? GridLength.Auto : new(0);
|
|
|
+ _isEnabled = enabled;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool GetEnabled()
|
|
|
+ {
|
|
|
+ return _isEnabled;
|
|
|
+ }
|
|
|
+}
|