using InABox.Core; using InABox.WPF; using NPOI.HPSF; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; namespace InABox.DynamicGrid { public class DFMultiImageControl : DynamicFormFieldControl, DFLayoutEmbeddedMediaValues> { private DFLayoutEmbeddedMediaValues _value = null!; private Grid Grid = null!; // Late-initialised private StackPanel Images = null!; // Late-initialised private bool Enabled = true; static DFMultiImageControl() { IsEnabledProperty.OverrideMetadata( typeof(DFMultiImageControl), new UIPropertyMetadata( true, ControlIsEnabledChanged)); } private static void ControlIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { var control = (DFMultiImageControl)obj; control.IsEnabled = true; control.Enabled = (bool)e.NewValue; } protected override FrameworkElement Create() { _value = new DFLayoutEmbeddedMediaValues(); Grid = new Grid(); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); var imagesScroll = new ScrollViewer { HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, VerticalScrollBarVisibility = ScrollBarVisibility.Disabled, Background = new SolidColorBrush(Colors.Gray) }; Images = new StackPanel { Orientation = Orientation.Horizontal, Height = 200 }; imagesScroll.Content = Images; var clearButton = new Button { Content = "Clear", Margin = new Thickness(0, 5, 0, 0), Width = 60, Height = 35 }; clearButton.Click += MultiImageClear_Click; var addButton = new Button { Content = "Add", Margin = new Thickness(0, 5, 0, 0), Width = 60, Height = 35 }; addButton.Click += MultiImageAdd_Click; imagesScroll.SetGridPosition(0, 0, 1, 3); clearButton.SetGridPosition(1, 0, 1, 1); addButton.SetGridPosition(1, 2, 1, 1); Grid.Children.Add(imagesScroll); Grid.Children.Add(clearButton); Grid.Children.Add(addButton); return Grid; } private void AddMultiImage(DFLayoutEmbeddedMediaValue value)// byte[]? data) { _value.Add(value); value.Thumbnail ??= value.Data != null ? ImageUtils.BitmapImageFromBytes(value.Data)?.Resize(200, 200).ToArray() : new System.Drawing.Bitmap(256, 256).WatermarkImage("No Image", System.Drawing.Color.Gray).AsBitmapImage().ToArray(); var border = new Border { Effect = new DropShadowEffect { ShadowDepth = 0, BlurRadius = 10 } }; var image = new Image { Margin = new Thickness(5) }; var source = value.Data != null ? ImageUtils.BitmapImageFromBytes(value.Data) : value.Thumbnail != null ? ImageUtils.BitmapImageFromBytes(value.Thumbnail) : null; if (source != null) { image.Source = source; var menu = new ContextMenu(); menu.AddItem("View Image", null, value, MultiImageView_Click); if (Enabled) { menu.AddItem("Remove Image", null, ((FrameworkElement)border, value), MultiImageRemove_Click); } image.ContextMenu = menu; border.Child = image; Images.Children.Add(border); } } private void MultiImageClear_Click(object sender, RoutedEventArgs e) { _value.Clear(); if (Images.Children.Count > 0) { Images.Children.Clear(); ChangeField(); } } private void ShowImage(byte[] data) { var filename = Path.ChangeExtension(Path.GetTempFileName(), ".jpg"); File.WriteAllBytes(filename, data); var gsProcessInfo = new ProcessStartInfo(); gsProcessInfo.Verb = "open"; gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal; gsProcessInfo.FileName = filename; gsProcessInfo.UseShellExecute = true; Process.Start(gsProcessInfo); } private void MultiImageView_Click(DFLayoutEmbeddedMediaValue element) { if (element.Data?.Any() == true) { ShowImage(element.Data); } else { DigitalFormDocumentFactory.LoadDocument(element.ID, (data) => { element.Data = data; Dispatcher.BeginInvoke(() => ShowImage(data)); }); } } private void MultiImageRemove_Click((FrameworkElement, DFLayoutEmbeddedMediaValue) element) { _value.Remove(element.Item2); Images.Children.Remove(element.Item1); ChangeField(); } private void MultiImageAdd_Click(object sender, RoutedEventArgs e) { if (EmbeddedImageUtilities.SelectImageFile(out var data)) { AddMultiImage(new DFLayoutEmbeddedMediaValue { Data = data }); ChangeField(); } } public override DFLayoutEmbeddedMediaValues GetSerializedValue() { foreach (var val in _value) { if ((val.Data?.Any() == true) && (val.ID == Guid.Empty)) val.ID = DigitalFormDocumentFactory.SaveDocument(val.Data); } return _value; } public override void SetSerializedValue(DFLayoutEmbeddedMediaValues value) { Images.Children.Clear(); _value = new DFLayoutEmbeddedMediaValues(); foreach (var val in value) { AddMultiImage(val); } } public override List GetValue() { return _value.Select(x => x.ID).ToList(); } public override void SetValue(List? value) { var newValue = new DFLayoutEmbeddedMediaValues(); if(value is not null) { foreach (var id in value) { newValue.Add(new DFLayoutEmbeddedMediaValue { ID = id }); } } SetSerializedValue(newValue); } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == IsEnabledProperty) { Grid.RowDefinitions[1].Height = (bool)e.NewValue ? GridLength.Auto : new GridLength(0); } } protected override bool IsEmpty() => _value.Values.Length == 0; } }