151 lines
4.5 KiB
C#
151 lines
4.5 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using OpenCvSharp;
|
|
using OpenCvSharp.Extensions;
|
|
|
|
namespace Hawkeye.VisionBuilder.Features.ImagesStrip.Components
|
|
{
|
|
/// <summary>
|
|
/// Represents a single image thumbnail item with an image and filename label.
|
|
/// </summary>
|
|
public class ImageThumbnailControl : Panel
|
|
{
|
|
private const int ThumbnailSize = 108;
|
|
private const int BorderWidth = 3;
|
|
|
|
private readonly PictureBox _pictureBox;
|
|
private readonly Label _label;
|
|
private bool _isSelected;
|
|
private string _imagePath;
|
|
|
|
public string ImagePath
|
|
{
|
|
get => _imagePath;
|
|
set
|
|
{
|
|
_imagePath = value;
|
|
LoadImage(value);
|
|
_label.Text = Path.GetFileNameWithoutExtension(value);
|
|
}
|
|
}
|
|
|
|
public bool IsSelected
|
|
{
|
|
get => _isSelected;
|
|
set
|
|
{
|
|
if (_isSelected != value)
|
|
{
|
|
_isSelected = value;
|
|
Invalidate(); // Trigger repaint to show/hide border
|
|
}
|
|
}
|
|
}
|
|
|
|
public event EventHandler ThumbnailClicked;
|
|
|
|
public ImageThumbnailControl()
|
|
{
|
|
// Set up the container panel
|
|
Width = ThumbnailSize + (BorderWidth * 2);
|
|
Height = ThumbnailSize + 25 + (BorderWidth * 2); // Extra space for label
|
|
Margin = new Padding(5);
|
|
Cursor = Cursors.Hand;
|
|
|
|
// Create PictureBox for the image
|
|
_pictureBox = new PictureBox
|
|
{
|
|
Width = ThumbnailSize,
|
|
Height = ThumbnailSize,
|
|
SizeMode = PictureBoxSizeMode.StretchImage,
|
|
Location = new System.Drawing.Point(BorderWidth, BorderWidth),
|
|
BackColor = Color.Black
|
|
};
|
|
_pictureBox.Click += OnThumbnailClick;
|
|
|
|
// Create Label for the filename
|
|
_label = new Label
|
|
{
|
|
Width = ThumbnailSize,
|
|
Height = 20,
|
|
Location = new System.Drawing.Point(BorderWidth, ThumbnailSize + BorderWidth + 2),
|
|
TextAlign = ContentAlignment.MiddleCenter,
|
|
AutoEllipsis = true,
|
|
Font = new Font("Segoe UI", 8f)
|
|
};
|
|
_label.Click += OnThumbnailClick;
|
|
|
|
Controls.Add(_pictureBox);
|
|
Controls.Add(_label);
|
|
|
|
// Enable double buffering to reduce flicker
|
|
DoubleBuffered = true;
|
|
}
|
|
|
|
private void LoadImage(string imagePath)
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(imagePath))
|
|
{
|
|
using (var mat = new Mat(imagePath))
|
|
{
|
|
var resized = mat.Resize(new OpenCvSharp.Size(ThumbnailSize, ThumbnailSize));
|
|
var bitmap = resized.ToBitmap();
|
|
|
|
// Dispose old image if exists
|
|
var oldImage = _pictureBox.Image;
|
|
_pictureBox.Image = bitmap;
|
|
oldImage?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// If image loading fails, show error in label
|
|
_label.Text = "Error loading image";
|
|
_label.ForeColor = Color.Red;
|
|
}
|
|
}
|
|
|
|
private void OnThumbnailClick(object sender, EventArgs e)
|
|
{
|
|
ThumbnailClicked?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
|
|
// Draw selection border if selected
|
|
if (_isSelected)
|
|
{
|
|
using (var pen = new Pen(Color.DodgerBlue, BorderWidth))
|
|
{
|
|
var rect = new Rectangle(
|
|
BorderWidth / 2,
|
|
BorderWidth / 2,
|
|
Width - BorderWidth,
|
|
Height - BorderWidth
|
|
);
|
|
e.Graphics.DrawRectangle(pen, rect);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
// Dispose the image to free memory
|
|
_pictureBox?.Image?.Dispose();
|
|
_pictureBox?.Dispose();
|
|
_label?.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
}
|
|
}
|