From 82b6f9cffc72b1ecc3a4bd2894ffb39ab03960d1 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 4 May 2024 14:06:33 +0200 Subject: [PATCH] Tabajando en la rotacion de lo usercontrol --- MainViewModel.cs | 2 +- MainWindow.xaml.cs | 245 +++++++++++++++++++++++++++++++++++++++---- ObjetosSim/osBase.cs | 4 +- 3 files changed, 226 insertions(+), 25 deletions(-) diff --git a/MainViewModel.cs b/MainViewModel.cs index a2c97a2..fa609e6 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -159,8 +159,8 @@ namespace CtrEditor { SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen _selectedImage = value; - LoadStateObjetosSimulables(); ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen + LoadStateObjetosSimulables(); } _selectedImage = value; OnPropertyChanged(nameof(SelectedImage)); diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 44eb6f3..cac3577 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -17,11 +17,22 @@ namespace CtrEditor /// public partial class MainWindow : Window { + // Para el Canvas private Point _lastMousePosition; - private bool _isDrawing = false; - private bool _isDragging = false; + private bool _isDrawingCanvas = false; + private bool _isDraggingCanvas = false; private Image imagenDeFondo; + // Para los UserControl + private Point _startPointUserControl; + private UserControl _currentDraggingControl; + private bool _isRotatingUserControl = false; + private bool _isResizingUserControl = false; + private bool _isDraggingUserControl = false; + private bool _isMovingUserControl = false; + private double _initialAngleUserControl; + private TextBlock _angleDisplayTextBlock; + public MainWindow() { InitializeComponent(); @@ -53,39 +64,229 @@ namespace CtrEditor if (!NuevoOS.Inicializado) // Aun no fue inicializado { + // Obtiene el factor de escala + var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform; + double scaleX = scaleTransform?.ScaleX ?? 1.0; + double scaleY = scaleTransform?.ScaleY ?? 1.0; + // Obtiene el área visible del ScrollViewer - var visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth; - var visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight; + double visibleWidth = ImagenEnTrabajoScrollViewer.ViewportWidth; + double visibleHeight = ImagenEnTrabajoScrollViewer.ViewportHeight; - // Obtiene la posición actual del desplazamiento - var offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset; - var offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset; + // Obtiene la posición actual del desplazamiento ajustada por el zoom + double offsetX = ImagenEnTrabajoScrollViewer.HorizontalOffset / scaleX; + double offsetY = ImagenEnTrabajoScrollViewer.VerticalOffset / scaleY; - // Calcula el centro visible del Canvas - double centerX = offsetX + visibleWidth / 2; - double centerY = offsetY + visibleHeight / 2; + // Calcula el centro visible ajustado + double centerX = offsetX + (visibleWidth / scaleX) / 2; + double centerY = offsetY + (visibleHeight / scaleY) / 2; // Ajusta la posición del UserControl para que esté centrado en el área visible double left = centerX - (userControl.ActualWidth / 2); double top = centerY - (userControl.ActualHeight / 2); // Establece la posición del UserControl - Canvas.SetLeft(userControl, left); - Canvas.SetTop(userControl, top); - - NuevoOS.x = left; - NuevoOS.y = top; + NuevoOS.Left = left; + NuevoOS.Top = top; NuevoOS.Inicializado = true; } + // Establece la posición del UserControl + Canvas.SetLeft(userControl, NuevoOS.Left); + Canvas.SetTop(userControl, NuevoOS.Top); + + // Suscribirse a eventos de mouse para marcar el Control + userControl.MouseEnter += UserControl_MouseEnter; + userControl.MouseLeave += UserControl_MouseLeave; + + // Suscribir a eventos de mouse para panning + userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown; + userControl.MouseLeftButtonUp += UserControl_MouseLeftButtonUp; + userControl.MouseMove += UserControl_MouseMove; + // Añade el UserControl al Canvas ImagenEnTrabajoCanvas.Children.Add(userControl); } } } + private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (!_isDrawingCanvas) + { + var userControl = sender as UserControl; + _currentDraggingControl = userControl; + userControl.CaptureMouse(); // Importante para recibir eventos de movimiento incluso fuera del control + _isMovingUserControl = true; + // ROTACION + if (Keyboard.IsKeyDown(Key.LeftShift)) + { + // Inicializar la rotación + _isRotatingUserControl = true; + RotateTransform rotateTransform = userControl.RenderTransform as RotateTransform; + if (rotateTransform == null) + { + rotateTransform = new RotateTransform(); + userControl.RenderTransform = rotateTransform; + } + _initialAngleUserControl = rotateTransform.Angle; + + // Establecer el punto inicial de referencia para el cálculo de rotación + _startPointUserControl = new Point(rotateTransform.CenterX, rotateTransform.CenterY); + + // Ajusta el punto inicial al espacio del Canvas + _startPointUserControl = userControl.TranslatePoint(_startPointUserControl, ImagenEnTrabajoCanvas); + + // Crear y configurar el TextBlock si no existe + if (_angleDisplayTextBlock == null) + { + _angleDisplayTextBlock = new TextBlock + { + Foreground = Brushes.Black, + Background = Brushes.White, + Opacity = 0.8, + Padding = new Thickness(5) + }; + ImagenEnTrabajoCanvas.Children.Add(_angleDisplayTextBlock); + } + + PositionAngleDisplay(userControl); + _angleDisplayTextBlock.Visibility = Visibility.Visible; + } + // TAMANO + else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) + { + // Inicializar el cambio de tamaño + _isResizingUserControl = true; + } + // MOVIMIENTO + else + { + // Inicializar el movimiento/panning + _isDraggingUserControl = true; + _startPointUserControl = e.GetPosition(ImagenEnTrabajoCanvas); + } + } + } + + private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (_isMovingUserControl) + { + var userControl = sender as UserControl; + + userControl.ReleaseMouseCapture(); + _currentDraggingControl = null; + _isResizingUserControl = _isRotatingUserControl = _isDraggingUserControl = false ; + _isMovingUserControl = false; + // Ocultar el TextBlock de ángulo + if (_angleDisplayTextBlock != null) + { + _angleDisplayTextBlock.Visibility = Visibility.Collapsed; + } + } + } + + private void UserControl_MouseMove(object sender, MouseEventArgs e) + { + if (_isMovingUserControl && _currentDraggingControl != null) + { + var currentPosition = e.GetPosition(ImagenEnTrabajoCanvas); + + if (_isDraggingUserControl) + { + // Código para mover el control + var dx = currentPosition.X - _startPointUserControl.X; + var dy = currentPosition.Y - _startPointUserControl.Y; + var newX = Canvas.GetLeft(_currentDraggingControl) + dx; + var newY = Canvas.GetTop(_currentDraggingControl) + dy; + + Canvas.SetLeft(_currentDraggingControl, newX); + Canvas.SetTop(_currentDraggingControl, newY); + _startPointUserControl = currentPosition; // Actualiza el punto inicial para el siguiente movimiento + } + else if (_isRotatingUserControl) + { + // Código para rotar el control + RotateControl(_currentDraggingControl, currentPosition); + } + else if (_isResizingUserControl) + { + // Código para cambiar el tamaño del control + ResizeControl(_currentDraggingControl, currentPosition); + } + + } + } + + private void RotateControl(UserControl control, Point currentPosition) + { + // Calcular el vector desde el centro de rotación hasta el punto de inicio + double deltaX = _startPointUserControl.X - (Canvas.GetLeft(control) + control.ActualWidth / 2); + double deltaY = _startPointUserControl.Y - (Canvas.GetTop(control) + control.ActualHeight); + + // Calcular el vector desde el centro de rotación hasta la posición actual del ratón + double deltaXCurrent = currentPosition.X - (Canvas.GetLeft(control) + control.ActualWidth / 2); + double deltaYCurrent = currentPosition.Y - (Canvas.GetTop(control) + control.ActualHeight); + + // Calcular los ángulos + double initialAngle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI); + double currentAngle = Math.Atan2(deltaYCurrent, deltaXCurrent) * (180 / Math.PI); + + // Calcular la diferencia de ángulo y ajustar + double angleDelta = currentAngle - initialAngle; + + RotateTransform rotateTransform = control.RenderTransform as RotateTransform; + rotateTransform.Angle = angleDelta; + rotateTransform.CenterX = 0; + rotateTransform.CenterY = 0; + + // Actualizar el ángulo mostrado + _angleDisplayTextBlock.Text = $"Ángulo: {angleDelta:F2}°"; + PositionAngleDisplay(control); + } + + private void PositionAngleDisplay(UserControl control) + { + // Posicionar el TextBlock sobre el control + Canvas.SetLeft(_angleDisplayTextBlock, Canvas.GetLeft(control) + control.Width / 2 - _angleDisplayTextBlock.ActualWidth / 2); + Canvas.SetTop(_angleDisplayTextBlock, Canvas.GetTop(control) - _angleDisplayTextBlock.ActualHeight - 5); + } + + private void ResizeControl(UserControl control, Point currentPosition) + { + // Calcular la diferencia en la posición X desde el punto de inicio + double widthChange = currentPosition.X - _startPointUserControl.X; + + // Actualizar el ancho del control + control.Width = Math.Max(control.ActualWidth + widthChange, control.MinWidth); // Asegurar que no sea menor que el mínimo + + // Actualizar el punto de inicio para el próximo evento de movimiento + _startPointUserControl = currentPosition; + } + + + private void UserControl_MouseEnter(object sender, MouseEventArgs e) + { + // Lógica a ejecutar cuando el mouse entra en el UserControl + if (sender is UserControl userControl) + { + // Por ejemplo, cambiar el color de fondo para indicar el foco + userControl.Background = Brushes.LightBlue; + } + } + + private void UserControl_MouseLeave(object sender, MouseEventArgs e) + { + // Lógica a ejecutar cuando el mouse sale del UserControl + if (sender is UserControl userControl) + { + // Restaurar el color de fondo original + userControl.Background = Brushes.White; + } + } private void ViewModel_ImageSelected(object sender, string imagePath) { @@ -126,19 +327,19 @@ namespace CtrEditor private void Canvas_MouseUp_Panning(object sender, MouseButtonEventArgs e) { - if (_isDragging) + if (_isDraggingCanvas) { - _isDragging = false; + _isDraggingCanvas = false; ImagenEnTrabajoScrollViewer.ReleaseMouseCapture(); // Finaliza la captura del ratón } } private void Canvas_MouseDown_Panning(object sender, MouseButtonEventArgs e) { - if (e.LeftButton == MouseButtonState.Pressed && !_isDrawing) + if (e.LeftButton == MouseButtonState.Pressed && !_isDrawingCanvas && !_isMovingUserControl) { // Indica que se inicia el panning - _isDragging = true; + _isDraggingCanvas = true; // Guarda la posición actual del ratón _lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer); //ImagenEnTrabajoScrollViewer.CaptureMouse(); // Importante para capturar el movimiento @@ -147,7 +348,7 @@ namespace CtrEditor private void Canvas_MouseMove_Panning(object sender, MouseEventArgs e) { - if (_isDragging && !_isDrawing) + if (_isDraggingCanvas && !_isDrawingCanvas) { // Calcula el nuevo desplazamiento basado en el movimiento del ratón var currentPosition = e.GetPosition(ImagenEnTrabajoScrollViewer); @@ -170,8 +371,8 @@ namespace CtrEditor 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; + var absoluteX = ImagenEnTrabajoScrollViewer.HorizontalOffset + cursorPosition.X; + var absoluteY = ImagenEnTrabajoScrollViewer.VerticalOffset + cursorPosition.Y; // Aplicar el zoom st.ScaleX *= zoomFactor; diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 151a684..2f604c8 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -36,8 +36,8 @@ namespace CtrEditor.ObjetosSim public string Nombre => "Base"; public abstract void Update(); public bool Inicializado = false; - public double x { get; set; } - public double y { get; set; } + public double Left { get; set; } + public double Top { get; set; } }