فهرست منبع

avalonia: Added Multi-signature pad

Kenric Nugteren 2 ماه پیش
والد
کامیت
2ecce26145

+ 2 - 4
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/Fields/DFMultiImageFieldControl.cs

@@ -77,16 +77,14 @@ internal partial class DFMultiImageFieldControl : DigitalFormFieldControl<DFLayo
         {
             HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
             VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
-            Background = new SolidColorBrush(Colors.Gray)
+            Content = images
         };
 
-        imagesScroll.Content = images;
-
         Border = new Border
         {
+            Child = imagesScroll
         };
         Border.Classes.Add("Standard");
-        Border.Child = imagesScroll;
 
         var cameraButton = new Button
         {

+ 264 - 0
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/Fields/DFMultiSignatureFieldControl.cs

@@ -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;
+    }
+}

+ 21 - 0
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/Fields/DFSignaturePadEditorView.axaml

@@ -0,0 +1,21 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:components="using:InABox.Avalonia.Components"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:forms="using:PRS.Avalonia.DigitalForms"
+             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+             x:Class="PRS.Avalonia.DigitalForms.DFSignaturePadEditorView"
+             x:DataType="forms:DFSignaturePadEditorViewModel">
+    <Grid RowDefinitions="200,Auto"
+          ColumnDefinitions="*,Auto">
+        <components:InkCanvas Name="Canvas" Grid.Row="0" Grid.ColumnSpan="2"/>
+        <TextBox Grid.Row="1" Grid.Column="0"
+                 Watermark="Name"
+                 Text="{Binding SignatureName}"/>
+        <Button Classes="Standard"
+                Grid.Row="1" Grid.Column="1">
+            <Image Classes="Small" Source="{SvgImage /Images/cross.svg}"/>
+        </Button>
+    </Grid>
+</UserControl>

+ 31 - 0
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/Fields/DFSignaturePadEditorView.axaml.cs

@@ -0,0 +1,31 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using System;
+
+namespace PRS.Avalonia.DigitalForms;
+
+public partial class DFSignaturePadEditorView : UserControl
+{
+    public DFSignaturePadEditorView()
+    {
+        InitializeComponent();
+    }
+
+    protected override void OnDataContextChanged(EventArgs e)
+    {
+        base.OnDataContextChanged(e);
+
+        if(DataContext is not DFSignaturePadEditorViewModel model)
+        {
+            return;
+        }
+
+        model.GetImage = GetImage;
+    }
+
+    private byte[]? GetImage()
+    {
+        return Canvas.SaveImage();
+    }
+}

+ 47 - 0
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/Fields/DFSignaturePadEditorViewModel.cs

@@ -0,0 +1,47 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using InABox.Avalonia;
+using PRS.Avalonia.Modules;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PRS.Avalonia.DigitalForms;
+
+internal partial class DFSignaturePadEditorViewModel : ModuleViewModel
+{
+    public override string Title => "Edit Signature";
+
+    [ObservableProperty]
+    private string _signatureName = "";
+
+    [ObservableProperty]
+    private Func<string, Task<bool>>? _validateName;
+
+    [ObservableProperty]
+    private Action<string, byte[]?>? _signatureSaved;
+
+    [ObservableProperty]
+    private Func<byte[]?>? _getImage;
+
+    public DFSignaturePadEditorViewModel()
+    {
+        PrimaryMenu.Add(new(Images.tick, Save));
+    }
+
+    private async Task<bool> Save()
+    {
+        if(ValidateName is not null)
+        {
+            if(!await ValidateName(SignatureName))
+            {
+                return true;
+            }
+        }
+        Navigation.Back();
+        var image = GetImage?.Invoke();
+        SignatureSaved?.Invoke(SignatureName, image);
+        return true;
+    }
+}

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeViewModel.cs

@@ -410,7 +410,7 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
     }
 
     [RelayCommand]
-    private async void AddNote()
+    private async Task AddNote()
     {
         await GetBatch();