138 lines
4.5 KiB
C#
138 lines
4.5 KiB
C#
using System.Collections.ObjectModel;
|
|
using Microsoft.VisualBasic.Logging;
|
|
using System.Drawing.Drawing2D;
|
|
using OpenCvSharp.Extensions;
|
|
using VisionBuilder.UI.Common.ViewModel;
|
|
using VisionBuilder.UI.Common.ViewModel.Classes;
|
|
using System.Collections.Specialized;
|
|
|
|
namespace VisionBuilder.UI.Windows.Components
|
|
{
|
|
public partial class ErrorPreview : UserControl
|
|
{
|
|
private ErrorsVM _errorPreviewVM;
|
|
|
|
// Keep track of subscription to avoid duplicate handlers
|
|
private ObservableCollection<ErrorData> _subscribedErrors;
|
|
|
|
public void SetViewModel(ErrorsVM errorPreviewVm)
|
|
{
|
|
// Unsubscribe from previous Errors collection if needed
|
|
if (_subscribedErrors != null)
|
|
_subscribedErrors.CollectionChanged -= Errors_CollectionChanged;
|
|
|
|
_errorPreviewVM = errorPreviewVm;
|
|
|
|
if (_errorPreviewVM != null)
|
|
{
|
|
_subscribedErrors = _errorPreviewVM.Errors;
|
|
_subscribedErrors.CollectionChanged += Errors_CollectionChanged;
|
|
|
|
// Initial sync: clear and add all
|
|
flowLayoutPanel1.Controls.Clear();
|
|
foreach (var error in _subscribedErrors)
|
|
{
|
|
AddErrorPreviewInternal(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
public ErrorPreview()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private Font _numberedFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
|
|
private void AddErrorPreviewInternal(ErrorData errorData)
|
|
{
|
|
var pb = new PictureBox();
|
|
var width = 293 / 1.6f;
|
|
var height = 220 / 1.6f;
|
|
pb.Size = new Size((int)width, (int)height + 20);
|
|
pb.SizeMode = PictureBoxSizeMode.Zoom;
|
|
pb.Margin = new Padding(5,0,5,5);
|
|
|
|
var numberedImage = new Bitmap((int)width, (int)height + 20);
|
|
var text = errorData.Title;
|
|
|
|
using (Graphics g = Graphics.FromImage(numberedImage))
|
|
{
|
|
g.Clear(Color.White);
|
|
|
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
try
|
|
{
|
|
g.DrawImage(errorData.ImageAnalysis.ToBitmap(), 0, 0, width, height);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
|
|
var measure = g.MeasureString(text, _numberedFont);
|
|
g.TranslateTransform(width / 2 - measure.Width / 2, height);
|
|
|
|
g.DrawString(text, _numberedFont, Brushes.Black, 0, 0);
|
|
}
|
|
pb.Image = numberedImage;
|
|
pb.SizeMode = PictureBoxSizeMode.Zoom;
|
|
pb.Cursor = Cursors.Hand;
|
|
pb.Click += (sender, args) =>
|
|
{
|
|
_errorPreviewVM.ShowImage(errorData);
|
|
};
|
|
var tag = (errorData, text);
|
|
pb.Tag = tag;
|
|
flowLayoutPanel1.Controls.Add(pb);
|
|
flowLayoutPanel1.Controls.SetChildIndex(pb, 0);
|
|
|
|
try
|
|
{
|
|
flowLayoutPanel1.Refresh();
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private void Errors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
{
|
|
if (InvokeRequired)
|
|
{
|
|
BeginInvoke(new NotifyCollectionChangedEventHandler(Errors_CollectionChanged), sender, e);
|
|
return;
|
|
}
|
|
|
|
if (e.Action == NotifyCollectionChangedAction.Add)
|
|
{
|
|
foreach (ErrorData newError in e.NewItems)
|
|
{
|
|
AddErrorPreviewInternal(newError);
|
|
}
|
|
}
|
|
else if (e.Action == NotifyCollectionChangedAction.Remove)
|
|
{
|
|
foreach (ErrorData oldError in e.OldItems)
|
|
{
|
|
// Remove the PictureBox whose Tag contains the oldError
|
|
foreach (Control ctrl in flowLayoutPanel1.Controls)
|
|
{
|
|
if (ctrl is PictureBox pb && pb.Tag is ValueTuple<ErrorData, string> tag && tag.Item1 == oldError)
|
|
{
|
|
flowLayoutPanel1.Controls.Remove(pb);
|
|
pb.Dispose();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (e.Action == NotifyCollectionChangedAction.Reset)
|
|
{
|
|
flowLayoutPanel1.Controls.Clear();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|