ROIEditor/MainWindow.xaml.cs

490 lines
19 KiB
C#
Raw Normal View History

2024-04-11 06:51:12 -03:00
using Newtonsoft.Json;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Path = System.IO.Path;
namespace ROIEditor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ImagenEstado EstadoImagenActual = new ImagenEstado();
private Point? clickPosition = null;
private bool _isDrawing = false;
private Point _startPosition;
private Rectangle _currentRect = null;
private Image imagenDeFondo;
private bool _isDragging = false;
private Point _lastMousePosition;
public dbROIs ListaDeROIs = new dbROIs();
// Constructor de MainWindow
public MainWindow()
{
InitializeComponent();
CargarImagenes();
ListaImagenes.SelectionChanged += ListaImagenes_SelectionChanged;
ImagenEnTrabajoCanvas.MouseLeftButtonDown += ImagenEnTrabajoCanvas_MouseLeftButtonDown;
ImagenEnTrabajoCanvas.MouseRightButtonDown += ImagenEnTrabajoCanvas_MouseRightButtonDown;
ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown;
ImagenEnTrabajoCanvas.MouseMove += Canvas_MouseMove;
ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel;
// En el constructor de MainWindow o un método de inicialización
ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning;
ImagenEnTrabajoCanvas.MouseMove += Canvas_MouseMove_Panning;
ImagenEnTrabajoCanvas.MouseUp += Canvas_MouseUp_Panning;
// Agrega este manejador en el inicializador de tu ventana o control
ListaROIs.SelectionChanged += ListaROIs_SelectionChanged;
// Agrega este manejador en el inicializador de tu ventana o control
Guardar_ROI.Click += Guardar_ROI_Click;
// Suscripción a los eventos LostFocus
ROI_xy.LostFocus += GuardarCambiosRoi;
ROI_dxdy.LostFocus += GuardarCambiosRoi;
ROI_nombre.LostFocus += GuardarCambiosRoi;
ROI_num.LostFocus += GuardarCambiosRoi;
ROI_descripcion.LostFocus += GuardarCambiosRoi;
ROI_text1.LostFocus += GuardarCambiosRoi;
ROI_text2.LostFocus += GuardarCambiosRoi;
ROI_text3.LostFocus += GuardarCambiosRoi;
}
private void ListaROIs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
CargarDatosROI(selectedRoi);
}
}
private void Guardar_ROI_Click(object sender, RoutedEventArgs e)
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
ActualizarDatosROI(selectedRoi);
}
}
private void CargarDatosROI(Roi selectedRoi)
{
ROI_xy.Text = $"{selectedRoi.X}, {selectedRoi.Y}";
ROI_dxdy.Text = $"{selectedRoi.Width}, {selectedRoi.Height}";
ROI_nombre.Text = selectedRoi.Nombre;
ROI_num.Text = selectedRoi.CodigoNumerico.ToString();
ROI_descripcion.Text = selectedRoi.Descripcion;
ROI_text1.Text = selectedRoi.CampoTexto1;
ROI_text2.Text = selectedRoi.CampoTexto2;
ROI_text3.Text = selectedRoi.CampoTexto3;
}
private void ActualizarDatosROI(Roi selectedRoi)
{
try
{
// Suponiendo que se validen y parseen adecuadamente los valores
var xy = ROI_xy.Text.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var dxdy = ROI_dxdy.Text.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
selectedRoi.X = int.Parse(xy[0].Trim());
selectedRoi.Y = int.Parse(xy[1].Trim());
selectedRoi.Width = int.Parse(dxdy[0].Trim());
selectedRoi.Height = int.Parse(dxdy[1].Trim());
selectedRoi.Nombre = ROI_nombre.Text;
selectedRoi.CodigoNumerico = int.TryParse(ROI_num.Text, out int codigo) ? codigo : 0;
selectedRoi.Descripcion = ROI_descripcion.Text;
selectedRoi.CampoTexto1 = ROI_text1.Text;
selectedRoi.CampoTexto2 = ROI_text2.Text;
selectedRoi.CampoTexto3 = ROI_text3.Text;
// Aquí podrías llamar a un método que realice el guardado específico, si es necesario
// Por ejemplo, actualizar la visualización del ROI o guardar en un archivo JSON
}
catch (Exception ex)
{
// Manejar posibles errores de parseo o validación
MessageBox.Show($"Error al actualizar los datos del ROI: {ex.Message}");
}
}
private void GuardarCambiosRoi(object sender, RoutedEventArgs e)
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
ActualizarDatosROI(selectedRoi);
}
}
private void CargarImagenes()
{
// Asumiendo que las imágenes están en una carpeta "Imagenes" dentro del directorio de salida de tu aplicación
string folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Plantillas");
if (Directory.Exists(folderPath))
{
var archivosImagen = Directory.GetFiles(folderPath, "*.png"); // Asumiendo que buscas archivos .png
foreach (var archivo in archivosImagen)
{
// Aquí simplemente añadimos el nombre del archivo a la lista, pero podrías querer añadir un objeto más complejo
ListaImagenes.Items.Add(Path.GetFileName(archivo));
}
}
else
{
MessageBox.Show("No se encontró la carpeta de imágenes.");
}
}
private void Canvas_MouseDown_Panning(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && !_isDrawing)
{
// Indica que se inicia el panning
_isDragging = true;
// Guarda la posición actual del ratón
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
//ImagenEnTrabajoScrollViewer.CaptureMouse(); // Importante para capturar el movimiento
}
}
private void Canvas_MouseMove_Panning(object sender, MouseEventArgs e)
{
if (_isDragging && !_isDrawing)
{
// Calcula el nuevo desplazamiento basado en el movimiento del ratón
var currentPosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
var dx = currentPosition.X - _lastMousePosition.X;
var dy = currentPosition.Y - _lastMousePosition.Y;
// Ajusta el desplazamiento del ScrollViewer
ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(ImagenEnTrabajoScrollViewer.HorizontalOffset - dx);
ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(ImagenEnTrabajoScrollViewer.VerticalOffset - dy);
// Actualiza la posición del ratón para el próximo movimiento
_lastMousePosition = currentPosition;
}
}
private void Canvas_MouseUp_Panning(object sender, MouseButtonEventArgs e)
{
if (_isDragging)
{
_isDragging = false;
ImagenEnTrabajoScrollViewer.ReleaseMouseCapture(); // Finaliza la captura del ratón
}
}
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
// Verifica si el botón derecho del ratón fue el que se presionó
if (e.ChangedButton == MouseButton.Right)
{
if (!_isDrawing)
{
_startPosition = e.GetPosition(ImagenEnTrabajoCanvas);
_isDrawing = true;
// Inicializar un nuevo rectángulo
_currentRect = new Rectangle
{
Stroke = Brushes.Red,
StrokeThickness = 2,
Fill = Brushes.Transparent
};
Canvas.SetLeft(_currentRect, _startPosition.X);
Canvas.SetTop(_currentRect, _startPosition.Y);
ImagenEnTrabajoCanvas.Children.Add(_currentRect);
}
else
{
// Finaliza el dibujo del rectángulo
_isDrawing = false;
// Calcula las dimensiones finales y posición del ROI
var endPosition = e.GetPosition(ImagenEnTrabajoCanvas);
var x = Math.Min(_startPosition.X, endPosition.X);
var y = Math.Min(_startPosition.Y, endPosition.Y);
var width = Math.Abs(endPosition.X - _startPosition.X);
var height = Math.Abs(endPosition.Y - _startPosition.Y);
// Crea el nuevo objeto Roi con la información recopilada
Roi newRoi = new Roi(EstadoImagenActual.NombreImagen, (int)x, (int)y, (int)width, (int)height);
// Agrega el nuevo Roi a la lista de ROIs
ListaDeROIs.Add(newRoi);
// Elimina el rectángulo temporal del Canvas
ImagenEnTrabajoCanvas.Children.Remove(_currentRect);
_currentRect = null;
// Actualiza la interfaz de usuario con el nuevo ROI
ActualizarUIConROIs();
}
}
}
private void ActualizarUIConROIs()
{
// Aquí actualizas los controles de la interfaz de usuario que muestran los ROIs
// Por ejemplo, si tienes una ListBox para los ROIs, actualízala así:
ListaROIs.ItemsSource = null;
if (ListaDeROIs.Count() > 0)
{
ListaROIs.ItemsSource = ListaDeROIs.rois;
}
DibujarROIsEnCanvas();
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (_isDrawing)
{
var currentPosition = e.GetPosition(ImagenEnTrabajoCanvas);
var width = Math.Abs(currentPosition.X - _startPosition.X);
var height = Math.Abs(currentPosition.Y - _startPosition.Y);
_currentRect.Width = width;
_currentRect.Height = height;
// Ajusta la posición si el dibujo se hace hacia arriba o hacia la izquierda
if (currentPosition.X < _startPosition.X)
{
Canvas.SetLeft(_currentRect, currentPosition.X);
}
if (currentPosition.Y < _startPosition.Y)
{
Canvas.SetTop(_currentRect, currentPosition.Y);
}
}
}
private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
Point cursorPosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
// Calcular el punto focal del zoom relativo al contenido del ScrollViewer
var absoluteX = ImagenEnTrabajoScrollViewer.HorizontalOffset + cursorPosition.X;
var absoluteY = ImagenEnTrabajoScrollViewer.VerticalOffset + cursorPosition.Y;
// Aplicar el zoom
st.ScaleX *= zoomFactor;
st.ScaleY *= zoomFactor;
// Calcular el nuevo desplazamiento para que el zoom se centre en la posición del cursor
ImagenEnTrabajoScrollViewer.UpdateLayout(); // Asegurarse de que el layout del ScrollViewer esté actualizado
var newHorizontalOffset = absoluteX * zoomFactor - cursorPosition.X;
var newVerticalOffset = absoluteY * zoomFactor - cursorPosition.Y;
// Aplicar el nuevo desplazamiento
ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(newHorizontalOffset);
ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(newVerticalOffset);
e.Handled = true; // Evita el procesamiento adicional del evento
}
private void ImagenEnTrabajoCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
var mousePos = e.GetPosition(ImagenEnTrabajoCanvas);
// Verificar si mousePos está dentro de algún ROI y mostrar el formulario de comentario si es así
}
private void ImagenEnTrabajoCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var mousePos = e.GetPosition(ImagenEnTrabajoCanvas);
// Aquí puedes inicializar la creación de un nuevo ROI basándote en mousePos
}
private void CargarImagenEnTrabajo(string imagePath)
{
BitmapImage bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
if (imagenDeFondo == null)
{
imagenDeFondo = new Image();
ImagenEnTrabajoCanvas.Children.Add(imagenDeFondo);
}
imagenDeFondo.Source = bitmap;
RenderOptions.SetBitmapScalingMode(imagenDeFondo, BitmapScalingMode.HighQuality);
// Elimina solo los ROIs, no la imagen de fondo
for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--)
{
if (ImagenEnTrabajoCanvas.Children[i] is Rectangle)
{
ImagenEnTrabajoCanvas.Children.RemoveAt(i);
}
}
// Ajusta el tamaño del Canvas a la imagen, si es necesario
ImagenEnTrabajoCanvas.Width = bitmap.Width;
ImagenEnTrabajoCanvas.Height = bitmap.Height;
// Posiciona la imagen correctamente dentro del Canvas
Canvas.SetLeft(imagenDeFondo, 0);
Canvas.SetTop(imagenDeFondo, 0);
}
private void ListaImagenes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListaImagenes.SelectedItem != null)
{
if (EstadoImagenActual.NombreImagen != null)
{
SalvarEstadoImagen();
}
if (ListaDeROIs.Count()>0)
{
ListaDeROIs.GuardarRois();
}
EstadoImagenActual = new ImagenEstado();
EstadoImagenActual.NombreImagen = ListaImagenes.SelectedItem.ToString();
ListaDeROIs = new dbROIs(EstadoImagenActual.NombreImagen);
var imagePath = EstadoImagenActual.PathPlantillasPNG();
CargarImagenEnTrabajo(imagePath);
CargarEstadoImagen();
}
}
private void CargarEstadoImagen()
{
string jsonPath = EstadoImagenActual.PathPlantillasJson();
if (File.Exists(jsonPath))
{
string json = File.ReadAllText(jsonPath);
EstadoImagenActual = JsonConvert.DeserializeObject<ImagenEstado>(json);
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
st.ScaleX= EstadoImagenActual.ZoomScaleX ;
st.ScaleY = EstadoImagenActual.ZoomScaleY;
// Aplicar el nuevo desplazamiento
ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(EstadoImagenActual.HorizontalOffset);
ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(EstadoImagenActual.VerticalOffset);
DibujarROIsEnCanvas();
} else
{
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
EstadoImagenActual.ZoomScaleX = st.ScaleX;
EstadoImagenActual.ZoomScaleY = st.ScaleY;
EstadoImagenActual.HorizontalOffset = EstadoImagenActual.HorizontalOffset;
EstadoImagenActual.VerticalOffset = EstadoImagenActual.VerticalOffset;
}
}
private void SalvarEstadoImagen()
{
// Cambia la extensión del archivo de imagen a .json
string jsonPath = EstadoImagenActual.PathPlantillasJson();
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
EstadoImagenActual.ZoomScaleX = st.ScaleX;
EstadoImagenActual.ZoomScaleY = st.ScaleY;
EstadoImagenActual.HorizontalOffset = ImagenEnTrabajoScrollViewer.HorizontalOffset;
EstadoImagenActual.VerticalOffset = ImagenEnTrabajoScrollViewer.VerticalOffset;
// Serializa el estado de la imagen a JSON
string json = JsonConvert.SerializeObject(EstadoImagenActual, Formatting.Indented);
// Escribe el JSON en un archivo
File.WriteAllText(jsonPath, json);
}
private void DibujarROIsEnCanvas()
{
// Elimina solo los ROIs, no la imagen de fondo
for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--)
{
if (ImagenEnTrabajoCanvas.Children[i] is Rectangle)
{
ImagenEnTrabajoCanvas.Children.RemoveAt(i);
}
}
// Dibuja los ROIs
foreach (var roi in ListaDeROIs.rois)
{
Rectangle rect = roi.DibujarRoiEnCanvas(ImagenEnTrabajoCanvas);
// Eventos
rect.MouseEnter += Rect_MouseEnter;
rect.MouseLeave += Rect_MouseLeave;
rect.MouseDown += Rect_MouseDown;
}
}
private void Rect_MouseEnter(object sender, MouseEventArgs e)
{
if (sender is Rectangle rect)
{
rect.StrokeThickness = 4; // Aumenta el grosor
}
}
private void Rect_MouseLeave(object sender, MouseEventArgs e)
{
if (sender is Rectangle rect)
{
rect.StrokeThickness = 2; // Restaura el grosor
}
}
private void Rect_MouseDown(object sender, MouseButtonEventArgs e)
{
if (sender is Rectangle rect && rect.Tag is Roi roi)
{
int index = ListaDeROIs.rois.IndexOf(roi);
if (index != -1)
{
ListaROIs.SelectedIndex = index; // Selecciona el ROI en la lista
e.Handled = true; // Evita la propagación del evento
}
}
}
}
}