From 1e30f00c5790a1e226938dae60685c053ba8846a Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 3 May 2024 08:58:21 +0200 Subject: [PATCH] Pasando a los eventos de MainWindows para el canvas --- DatosDeTrabajo.cs | 40 +++++++++++ MainViewModel.cs | 78 ++++++++++----------- MainWindow.xaml | 20 +++--- MainWindow.xaml.cs | 125 ++++++++++++++++++++++++++++++++++ ObjetoSimuladoBotella.xaml.cs | 1 + ObjetoSimuladoPack.xaml.cs | 1 + estadoPersistente.cs | 2 +- 7 files changed, 213 insertions(+), 54 deletions(-) create mode 100644 DatosDeTrabajo.cs diff --git a/DatosDeTrabajo.cs b/DatosDeTrabajo.cs new file mode 100644 index 0000000..369b4cc --- /dev/null +++ b/DatosDeTrabajo.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CtrEditor +{ + public class DatosDeTrabajo + { + public Dictionary Imagenes { get; private set; } + + public DatosDeTrabajo() + { + Imagenes = new Dictionary(); + CargarImagenes(); // Inicializar la carga de imágenes basada en el directorio persistente + } + + public void CargarImagenes() + { + Imagenes.Clear(); + string folderPath = EstadoPersistente.Instance.directorio; // Usar directamente desde el Singleton + + if (Directory.Exists(folderPath)) + { + var archivosImagen = Directory.GetFiles(folderPath, "*.png"); // Ajustar para otros formatos si es necesario + foreach (var archivo in archivosImagen) + { + var nombreArchivo = Path.GetFileName(archivo); + if (!Imagenes.ContainsKey(nombreArchivo)) + { + Imagenes[nombreArchivo] = archivo; + } + } + } + } + } +} diff --git a/MainViewModel.cs b/MainViewModel.cs index 6d4039a..5a2f4f0 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -9,35 +9,62 @@ using System.Windows.Controls; using System.Windows.Input; using Ookii.Dialogs.Wpf; using System.Windows.Input; +using System.Collections.ObjectModel; +using System.Windows.Media; +using System.Windows.Media.Imaging; namespace CtrEditor { public class MainViewModel : INotifyPropertyChanged { - private double _zoomFactor = 1.0; + public DatosDeTrabajo datosDeTrabajo { get; } + public ObservableCollection listaImagenes { get; private set; } // Publicación de las claves del diccionario + private string _selectedImage; + // Evento que se dispara cuando se selecciona una nueva imagen + public event EventHandler ImageSelected; public MainViewModel() { OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory); - LoadImageCommand = new RelayCommand(LoadImage); + datosDeTrabajo = new DatosDeTrabajo(); + listaImagenes = new ObservableCollection(datosDeTrabajo.Imagenes.Keys); + directorioTrabajo = EstadoPersistente.Instance.directorio; } - public string DirectorioTrabajo + public string directorioTrabajo { - get => EstadoPersistente.Instance.DirectorioTrabajo; + get => EstadoPersistente.Instance.directorio; set { if (value != null) { - OnPropertyChanged(nameof(DirectorioTrabajo)); // Notificar el cambio de propiedad - EstadoPersistente.Instance.DirectorioTrabajo = value; // Actualizar el estado persistente + EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado + datosDeTrabajo.CargarImagenes(); + listaImagenes = new ObservableCollection(datosDeTrabajo.Imagenes.Keys); // Actualizar claves + OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad + OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado } } } + public string SelectedImage + { + get => _selectedImage; + set + { + if (_selectedImage != value) + { + _selectedImage = value; + OnPropertyChanged(nameof(SelectedImage)); + ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen + } + } + } + + public ICommand OpenWorkDirectoryCommand { get; } private void OpenWorkDirectory() @@ -45,53 +72,18 @@ namespace CtrEditor var dialog = new VistaFolderBrowserDialog(); if (dialog.ShowDialog() == true) // Mostrar el diálogo y comprobar si el resultado es positivo { - DirectorioTrabajo = dialog.SelectedPath; // Actualizar la propiedad que también actualiza el estado persistente + directorioTrabajo = dialog.SelectedPath; // Actualizar la propiedad que también actualiza el estado persistente } } - // Ejemplo de propiedad para gestionar el UserControl activo - private UserControl _activeControl; - public UserControl ActiveControl - { - get => _activeControl; - set { _activeControl = value; OnPropertyChanged(); } - } - // Comando para cargar una imagen - public ICommand LoadImageCommand { get; private set; } - - - private void LoadImage() - { - // Implementar lógica de carga de imagen - } + // Implementación de INotifyPropertyChanged... public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - - public double ZoomFactor - { - get => _zoomFactor; - set { _zoomFactor = value; OnPropertyChanged(); } - } - - private double _offsetX = 0; - private double _offsetY = 0; - public double OffsetX - { - get => _offsetX; - set { _offsetX = value; OnPropertyChanged(); } - } - public double OffsetY - { - get => _offsetY; - set { _offsetY = value; OnPropertyChanged(); } - } - - // Implementación de INotifyPropertyChanged... } } diff --git a/MainWindow.xaml b/MainWindow.xaml index bd8309c..c2a763d 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -2,10 +2,12 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ctreditor="clr-namespace:CtrEditor" Height="450" Width="800" - ResizeMode="CanResize" Title="{Binding DirectorioTrabajo}"> + ResizeMode="CanResize" Title="{Binding directorioTrabajo}"> + + @@ -32,7 +34,7 @@ - + @@ -50,14 +52,12 @@ - - - - - - - - + + + + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 0fc2633..a52c644 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -16,11 +16,136 @@ namespace CtrEditor /// public partial class MainWindow : Window { + private Point _lastMousePosition; + private bool _isDrawing = false; + private bool _isDragging = false; + private Image imagenDeFondo; + public MainWindow() { InitializeComponent(); + this.Loaded += MainWindow_Loaded; + ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel; + ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning; + ImagenEnTrabajoCanvas.MouseMove += Canvas_MouseMove_Panning; + ImagenEnTrabajoCanvas.MouseUp += Canvas_MouseUp_Panning; + } + private void MainWindow_Loaded(object sender, RoutedEventArgs e) + { + if (DataContext is MainViewModel viewModel) + { + viewModel.ImageSelected += ViewModel_ImageSelected; + } + } + private void ViewModel_ImageSelected(object sender, string imagePath) + { + LoadImageToCanvas(imagePath); } + private void LoadImageToCanvas(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 Canvas_MouseUp_Panning(object sender, MouseButtonEventArgs e) + { + if (_isDragging) + { + _isDragging = false; + ImagenEnTrabajoScrollViewer.ReleaseMouseCapture(); // Finaliza la captura del ratón + } + } + + 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 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 MainWindow_Closed(object sender, EventArgs e) + { + if (DataContext is MainViewModel viewModel) + { + viewModel.ImageSelected -= ViewModel_ImageSelected; + } + } } } \ No newline at end of file diff --git a/ObjetoSimuladoBotella.xaml.cs b/ObjetoSimuladoBotella.xaml.cs index dddcc68..98fba5d 100644 --- a/ObjetoSimuladoBotella.xaml.cs +++ b/ObjetoSimuladoBotella.xaml.cs @@ -25,4 +25,5 @@ namespace CtrEditor InitializeComponent(); } } + } diff --git a/ObjetoSimuladoPack.xaml.cs b/ObjetoSimuladoPack.xaml.cs index 793f096..710e17d 100644 --- a/ObjetoSimuladoPack.xaml.cs +++ b/ObjetoSimuladoPack.xaml.cs @@ -25,4 +25,5 @@ namespace CtrEditor InitializeComponent(); } } + } diff --git a/estadoPersistente.cs b/estadoPersistente.cs index b3f74ea..0c8b03a 100644 --- a/estadoPersistente.cs +++ b/estadoPersistente.cs @@ -21,7 +21,7 @@ namespace CtrEditor private string _strDirectorioTrabajo; // Propiedad pública con get y set para controlar el acceso a _strDirectorioTrabajo - public string DirectorioTrabajo + public string directorio { get { return _strDirectorioTrabajo; } set { _strDirectorioTrabajo = value; }