Se realizaron mejoras en la gestión de objetos visuales en la clase ObjectManipulationManager. Se optimizó la lógica para purgar objetos eliminados y se mejoró la rotación de objetos, permitiendo rotaciones en incrementos de 45 grados al mantener presionada la tecla Shift. Además, se ajustaron espacios en blanco y se mejoró la legibilidad del código en varias secciones.
This commit is contained in:
parent
75c507be4e
commit
ac8773ebc7
|
@ -173,8 +173,8 @@ namespace CtrEditor
|
|||
|
||||
private void PurgeDeletedObjects()
|
||||
{
|
||||
var deletedObjects = _selectedObjects.Where(obj =>
|
||||
obj.VisualRepresentation == null ||
|
||||
var deletedObjects = _selectedObjects.Where(obj =>
|
||||
obj.VisualRepresentation == null ||
|
||||
!_canvas.Children.Contains(obj.VisualRepresentation)).ToList();
|
||||
|
||||
foreach (var obj in deletedObjects)
|
||||
|
@ -202,7 +202,7 @@ namespace CtrEditor
|
|||
PurgeDeletedObjects();
|
||||
// Asegurarse de que el canvas haya actualizado su layout
|
||||
_canvas.UpdateLayout();
|
||||
|
||||
|
||||
RemoveResizeRectangles();
|
||||
if (_selectedObjects.Any())
|
||||
{
|
||||
|
@ -253,14 +253,15 @@ namespace CtrEditor
|
|||
public void AddResizeRectangles(IEnumerable<osBase> selectedObjects)
|
||||
{
|
||||
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
|
||||
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
|
||||
if (_selectedObjectsAreVisible) {
|
||||
if (_selectedObjectsAreVisible)
|
||||
{
|
||||
|
||||
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
|
||||
rectBox.Left -= (float)rectHighlightSize;
|
||||
|
@ -303,7 +304,7 @@ namespace CtrEditor
|
|||
|
||||
foreach (var obj in selectedObjects)
|
||||
{
|
||||
if (obj.VisualRepresentation != null && obj.VisualRepresentation.Visibility!=Visibility.Collapsed)
|
||||
if (obj.VisualRepresentation != null && obj.VisualRepresentation.Visibility != Visibility.Collapsed)
|
||||
{
|
||||
// Obtener el bounding box del objeto actual
|
||||
Rect objectBounds = VisualTreeHelper.GetDescendantBounds(obj.VisualRepresentation);
|
||||
|
@ -336,7 +337,7 @@ namespace CtrEditor
|
|||
// 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)
|
||||
|
@ -377,10 +378,10 @@ namespace CtrEditor
|
|||
// Calcular el tamaño apropiado para los manejadores basado en el tamaño del objeto
|
||||
double minObjectDimension = Math.Min(rectBox.Width, rectBox.Height);
|
||||
double rectSize = Math.Min(defaultRectSize, minObjectDimension / 3);
|
||||
|
||||
|
||||
// Asegurar un tamaño mínimo para los manejadores
|
||||
rectSize = Math.Max(rectSize, 6);
|
||||
|
||||
|
||||
// Calcular el offset para posicionar los manejadores fuera del rectángulo
|
||||
double offset = rectSize / 2;
|
||||
|
||||
|
@ -419,9 +420,9 @@ namespace CtrEditor
|
|||
return (Cursors.SizeWE, Cursors.SizeNS, Cursors.SizeNWSE);
|
||||
|
||||
double angle = Math.Abs(firstObject.Angulo % 360);
|
||||
|
||||
|
||||
// Si el objeto no está significativamente rotado, usar cursores estándar
|
||||
if (angle < 15 || (angle > 345 && angle < 360) ||
|
||||
if (angle < 15 || (angle > 345 && angle < 360) ||
|
||||
(angle > 165 && angle < 195))
|
||||
{
|
||||
return (Cursors.SizeWE, Cursors.SizeNS, Cursors.SizeNWSE);
|
||||
|
@ -569,7 +570,7 @@ namespace CtrEditor
|
|||
}
|
||||
|
||||
UpdateSelectionVisuals();
|
||||
|
||||
|
||||
// Update the view model's selection state
|
||||
vm.NotifySelectionChanged();
|
||||
}
|
||||
|
@ -583,7 +584,7 @@ namespace CtrEditor
|
|||
_selectedObjects.Remove(obj);
|
||||
obj.IsSelected = false;
|
||||
RemoveSelectionHighlight(obj.VisualRepresentation);
|
||||
|
||||
|
||||
// Update the view model's selection state
|
||||
if (_mainWindow.DataContext is MainViewModel vm)
|
||||
{
|
||||
|
@ -652,7 +653,7 @@ namespace CtrEditor
|
|||
Width = transformedBoundingBox.Width,
|
||||
Height = transformedBoundingBox.Height,
|
||||
Fill = Brushes.Transparent,
|
||||
Stroke = new SolidColorBrush(isReference ?
|
||||
Stroke = new SolidColorBrush(isReference ?
|
||||
Color.FromArgb(180, 128, 0, 128) : // Purple for reference
|
||||
Color.FromArgb(180, 255, 0, 0)), // Red for others
|
||||
StrokeThickness = isReference ? 3 : 2, // Más grueso para el de referencia
|
||||
|
@ -715,7 +716,7 @@ namespace CtrEditor
|
|||
{
|
||||
// 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
|
||||
|
@ -724,10 +725,10 @@ namespace CtrEditor
|
|||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Capturar estado antes de iniciar redimensionamiento
|
||||
CaptureUndoState();
|
||||
|
||||
|
||||
_currentDraggingRectangle = sender as Rectangle;
|
||||
_lastMousePosition = e.GetPosition(_canvas);
|
||||
_currentDraggingRectangle.CaptureMouse();
|
||||
|
@ -741,10 +742,10 @@ namespace CtrEditor
|
|||
if (userControl != null && userControl.DataContext is osBase datos)
|
||||
{
|
||||
bool isControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
|
||||
|
||||
|
||||
// Determinar qué objetos serán afectados por el movimiento
|
||||
List<osBase> objectsToMove = new List<osBase>();
|
||||
|
||||
|
||||
if (!isControlPressed)
|
||||
{
|
||||
// Si no está Ctrl presionado y vamos a hacer dragging
|
||||
|
@ -758,28 +759,28 @@ namespace CtrEditor
|
|||
// Si no está seleccionado, solo vamos a mover este objeto
|
||||
objectsToMove.Add(datos);
|
||||
}
|
||||
|
||||
|
||||
// Verificar si alguno de los objetos a mover está bloqueado
|
||||
bool willMoveLockedObjects = objectsToMove.Any(obj => obj.Lock_movement);
|
||||
|
||||
|
||||
if (!willMoveLockedObjects)
|
||||
{
|
||||
// Capturar estado antes de iniciar movimiento
|
||||
CaptureUndoStateForObjects(objectsToMove);
|
||||
|
||||
|
||||
userControl.CaptureMouse();
|
||||
_currentDraggingControl = userControl;
|
||||
_isMovingUserControl = true;
|
||||
InitializeDrag(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Manejar la selección después de capturar el estado
|
||||
HandleObjectSelection(userControl, datos);
|
||||
|
||||
|
||||
// Actualizar el estado de objetos bloqueados después de la selección
|
||||
hasLockedObjects = _selectedObjects.Any(obj => obj.Lock_movement);
|
||||
|
||||
|
||||
if (hasLockedObjects && !isControlPressed)
|
||||
{
|
||||
// Si hay objetos bloqueados, no permitir el inicio del arrastre
|
||||
|
@ -831,14 +832,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;
|
||||
|
||||
|
@ -992,11 +993,11 @@ namespace CtrEditor
|
|||
return HandleMode.None;
|
||||
|
||||
double angle = Math.Abs(firstObject.Angulo % 360);
|
||||
|
||||
|
||||
// Si el objeto no está significativamente rotado, usar el comportamiento por defecto
|
||||
if (angle < 15 || (angle > 345 && angle < 360) ||
|
||||
(angle > 75 && angle < 105) ||
|
||||
(angle > 165 && angle < 195) ||
|
||||
if (angle < 15 || (angle > 345 && angle < 360) ||
|
||||
(angle > 75 && angle < 105) ||
|
||||
(angle > 165 && angle < 195) ||
|
||||
(angle > 255 && angle < 285))
|
||||
{
|
||||
return DetermineHandleModeDefault(resizeDirection);
|
||||
|
@ -1038,14 +1039,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)
|
||||
|
@ -1080,13 +1081,13 @@ namespace CtrEditor
|
|||
// Para objetos rotados, transformar los cambios del mouse según la orientación del objeto
|
||||
// Convertir ángulo de grados a radianes
|
||||
double angleRad = obj.Angulo * Math.PI / 180.0;
|
||||
|
||||
|
||||
// Calcular los componentes de cambio transformados según la rotación
|
||||
// Rotar el vector de cambio por el ángulo negativo del objeto para obtener
|
||||
// los cambios en el sistema de coordenadas local del objeto
|
||||
double cos = Math.Cos(-angleRad);
|
||||
double sin = Math.Sin(-angleRad);
|
||||
|
||||
|
||||
double localDeltaX = deltaX * cos - deltaY * sin;
|
||||
double localDeltaY = deltaX * sin + deltaY * cos;
|
||||
|
||||
|
@ -1115,16 +1116,19 @@ 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
|
||||
|
||||
// Verificar si la tecla Shift está presionada para rotación en incrementos de 45 grados
|
||||
bool isShiftPressed = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
|
||||
|
||||
// Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
|
||||
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
|
||||
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
|
||||
|
@ -1137,11 +1141,48 @@ namespace CtrEditor
|
|||
else
|
||||
{
|
||||
double deltaAngle = angle - _lastAngle;
|
||||
foreach (var selectedObject in _selectedObjects)
|
||||
|
||||
if (isShiftPressed)
|
||||
{
|
||||
selectedObject.Rotate(deltaAngle);
|
||||
// Rotación en incrementos de 45 grados
|
||||
// Calcular el ángulo total acumulado desde el inicio de la rotación
|
||||
double totalAngleChange = angle - _lastAngle;
|
||||
|
||||
// Determinar a qué incremento de 45 grados corresponde
|
||||
double snapAngle = Math.Round(totalAngleChange / 45.0) * 45.0;
|
||||
|
||||
// Solo aplicar la rotación si hay un cambio significativo (al menos 22.5 grados de movimiento)
|
||||
if (Math.Abs(totalAngleChange) > 22.5)
|
||||
{
|
||||
// Calcular el cambio real que necesitamos aplicar
|
||||
double actualRotationChange = snapAngle;
|
||||
|
||||
foreach (var selectedObject in _selectedObjects)
|
||||
{
|
||||
// Obtener el ángulo actual del objeto
|
||||
double currentObjectAngle = selectedObject.Angulo;
|
||||
|
||||
// Calcular el nuevo ángulo alineado a incrementos de 45 grados
|
||||
double targetAngle = Math.Round((currentObjectAngle + actualRotationChange) / 45.0) * 45.0;
|
||||
|
||||
// Aplicar la rotación necesaria para llegar al ángulo objetivo
|
||||
double rotationNeeded = targetAngle - currentObjectAngle;
|
||||
selectedObject.Rotate(rotationNeeded);
|
||||
}
|
||||
|
||||
// Actualizar el ángulo de referencia para evitar aplicar la misma rotación múltiples veces
|
||||
_lastAngle = (float)angle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rotación libre (comportamiento original)
|
||||
foreach (var selectedObject in _selectedObjects)
|
||||
{
|
||||
selectedObject.Rotate(deltaAngle);
|
||||
}
|
||||
_lastAngle = (float)angle;
|
||||
}
|
||||
_lastAngle = (float)angle;
|
||||
}
|
||||
|
||||
UpdateAllSelectionHighlights();
|
||||
|
@ -1237,10 +1278,10 @@ namespace CtrEditor
|
|||
ClearSelection();
|
||||
RemoveResizeRectangles();
|
||||
RemoveAllSelectionHighlights();
|
||||
|
||||
|
||||
// Ensure the property panel is cleared by explicitly setting SelectedItemOsList to null
|
||||
viewModel.SelectedItemOsList = null;
|
||||
|
||||
|
||||
// Actualizar el estado de cambios sin guardar
|
||||
if (viewModel != null)
|
||||
{
|
||||
|
@ -1339,7 +1380,7 @@ namespace CtrEditor
|
|||
{
|
||||
// Capturar solo el estado de los objetos seleccionados
|
||||
var undoState = new UndoState(_selectedObjects);
|
||||
|
||||
|
||||
// Mantener solo los últimos MaxUndoSteps estados
|
||||
if (_undoHistory.Count >= MaxUndoSteps)
|
||||
{
|
||||
|
@ -1353,7 +1394,7 @@ namespace CtrEditor
|
|||
_undoHistory.Push(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_undoHistory.Push(undoState);
|
||||
Console.WriteLine($"Estado capturado para undo de {_selectedObjects.Count} objetos. Historial: {_undoHistory.Count} estados");
|
||||
}
|
||||
|
@ -1374,7 +1415,7 @@ namespace CtrEditor
|
|||
{
|
||||
// Capturar solo el estado de los objetos especificados
|
||||
var undoState = new UndoState(objectsList);
|
||||
|
||||
|
||||
// Mantener solo los últimos MaxUndoSteps estados
|
||||
if (_undoHistory.Count >= MaxUndoSteps)
|
||||
{
|
||||
|
@ -1388,7 +1429,7 @@ namespace CtrEditor
|
|||
_undoHistory.Push(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_undoHistory.Push(undoState);
|
||||
Console.WriteLine($"Estado capturado para undo de {objectsList.Count} objetos específicos. Historial: {_undoHistory.Count} estados");
|
||||
}
|
||||
|
@ -1417,7 +1458,7 @@ namespace CtrEditor
|
|||
if (_mainWindow.DataContext is MainViewModel viewModel)
|
||||
{
|
||||
_isApplyingUndo = true;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var undoState = _undoHistory.Pop();
|
||||
|
@ -1443,10 +1484,10 @@ namespace CtrEditor
|
|||
|
||||
// Actualizar los visuales de selección
|
||||
UpdateSelectionVisuals();
|
||||
|
||||
|
||||
// Marcar como cambios sin guardar
|
||||
viewModel.HasUnsavedChanges = true;
|
||||
|
||||
|
||||
Console.WriteLine("Undo aplicado exitosamente");
|
||||
}
|
||||
finally
|
||||
|
|
Loading…
Reference in New Issue