Mejorada la seleccion de objetos.

This commit is contained in:
Miguel 2025-02-17 15:16:40 +01:00
parent 633cd71d00
commit 89745d15bf
1 changed files with 187 additions and 63 deletions

View File

@ -15,6 +15,7 @@ using System.Windows.Shapes;
using System.Numerics;
using CommunityToolkit.Mvvm.Input;
using CtrEditor.FuncionesBase;
using Color = System.Windows.Media.Color;
namespace CtrEditor
{
@ -31,6 +32,8 @@ namespace CtrEditor
private Image imagenDeFondo;
private List<Rectangle> resizeRectangles = new List<Rectangle>();
private List<Rectangle> highlightRectangles = new List<Rectangle>(); // Nueva lista para los rectángulos de resaltado
private System.Threading.Timer timerRemoveHighlight = null;
private DispatcherTimer _zoomTimer;
private double _targetZoomFactor;
@ -68,6 +71,7 @@ namespace CtrEditor
// Agregar el evento KeyDown a la ventana
this.KeyDown += MainWindow_KeyDown;
ImagenEnTrabajoCanvas.MouseEnter += Canvas_MouseEnter;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
@ -92,6 +96,7 @@ namespace CtrEditor
{
userControl.MouseEnter += UserControl_MouseEnter;
userControl.MouseLeave += UserControl_MouseLeave;
userControl.Cursor = Cursors.Hand; // Agregar cursor de mano
// Suscribir a eventos de mouse para panning
userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
@ -123,6 +128,7 @@ namespace CtrEditor
{
if (!_isDrawingCanvas)
{
// Si el sender es un rectángulo de redimensionamiento
if (resizeRectangles != null && resizeRectangles.Contains(sender))
{
_isResizingUserControl = true;
@ -130,27 +136,39 @@ namespace CtrEditor
((Rectangle)sender).CaptureMouse();
_isMovingUserControl = true;
lastAngle = 0;
e.Handled = true; // Evitar que el evento se propague
return;
}
else
var userControl = sender as UserControl;
if (userControl != null)
{
var userControl = sender as UserControl;
userControl.CaptureMouse(); // Importante para recibir eventos de movimiento incluso fuera del control
// Si hacemos clic en un control diferente al seleccionado, remover los rectángulos anteriores
if (_currentDraggingControl != userControl)
{
RemoveResizeRectangles();
}
userControl.CaptureMouse();
_currentDraggingControl = userControl;
_isMovingUserControl = true;
RemoveResizeRectangles();
if (sender is UserControl control && control.DataContext is osBase datos)
// Actualizar la selección en el ViewModel
if (userControl.DataContext is osBase datos)
{
var viewModel = DataContext as MainViewModel;
if (viewModel != null)
{
viewModel.SelectedItemOsList = datos; // Esto desencadenará ListaOs_SelectionChanged
viewModel.SelectedItemOsList = datos;
AddResizeRectangles(userControl);
}
}
// ROTACION
// Resto del código para manejar rotación, tamaño y movimiento
if (Keyboard.IsKeyDown(Key.LeftShift))
{
// Código de rotación existente
// ROTACION
// Inicializar la rotación
_isRotatingUserControl = true;
RotateTransform rotateTransform = userControl.RenderTransform as RotateTransform;
@ -183,16 +201,16 @@ namespace CtrEditor
_angleDisplayTextBlock.Visibility = Visibility.Visible;
Canvas.SetZIndex(_angleDisplayTextBlock, 15);
}
// TAMANO
else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
// Código de cambio de tamaño existente
// Inicializar el cambio de tamaño
_isResizingUserControl = true;
_startPointUserControl = e.GetPosition(ImagenEnTrabajoCanvas);
}
// MOVIMIENTO
else
{
// Código de movimiento existente
// Inicializar el movimiento/panning
_isDraggingUserControl = true;
_startPointUserControl = e.GetPosition(ImagenEnTrabajoCanvas);
@ -217,39 +235,11 @@ namespace CtrEditor
private Point transformedBoundingBoxCenter = new Point();
private float lastAngle;
private System.Threading.Timer timerRemoveResizeRectangles = null;
public void ResetTimerRemoveResizeRectangles()
{
if (timerRemoveResizeRectangles == null)
timerRemoveResizeRectangles = new System.Threading.Timer(TimerCallbackRemoveResizeRectangles, null, Timeout.Infinite, Timeout.Infinite);
timerRemoveResizeRectangles.Change(2000, Timeout.Infinite);
}
private async void TimerCallbackRemoveResizeRectangles(object state)
{
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
// Realiza tus cambios en la interfaz de usuario aquí
MakeResizeRectanglesTransparent();
});
}
}
public void PauseTimerRemoveResizeRectangles()
{
if (timerRemoveResizeRectangles != null)
{
timerRemoveResizeRectangles.Change(Timeout.Infinite, Timeout.Infinite);
}
}
private void AddResizeRectangles(UserControl userControl)
{
double rectSize = 10;
double rectHighlightSize = 1;
RemoveResizeRectangles();
if (userControl is IDataContainer dataContainer && dataContainer.Datos is osBase mvBase && mvBase.Show_On_This_Page)
@ -263,14 +253,34 @@ namespace CtrEditor
Rect transformedBoundingBox = transform.TransformBounds(boundingBox);
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(transformedBoundingBox);
rectBox.Left -= (float)rectSize;
rectBox.Right += (float)rectSize;
rectBox.Top -= (float)rectSize;
rectBox.Bottom += (float)rectSize;
rectBox.Left -= (float)rectHighlightSize;
rectBox.Right += (float)rectHighlightSize;
rectBox.Top -= (float)rectHighlightSize;
rectBox.Bottom += (float)rectHighlightSize;
transformedBoundingBoxCenter.X = transformedBoundingBox.Left + transformedBoundingBox.Width / 2;
transformedBoundingBoxCenter.Y = transformedBoundingBox.Top + transformedBoundingBox.Height / 2;
// Agregar primero el rectángulo de selección
Rectangle selectionRect = new Rectangle
{
Width = rectBox.Width + (rectHighlightSize * 2), // Hacer el rectángulo un poco más grande
Height = rectBox.Height + (rectHighlightSize * 2),
Fill = Brushes.Transparent,
Stroke = new SolidColorBrush(Color.FromArgb(180, 0, 120, 215)), // Azul semi-transparente
StrokeThickness = 1.5,
Tag = "Selection",
IsHitTestVisible = false,
StrokeDashArray = new DoubleCollection(new double[] { 3, 3 }) // Borde punteado más visible
};
Canvas.SetLeft(selectionRect, rectBox.Left - rectHighlightSize);
Canvas.SetTop(selectionRect, rectBox.Top - rectHighlightSize);
Canvas.SetZIndex(selectionRect, ((int)ZIndexEnum.RectangulosPropiead - 1)); // Un nivel por debajo de los controles de redimensión
resizeRectangles.Add(selectionRect);
ImagenEnTrabajoCanvas.Children.Add(selectionRect);
// Cargar el cursor personalizado para rotación
Cursor rotationCursorRx = new Cursor(Application.GetResourceStream(new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationRx.cur")).Stream);
Cursor rotationCursorSx = new Cursor(Application.GetResourceStream(new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationSx.cur")).Stream);
@ -357,20 +367,62 @@ namespace CtrEditor
resizeRectangles.Add(rect);
ImagenEnTrabajoCanvas.Children.Add(rect);
Canvas.SetZIndex(rect, ((int)ZIndexEnum.RectangulosPropiead));
ResetTimerRemoveResizeRectangles();
}
}
}
private void AddHighlightRectangles(UserControl userControl)
{
double rectSize = 1;
RemoveHighlightRectangles(); // Eliminar highlight anterior
if (userControl is IDataContainer dataContainer && dataContainer.Datos is osBase mvBase && mvBase.Show_On_This_Page)
{
// Obtener el BoundingBox aproximado del UserControl
Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
// Transformar el BoundingBox a las coordenadas del Canvas
GeneralTransform transform = userControl.TransformToAncestor(ImagenEnTrabajoCanvas);
Rect transformedBoundingBox = transform.TransformBounds(boundingBox);
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(transformedBoundingBox);
rectBox.Left -= (float)rectSize;
rectBox.Right += (float)rectSize;
rectBox.Top -= (float)rectSize;
rectBox.Bottom += (float)rectSize;
// Crear un rectángulo de resaltado alrededor del objeto con estilo más sutil
Rectangle highlightRect = new Rectangle
{
Width = rectBox.Width,
Height = rectBox.Height,
Fill = Brushes.Transparent,
Stroke = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)), // Borde semitransparente
StrokeThickness = 1,
Tag = "Highlight",
IsHitTestVisible = false,
StrokeDashArray = new DoubleCollection(new double[] { 2, 2 }) // Borde punteado
};
Canvas.SetLeft(highlightRect, rectBox.Left);
Canvas.SetTop(highlightRect, rectBox.Top);
highlightRectangles.Add(highlightRect); // Usar la nueva lista
ImagenEnTrabajoCanvas.Children.Add(highlightRect);
Canvas.SetZIndex(highlightRect, ((int)ZIndexEnum.RectangulosPropiead));
// Reiniciar el timer
if (timerRemoveHighlight == null)
timerRemoveHighlight = new System.Threading.Timer(TimerCallbackRemoveHighlight, null, Timeout.Infinite, Timeout.Infinite);
timerRemoveHighlight.Change(2000, Timeout.Infinite);
}
}
private void ResizeRectangle_MouseLeave(object sender, MouseEventArgs e)
{
var rect = sender as Rectangle;
rect.Fill = Brushes.Transparent; // Volver al color original
ResetTimerRemoveResizeRectangles();
}
private void MakeResizeRectanglesTransparent()
@ -408,6 +460,18 @@ namespace CtrEditor
resizeRectangles.Clear();
}
private void RemoveHighlightRectangles()
{
if (highlightRectangles == null || highlightRectangles.Count == 0)
return;
foreach (var rect in highlightRectangles)
{
ImagenEnTrabajoCanvas.Children.Remove(rect);
}
highlightRectangles.Clear();
}
private Point lastMousePosition;
private void MarkUnsavedChanges()
@ -460,11 +524,11 @@ namespace CtrEditor
_currentDraggingRectangle = rect; // Asignar el rectángulo actual que se está arrastrando
_startPointUserControl = new Point(Canvas.GetLeft(rect), Canvas.GetTop(rect));
MakeResizeRectanglesNormal();
PauseTimerRemoveResizeRectangles();
}
if (_isMovingUserControl && _currentDraggingControl != null)
{
var currentPosition = e.GetPosition(ImagenEnTrabajoCanvas);
MakeResizeRectanglesTransparent(); // Hacer transparente durante cualquier manipulación
if (_isDraggingUserControl)
{
@ -607,18 +671,33 @@ namespace CtrEditor
private void UserControl_MouseEnter(object sender, MouseEventArgs e)
{
if (_currentDraggingControl != null)
if (sender is UserControl userControl && userControl is IDataContainer dataContainer)
{
RemoveResizeRectangles();
}
if (sender is UserControl userControl)
if (userControl is IDataContainer dataContainer)
dataContainer.Highlight(true);
if (DataContext is MainViewModel viewModel)
{
dataContainer.Highlight(true);
_currentDraggingControl = sender as UserControl;
AddResizeRectangles(_currentDraggingControl);
var selectedObject = viewModel.SelectedItemOsList;
// Si el control actual no es el seleccionado
if (selectedObject?.VisualRepresentation != userControl)
{
// Siempre mostrar el highlight temporal
AddHighlightRectangles(userControl);
}
}
}
}
private async void TimerCallbackRemoveHighlight(object state)
{
if (Application.Current != null)
{
Application.Current.Dispatcher.Invoke(() =>
{
RemoveHighlightRectangles();
});
}
}
private void UserControl_MouseLeave(object sender, MouseEventArgs e)
@ -671,6 +750,12 @@ namespace CtrEditor
{
_isDraggingCanvas = false;
ImagenEnTrabajoScrollViewer.ReleaseMouseCapture(); // Finaliza la captura del ratón
// Restaurar la visibilidad de los rectángulos de selección si hay un objeto seleccionado
if (DataContext is MainViewModel viewModel && viewModel.SelectedItemOsList != null)
{
MakeResizeRectanglesNormal();
}
}
}
@ -678,11 +763,18 @@ namespace CtrEditor
{
if (e.LeftButton == MouseButtonState.Pressed && !_isDrawingCanvas && !_isMovingUserControl)
{
// Indica que se inicia el panning
_isDraggingCanvas = true;
// Guarda la posición actual del ratón
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
//ImagenEnTrabajoScrollViewer.CaptureMouse(); // Importante para capturar el movimiento
// Asegurarnos de que el clic fue directamente en el canvas y no en un elemento hijo
if (e.Source == ImagenEnTrabajoCanvas)
{
if (DataContext is MainViewModel viewModel)
{
viewModel.SelectedItemOsList = null; // Deseleccionar el objeto actual
RemoveResizeRectangles(); // Eliminar los rectángulos después de deseleccionar
}
}
}
}
@ -694,7 +786,9 @@ namespace CtrEditor
var dx = currentPosition.X - _lastMousePosition.X;
var dy = currentPosition.Y - _lastMousePosition.Y;
// Ocultar rectángulos y eliminar highlights durante el panning
MakeResizeRectanglesTransparent();
RemoveHighlightRectangles();
// Obtener la transformación actual del Canvas
var transform = (TranslateTransform)((TransformGroup)ImagenEnTrabajoCanvas.RenderTransform).Children.First(t => t is TranslateTransform);
@ -707,7 +801,9 @@ namespace CtrEditor
private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
// Ocultar rectángulos y eliminar highlights
MakeResizeRectanglesTransparent();
RemoveHighlightRectangles();
_initialZoomFactor = ((ScaleTransform)((TransformGroup)ImagenEnTrabajoCanvas.RenderTransform).Children.First(t => t is ScaleTransform)).ScaleX;
@ -748,6 +844,12 @@ namespace CtrEditor
// Volver a activar el escalado de alta calidad después de completar el zoom
RenderOptions.SetBitmapScalingMode(ImagenEnTrabajoCanvas, BitmapScalingMode.HighQuality);
// Restaurar la visibilidad de los rectángulos de selección si hay un objeto seleccionado
if (DataContext is MainViewModel viewModel && viewModel.SelectedItemOsList != null)
{
MakeResizeRectanglesNormal();
}
return;
}
@ -818,7 +920,6 @@ namespace CtrEditor
private void ListaOs_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
//PanelEdicion.Children.Clear(); // Limpiar el panel existente
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
if (e.AddedItems.Count > 0 && e.AddedItems[0] is osBase selectedObject)
@ -826,19 +927,42 @@ namespace CtrEditor
if (selectedObject.VisualRepresentation != null)
{
_currentDraggingControl = selectedObject.VisualRepresentation;
RemoveResizeRectangles();
AddResizeRectangles(_currentDraggingControl);
}
CargarPropiedadesosDatos(selectedObject);
}
else
{
RemoveResizeRectangles();
}
}
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete && DataContext is MainViewModel viewModel)
if (DataContext is MainViewModel viewModel)
{
viewModel.EliminarObjetoSeleccionado();
e.Handled = true;
if (e.Key == Key.Delete)
{
viewModel.EliminarObjetoSeleccionado();
e.Handled = true;
}
else if (e.Key == Key.Escape)
{
// Deseleccionar el objeto actual y eliminar los rectángulos de selección
viewModel.SelectedItemOsList = null;
RemoveResizeRectangles();
e.Handled = true;
}
}
}
private void Canvas_MouseEnter(object sender, MouseEventArgs e)
{
// Solo remover los rectángulos si el mouse entra directamente al Canvas
if (e.OriginalSource == ImagenEnTrabajoCanvas)
{
// RemoveResizeRectangles();
}
}
}