From 0d8780b16f1d19a523ccc6b92968efb0b50e26d3 Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 13 Jun 2025 20:16:12 +0200 Subject: [PATCH] =?UTF-8?q?Implementada=20la=20funcionalidad=20de=20bloque?= =?UTF-8?q?o=20de=20movimiento=20para=20objetos:=20se=20agreg=C3=B3=20la?= =?UTF-8?q?=20propiedad=20'lock=5Fmovement'=20en=20la=20clase=20osBase=20y?= =?UTF-8?q?=20se=20modificaron=20las=20funciones=20de=20manipulaci=C3=B3n?= =?UTF-8?q?=20de=20objetos=20para=20respetar=20este=20bloqueo,=20evitando?= =?UTF-8?q?=20redimensionamientos,=20movimientos=20y=20eliminaciones=20de?= =?UTF-8?q?=20objetos=20bloqueados.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ObjectManipulationManager.cs | 108 ++++++++++++++++++++++++++++++----- ObjetosSim/osBase.cs | 6 ++ 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/ObjectManipulationManager.cs b/ObjectManipulationManager.cs index d828e4c..8704c86 100644 --- a/ObjectManipulationManager.cs +++ b/ObjectManipulationManager.cs @@ -185,6 +185,9 @@ namespace CtrEditor double rectHighlightSize = 1; RemoveResizeRectangles(); + // Verificar si hay objetos bloqueados + bool hasLockedObjects = selectedObjects.Any(obj => obj.Lock_movement); + // Calcular el bounding box que contenga todos los objetos seleccionados Rect boundingBox = CalculateTotalBoundingBox(selectedObjects); if (_selectedObjectsAreVisible) { @@ -200,19 +203,23 @@ namespace CtrEditor boundingBox.Top + boundingBox.Height / 2 ); - // Selection rectangle - Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize); + // Siempre mostrar el rectángulo de selección + Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize, hasLockedObjects); _resizeRectangles.Add(selectionRect); _canvas.Children.Add(selectionRect); - // Load rotation cursors - 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); + // Solo agregar handles de manipulación si no hay objetos bloqueados + if (!hasLockedObjects) + { + // Load rotation cursors + 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); - // Add resize/rotation handles - AddResizeHandles(rectBox, 10, rotationCursorRx, rotationCursorSx); + // Add resize/rotation handles + AddResizeHandles(rectBox, 10, rotationCursorRx, rotationCursorSx); + } } } @@ -248,7 +255,7 @@ namespace CtrEditor ); } - private Rectangle CreateSelectionRectangle(FuncionesBase.MutableRect rectBox, double rectHighlightSize) + private Rectangle CreateSelectionRectangle(FuncionesBase.MutableRect rectBox, double rectHighlightSize, bool hasLockedObjects = false) { if (double.IsInfinity(rectBox.Width) || double.IsInfinity(rectBox.Height) || double.IsNaN(rectBox.Width) || double.IsNaN(rectBox.Height)) @@ -256,16 +263,33 @@ namespace CtrEditor throw new ArgumentException("Invalid dimensions for selection rectangle."); } + // Cambiar el estilo visual dependiendo si hay objetos bloqueados + Brush strokeBrush; + DoubleCollection dashArray; + + if (hasLockedObjects) + { + // Estilo para objetos bloqueados (rojo/naranja con líneas más separadas) + strokeBrush = new SolidColorBrush(Color.FromArgb(180, 255, 140, 0)); // Naranja + dashArray = new DoubleCollection(new double[] { 5, 3 }); // Líneas más largas + } + else + { + // Estilo normal para objetos no bloqueados (azul) + strokeBrush = new SolidColorBrush(Color.FromArgb(180, 0, 120, 215)); // Azul + dashArray = new DoubleCollection(new double[] { 3, 3 }); // Líneas normales + } + var rect = new Rectangle { Width = rectBox.Width + (rectHighlightSize * 2), Height = rectBox.Height + (rectHighlightSize * 2), Fill = Brushes.Transparent, - Stroke = new SolidColorBrush(Color.FromArgb(180, 0, 120, 215)), + Stroke = strokeBrush, StrokeThickness = 1.5, Tag = "Selection", IsHitTestVisible = false, - StrokeDashArray = new DoubleCollection(new double[] { 3, 3 }) + StrokeDashArray = dashArray }; Canvas.SetLeft(rect, rectBox.Left - rectHighlightSize); @@ -568,8 +592,18 @@ namespace CtrEditor { if (!_isDrawingCanvas) { + // Verificar si hay objetos bloqueados en la selección actual + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (_resizeRectangles != null && _resizeRectangles.Contains(sender)) { + // Si hay objetos bloqueados, no permitir redimensionamiento + if (hasLockedObjects) + { + e.Handled = true; + return; + } + _currentDraggingRectangle = sender as Rectangle; _lastMousePosition = e.GetPosition(_canvas); _currentDraggingRectangle.CaptureMouse(); @@ -585,16 +619,24 @@ namespace CtrEditor if (userControl.DataContext is osBase datos) { HandleObjectSelection(userControl, datos); + + // Actualizar el estado de objetos bloqueados después de la selección + hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); } - // Solo iniciar el arrastre si no se presionó Ctrl - if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) + // Solo iniciar el arrastre si no se presionó Ctrl y no hay objetos bloqueados + if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && !hasLockedObjects) { userControl.CaptureMouse(); _currentDraggingControl = userControl; _isMovingUserControl = true; InitializeDrag(e); } + else if (hasLockedObjects) + { + // Si hay objetos bloqueados, no permitir el inicio del arrastre + e.Handled = true; + } } } } @@ -641,6 +683,14 @@ namespace CtrEditor private void HandleDrag(Point currentPosition) { PurgeDeletedObjects(); + + // Verificar si hay objetos bloqueados antes de mover + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (hasLockedObjects) + { + return; // No mover si hay objetos bloqueados + } + var dx = currentPosition.X - _startPointUserControl.X; var dy = currentPosition.Y - _startPointUserControl.Y; @@ -792,6 +842,14 @@ namespace CtrEditor private void HandleResize(Point currentPosition, HandleMode mode) { PurgeDeletedObjects(); + + // Verificar si hay objetos bloqueados antes de redimensionar + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (hasLockedObjects) + { + return; // No redimensionar si hay objetos bloqueados + } + RemoveAllSelectionHighlights(); // Remover antes de redimensionar foreach (var selectedObject in _selectedObjects) @@ -816,6 +874,14 @@ namespace CtrEditor private void HandleRotation(Point currentPosition) { PurgeDeletedObjects(); + + // Verificar si hay objetos bloqueados antes de rotar + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (hasLockedObjects) + { + return; // No rotar si hay objetos bloqueados + } + RemoveAllSelectionHighlights(); // Remover antes de rotar // Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados @@ -845,6 +911,13 @@ namespace CtrEditor PurgeDeletedObjects(); if (_selectedObjects.Count <= 1) return; + // Verificar si hay objetos bloqueados antes de alinear + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (hasLockedObjects) + { + return; // No alinear si hay objetos bloqueados + } + var alignment = new ObjectAlignment(_selectedObjects, _selectedObjects.FirstOrDefault()); switch (alignmentType) @@ -901,6 +974,13 @@ namespace CtrEditor var viewModel = _mainWindow.DataContext as MainViewModel; if (viewModel == null) return; + // Verificar si hay objetos bloqueados antes de eliminar + bool hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement); + if (hasLockedObjects) + { + return; // No eliminar si hay objetos bloqueados + } + // Crear una copia de la lista para evitar modificaciones durante la iteración var objectsToRemove = _selectedObjects.ToList(); diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 098775a..91c0f00 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -78,6 +78,12 @@ namespace CtrEditor.ObjetosSim public UniqueId Id { get; set; } + + [ObservableProperty] + [property: Description("Lock object to mouse movement.")] + [property: Category("Layout:")] + private bool lock_movement; + [ObservableProperty] [property: Description("X coordinate.")] [property: Category("Layout:")]