Pasando a los eventos de MainWindows para el canvas

This commit is contained in:
Miguel 2024-05-03 08:58:21 +02:00
parent 6c25cb8915
commit 1e30f00c57
7 changed files with 213 additions and 54 deletions

40
DatosDeTrabajo.cs Normal file
View File

@ -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<string, string> Imagenes { get; private set; }
public DatosDeTrabajo()
{
Imagenes = new Dictionary<string, string>();
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;
}
}
}
}
}
}

View File

@ -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<string> 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<string> ImageSelected;
public MainViewModel()
{
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
LoadImageCommand = new RelayCommand(LoadImage);
datosDeTrabajo = new DatosDeTrabajo();
listaImagenes = new ObservableCollection<string>(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<string>(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...
}
}

View File

@ -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}">
<Window.DataContext>
<ctreditor:MainViewModel/>
</Window.DataContext>
<Grid>
<!-- Menú Principal sobre toda la ventana -->
<Menu VerticalAlignment="Top" HorizontalAlignment="Stretch">
@ -32,7 +34,7 @@
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding ImageList}" SelectedItem="{Binding SelectedImage}" />
<ListBox x:Name="ListaImagenes" Grid.Row="0" Margin="5" ItemsSource="{Binding listaImagenes}" SelectedItem="{Binding SelectedImage}" />
<ListBox x:Name="ListaFunciones" Grid.Row="1" Margin="5"/>
</Grid>
@ -50,14 +52,12 @@
<MenuItem Header="Eliminar"/>
</Menu>
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Canvas x:Name="ImagenEnTrabajoCanvas" Background="Beige" Margin="5">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ZoomFactor}" ScaleY="{Binding ZoomFactor}"/>
<TranslateTransform X="{Binding OffsetX}" Y="{Binding OffsetY}"/>
</TransformGroup>
</Canvas.RenderTransform>
<ScrollViewer x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" PanningMode="Both">
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="200">
<!-- El Margin puede ser ajustado según el espacio adicional que quieras proporcionar -->
<Canvas.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Canvas.LayoutTransform>
</Canvas>
</ScrollViewer>
</Grid>

View File

@ -16,11 +16,136 @@ namespace CtrEditor
/// </summary>
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;
}
}
}
}

View File

@ -25,4 +25,5 @@ namespace CtrEditor
InitializeComponent();
}
}
}

View File

@ -25,4 +25,5 @@ namespace CtrEditor
InitializeComponent();
}
}
}

View File

@ -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; }