Implementada la funcionalidad de bloqueo de movimiento para objetos: se agregó la propiedad 'lock_movement' en la clase osBase y se modificaron las funciones de manipulación de objetos para respetar este bloqueo, evitando redimensionamientos, movimientos y eliminaciones de objetos bloqueados.

This commit is contained in:
Miguel 2025-06-13 20:16:12 +02:00
parent b8d3c953e6
commit 0d8780b16f
2 changed files with 100 additions and 14 deletions

View File

@ -185,6 +185,9 @@ namespace CtrEditor
double rectHighlightSize = 1; double rectHighlightSize = 1;
RemoveResizeRectangles(); RemoveResizeRectangles();
// Verificar si hay objetos bloqueados
bool hasLockedObjects = selectedObjects.Any(obj => obj.Lock_movement);
// Calcular el bounding box que contenga todos los objetos seleccionados // Calcular el bounding box que contenga todos los objetos seleccionados
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects); Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
if (_selectedObjectsAreVisible) { if (_selectedObjectsAreVisible) {
@ -200,19 +203,23 @@ namespace CtrEditor
boundingBox.Top + boundingBox.Height / 2 boundingBox.Top + boundingBox.Height / 2
); );
// Selection rectangle // Siempre mostrar el rectángulo de selección
Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize); Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize, hasLockedObjects);
_resizeRectangles.Add(selectionRect); _resizeRectangles.Add(selectionRect);
_canvas.Children.Add(selectionRect); _canvas.Children.Add(selectionRect);
// Load rotation cursors // Solo agregar handles de manipulación si no hay objetos bloqueados
Cursor rotationCursorRx = new Cursor(Application.GetResourceStream( if (!hasLockedObjects)
new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationRx.cur")).Stream); {
Cursor rotationCursorSx = new Cursor(Application.GetResourceStream( // Load rotation cursors
new Uri("pack://application:,,,/CtrEditor;component/Icons/rotationSx.cur")).Stream); 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 // Add resize/rotation handles
AddResizeHandles(rectBox, 10, rotationCursorRx, rotationCursorSx); 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) || if (double.IsInfinity(rectBox.Width) || double.IsInfinity(rectBox.Height) ||
double.IsNaN(rectBox.Width) || double.IsNaN(rectBox.Height)) double.IsNaN(rectBox.Width) || double.IsNaN(rectBox.Height))
@ -256,16 +263,33 @@ namespace CtrEditor
throw new ArgumentException("Invalid dimensions for selection rectangle."); 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 var rect = new Rectangle
{ {
Width = rectBox.Width + (rectHighlightSize * 2), Width = rectBox.Width + (rectHighlightSize * 2),
Height = rectBox.Height + (rectHighlightSize * 2), Height = rectBox.Height + (rectHighlightSize * 2),
Fill = Brushes.Transparent, Fill = Brushes.Transparent,
Stroke = new SolidColorBrush(Color.FromArgb(180, 0, 120, 215)), Stroke = strokeBrush,
StrokeThickness = 1.5, StrokeThickness = 1.5,
Tag = "Selection", Tag = "Selection",
IsHitTestVisible = false, IsHitTestVisible = false,
StrokeDashArray = new DoubleCollection(new double[] { 3, 3 }) StrokeDashArray = dashArray
}; };
Canvas.SetLeft(rect, rectBox.Left - rectHighlightSize); Canvas.SetLeft(rect, rectBox.Left - rectHighlightSize);
@ -568,8 +592,18 @@ namespace CtrEditor
{ {
if (!_isDrawingCanvas) 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)) if (_resizeRectangles != null && _resizeRectangles.Contains(sender))
{ {
// Si hay objetos bloqueados, no permitir redimensionamiento
if (hasLockedObjects)
{
e.Handled = true;
return;
}
_currentDraggingRectangle = sender as Rectangle; _currentDraggingRectangle = sender as Rectangle;
_lastMousePosition = e.GetPosition(_canvas); _lastMousePosition = e.GetPosition(_canvas);
_currentDraggingRectangle.CaptureMouse(); _currentDraggingRectangle.CaptureMouse();
@ -585,16 +619,24 @@ namespace CtrEditor
if (userControl.DataContext is osBase datos) if (userControl.DataContext is osBase datos)
{ {
HandleObjectSelection(userControl, 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 // Solo iniciar el arrastre si no se presionó Ctrl y no hay objetos bloqueados
if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && !hasLockedObjects)
{ {
userControl.CaptureMouse(); userControl.CaptureMouse();
_currentDraggingControl = userControl; _currentDraggingControl = userControl;
_isMovingUserControl = true; _isMovingUserControl = true;
InitializeDrag(e); 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) private void HandleDrag(Point currentPosition)
{ {
PurgeDeletedObjects(); 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 dx = currentPosition.X - _startPointUserControl.X;
var dy = currentPosition.Y - _startPointUserControl.Y; var dy = currentPosition.Y - _startPointUserControl.Y;
@ -792,6 +842,14 @@ namespace CtrEditor
private void HandleResize(Point currentPosition, HandleMode mode) private void HandleResize(Point currentPosition, HandleMode mode)
{ {
PurgeDeletedObjects(); 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 RemoveAllSelectionHighlights(); // Remover antes de redimensionar
foreach (var selectedObject in _selectedObjects) foreach (var selectedObject in _selectedObjects)
@ -816,6 +874,14 @@ namespace CtrEditor
private void HandleRotation(Point currentPosition) private void HandleRotation(Point currentPosition)
{ {
PurgeDeletedObjects(); 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 RemoveAllSelectionHighlights(); // Remover antes de rotar
// Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados // Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
@ -845,6 +911,13 @@ namespace CtrEditor
PurgeDeletedObjects(); PurgeDeletedObjects();
if (_selectedObjects.Count <= 1) return; 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()); var alignment = new ObjectAlignment(_selectedObjects, _selectedObjects.FirstOrDefault());
switch (alignmentType) switch (alignmentType)
@ -901,6 +974,13 @@ namespace CtrEditor
var viewModel = _mainWindow.DataContext as MainViewModel; var viewModel = _mainWindow.DataContext as MainViewModel;
if (viewModel == null) return; 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 // Crear una copia de la lista para evitar modificaciones durante la iteración
var objectsToRemove = _selectedObjects.ToList(); var objectsToRemove = _selectedObjects.ToList();

View File

@ -78,6 +78,12 @@ namespace CtrEditor.ObjetosSim
public UniqueId Id { get; set; } public UniqueId Id { get; set; }
[ObservableProperty]
[property: Description("Lock object to mouse movement.")]
[property: Category("Layout:")]
private bool lock_movement;
[ObservableProperty] [ObservableProperty]
[property: Description("X coordinate.")] [property: Description("X coordinate.")]
[property: Category("Layout:")] [property: Category("Layout:")]