Compare commits
3 Commits
3dab570f5d
...
326c615887
Author | SHA1 | Date |
---|---|---|
|
326c615887 | |
|
5ee91dd26a | |
|
67c6464ea1 |
|
@ -1,14 +1,12 @@
|
||||||
using System.Globalization;
|
using CtrEditor.ObjetosSim;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using System.Diagnostics;
|
|
||||||
using CtrEditor.ObjetosSim;
|
|
||||||
using CtrEditor.FuncionesBase;
|
|
||||||
using Xceed.Wpf.Toolkit.PropertyGrid;
|
|
||||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||||
using UserControl = System.Windows.Controls.UserControl;
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
|
|
||||||
|
@ -134,10 +132,12 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
_isDraggingCanvas = false;
|
_isDraggingCanvas = false;
|
||||||
ImagenEnTrabajoCanvas.ReleaseMouseCapture();
|
ImagenEnTrabajoCanvas.ReleaseMouseCapture();
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
|
||||||
if (DataContext is MainViewModel viewModel && viewModel.SelectedItemOsList != null)
|
if (_objectManager.SelectedObjects.Count > 0)
|
||||||
{
|
{
|
||||||
_objectManager.MakeResizeRectanglesNormal();
|
_objectManager.MakeResizeRectanglesNormal();
|
||||||
|
_objectManager.UpdateSelectionVisuals(); // Agregar esta línea
|
||||||
}
|
}
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
@ -147,12 +147,14 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
if (e.LeftButton == MouseButtonState.Pressed && !_isDrawingCanvas)
|
if (e.LeftButton == MouseButtonState.Pressed && !_isDrawingCanvas)
|
||||||
{
|
{
|
||||||
// Solo activar el panning si el clic fue directamente en el canvas
|
// Solo permitir el panning si el clic fue en el canvas o en la imagen de fondo
|
||||||
if (e.Source == ImagenEnTrabajoCanvas)
|
// y no en otros controles
|
||||||
|
if (e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo)
|
||||||
{
|
{
|
||||||
_isDraggingCanvas = true;
|
_isDraggingCanvas = true;
|
||||||
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
|
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
|
||||||
ImagenEnTrabajoCanvas.CaptureMouse();
|
ImagenEnTrabajoCanvas.CaptureMouse();
|
||||||
|
Mouse.OverrideCursor = Cursors.Hand;
|
||||||
|
|
||||||
if (DataContext is MainViewModel viewModel)
|
if (DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
|
@ -224,9 +226,10 @@ namespace CtrEditor
|
||||||
|
|
||||||
RenderOptions.SetBitmapScalingMode(ImagenEnTrabajoCanvas, BitmapScalingMode.HighQuality);
|
RenderOptions.SetBitmapScalingMode(ImagenEnTrabajoCanvas, BitmapScalingMode.HighQuality);
|
||||||
|
|
||||||
if (DataContext is MainViewModel viewModel && viewModel.SelectedItemOsList != null)
|
if (_objectManager.SelectedObjects.Count > 0)
|
||||||
{
|
{
|
||||||
_objectManager.MakeResizeRectanglesNormal();
|
_objectManager.MakeResizeRectanglesNormal();
|
||||||
|
_objectManager.UpdateSelectionVisuals(); // Agregar esta línea
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -293,14 +296,12 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
// Limpiar la selección en el ListBox
|
// Limpiar la selección en el ListBox
|
||||||
viewModel.SelectedItemOsList = null;
|
viewModel.SelectedItemOsList = null;
|
||||||
|
|
||||||
// Limpiar la selección múltiple
|
// Limpiar la selección múltiple
|
||||||
_objectManager.ClearSelection();
|
_objectManager.ClearSelection();
|
||||||
_objectManager.RemoveResizeRectangles();
|
_objectManager.RemoveResizeRectangles();
|
||||||
|
|
||||||
// Desactivar el modo de selección múltiple
|
|
||||||
viewModel.IsMultiSelectionActive = false;
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,9 +374,10 @@ namespace CtrEditor
|
||||||
private void Canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
private void Canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
// Aceptar el evento si viene del canvas o de la imagen de fondo
|
// Aceptar el evento si viene del canvas o de la imagen de fondo
|
||||||
if ((e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo) && DataContext is MainViewModel viewModel)
|
if ((e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo || e.Source is UserControl) &&
|
||||||
|
DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
e.Handled = true; // Importante: marcar el evento como manejado
|
e.Handled = true;
|
||||||
ShowContextMenu(e.GetPosition(ImagenEnTrabajoCanvas));
|
ShowContextMenu(e.GetPosition(ImagenEnTrabajoCanvas));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,26 +385,60 @@ namespace CtrEditor
|
||||||
private void ShowContextMenu(Point position)
|
private void ShowContextMenu(Point position)
|
||||||
{
|
{
|
||||||
var contextMenu = new ContextMenu();
|
var contextMenu = new ContextMenu();
|
||||||
var multiSelectMenuItem = new MenuItem
|
var multiSelectMenuItem = new MenuItem
|
||||||
{
|
{
|
||||||
Header = "Modo Multi-Selección",
|
Header = "Modo Multi-Selección",
|
||||||
IsCheckable = true,
|
IsCheckable = true,
|
||||||
StaysOpenOnClick = false // Cerrar el menú al hacer clic
|
StaysOpenOnClick = false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (DataContext is MainViewModel viewModel)
|
if (DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
multiSelectMenuItem.IsChecked = viewModel.IsMultiSelectionActive;
|
multiSelectMenuItem.IsChecked = viewModel.IsMultiSelectionActive;
|
||||||
multiSelectMenuItem.Click += (s, e) =>
|
multiSelectMenuItem.Click += (s, e) =>
|
||||||
{
|
{
|
||||||
viewModel.IsMultiSelectionActive = multiSelectMenuItem.IsChecked;
|
viewModel.IsMultiSelectionActive = multiSelectMenuItem.IsChecked;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
contextMenu.Items.Add(multiSelectMenuItem);
|
// Solo mostrar opciones de alineación si hay objetos seleccionados
|
||||||
contextMenu.PlacementTarget = ImagenEnTrabajoCanvas;
|
if (_objectManager.SelectedObjects.Count > 1)
|
||||||
contextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint;
|
{
|
||||||
contextMenu.IsOpen = true;
|
var alignmentMenu = new MenuItem { Header = "Alinear" };
|
||||||
|
var sizeMenu = new MenuItem { Header = "Igualar Tamaño" };
|
||||||
|
var joinMenu = new MenuItem { Header = "Unir" };
|
||||||
|
|
||||||
|
// Opciones de alineación
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Alinear a la Izquierda", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.Left)) });
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Alinear a la Derecha", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.Right)) });
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Alinear Arriba", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.Top)) });
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Alinear Abajo", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.Bottom)) });
|
||||||
|
alignmentMenu.Items.Add(new Separator());
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Centrar Horizontalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.CenterHorizontally)) });
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Centrar Verticalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.CenterVertically)) });
|
||||||
|
alignmentMenu.Items.Add(new Separator());
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Distribuir Horizontalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.DistributeHorizontally)) });
|
||||||
|
alignmentMenu.Items.Add(new MenuItem { Header = "Distribuir Verticalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.DistributeVertically)) });
|
||||||
|
|
||||||
|
// Opciones de igualar tamaño
|
||||||
|
sizeMenu.Items.Add(new MenuItem { Header = "Igualar Ancho", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.EqualWidth)) });
|
||||||
|
sizeMenu.Items.Add(new MenuItem { Header = "Igualar Alto", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.EqualHeight)) });
|
||||||
|
sizeMenu.Items.Add(new MenuItem { Header = "Igualar Ángulo", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.EqualAngle)) });
|
||||||
|
|
||||||
|
// Opciones de unir
|
||||||
|
joinMenu.Items.Add(new MenuItem { Header = "Unir Horizontalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.JoinHorizontally)) });
|
||||||
|
joinMenu.Items.Add(new MenuItem { Header = "Unir Verticalmente", Command = new RelayCommand(() => _objectManager.AlignObjects(AlignmentType.JoinVertically)) });
|
||||||
|
|
||||||
|
contextMenu.Items.Add(alignmentMenu);
|
||||||
|
contextMenu.Items.Add(sizeMenu);
|
||||||
|
contextMenu.Items.Add(joinMenu);
|
||||||
|
contextMenu.Items.Add(new Separator());
|
||||||
|
}
|
||||||
|
|
||||||
|
contextMenu.Items.Add(multiSelectMenuItem);
|
||||||
|
contextMenu.PlacementTarget = ImagenEnTrabajoCanvas;
|
||||||
|
contextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint;
|
||||||
|
contextMenu.IsOpen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,230 @@
|
||||||
|
using CtrEditor.ObjetosSim;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace CtrEditor
|
||||||
|
{
|
||||||
|
public class ObjectAlignment
|
||||||
|
{
|
||||||
|
private readonly ObservableCollection<osBase> _selectedObjects;
|
||||||
|
|
||||||
|
public ObjectAlignment(ObservableCollection<osBase> selectedObjects)
|
||||||
|
{
|
||||||
|
_selectedObjects = selectedObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignLeft()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float leftMost = _selectedObjects.Min(obj => obj.Left);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Left = leftMost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignRight()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float rightMost = _selectedObjects.Max(obj => obj.Left + obj.Ancho);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Left = rightMost - obj.Ancho;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignTop()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float topMost = _selectedObjects.Min(obj => obj.Top);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Top = topMost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignBottom()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float bottomMost = _selectedObjects.Max(obj => obj.Top + obj.Alto);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Top = bottomMost - obj.Alto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignCenterHorizontally()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float averageY = _selectedObjects.Average(obj => obj.Top + obj.Alto / 2);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Top = averageY - obj.Alto / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignCenterVertically()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float averageX = _selectedObjects.Average(obj => obj.Left + obj.Ancho / 2);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Left = averageX - obj.Ancho / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DistributeHorizontally()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 2) return;
|
||||||
|
|
||||||
|
// Ordenar objetos por su centro X real (considerando rotación)
|
||||||
|
var objectsWithCenters = _selectedObjects
|
||||||
|
.Select(obj => new
|
||||||
|
{
|
||||||
|
Object = obj,
|
||||||
|
Center = GetObjectCenter(obj)
|
||||||
|
})
|
||||||
|
.OrderBy(x => x.Center.X)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Calcular el espacio total y el espaciado
|
||||||
|
float leftMost = (float)objectsWithCenters.First().Center.X;
|
||||||
|
float rightMost = (float)objectsWithCenters.Last().Center.X;
|
||||||
|
float totalWidth = rightMost - leftMost;
|
||||||
|
float spacing = totalWidth / (_selectedObjects.Count - 1);
|
||||||
|
|
||||||
|
// Distribuir objetos basados en sus centros
|
||||||
|
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
||||||
|
{
|
||||||
|
var obj = objectsWithCenters[i].Object;
|
||||||
|
var targetCenterX = leftMost + (spacing * i);
|
||||||
|
var currentCenter = GetObjectCenter(obj);
|
||||||
|
var deltaX = targetCenterX - currentCenter.X;
|
||||||
|
|
||||||
|
obj.Left += (float)deltaX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DistributeVertically()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 2) return;
|
||||||
|
|
||||||
|
// Ordenar objetos por su centro Y real (considerando rotación)
|
||||||
|
var objectsWithCenters = _selectedObjects
|
||||||
|
.Select(obj => new
|
||||||
|
{
|
||||||
|
Object = obj,
|
||||||
|
Center = GetObjectCenter(obj)
|
||||||
|
})
|
||||||
|
.OrderBy(x => x.Center.Y)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Calcular el espacio total y el espaciado
|
||||||
|
float topMost = (float)objectsWithCenters.First().Center.Y;
|
||||||
|
float bottomMost = (float)objectsWithCenters.Last().Center.Y;
|
||||||
|
float totalHeight = bottomMost - topMost;
|
||||||
|
float spacing = totalHeight / (_selectedObjects.Count - 1);
|
||||||
|
|
||||||
|
// Distribuir objetos basados en sus centros
|
||||||
|
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
||||||
|
{
|
||||||
|
var obj = objectsWithCenters[i].Object;
|
||||||
|
var targetCenterY = topMost + (spacing * i);
|
||||||
|
var currentCenter = GetObjectCenter(obj);
|
||||||
|
var deltaY = targetCenterY - currentCenter.Y;
|
||||||
|
|
||||||
|
obj.Top += (float)deltaY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EqualWidth()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float averageWidth = _selectedObjects.Average(obj => obj.Ancho);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Ancho = averageWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EqualHeight()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float averageHeight = _selectedObjects.Average(obj => obj.Alto);
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Alto = averageHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EqualAngle()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
float referenceAngle = _selectedObjects.First().Angulo;
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
obj.Angulo = referenceAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void JoinHorizontally()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
var sortedObjects = _selectedObjects
|
||||||
|
.OrderBy(obj => obj.Left)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
for (int i = 1; i < sortedObjects.Count; i++)
|
||||||
|
{
|
||||||
|
var previousObj = sortedObjects[i - 1];
|
||||||
|
var currentObj = sortedObjects[i];
|
||||||
|
currentObj.Left = previousObj.Left + previousObj.Ancho;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void JoinVertically()
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
var sortedObjects = _selectedObjects
|
||||||
|
.OrderBy(obj => obj.Top)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
for (int i = 1; i < sortedObjects.Count; i++)
|
||||||
|
{
|
||||||
|
var previousObj = sortedObjects[i - 1];
|
||||||
|
var currentObj = sortedObjects[i];
|
||||||
|
currentObj.Top = previousObj.Top + previousObj.Alto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point GetObjectCenter(osBase obj)
|
||||||
|
{
|
||||||
|
double angleRad = obj.Angulo * Math.PI / 180.0;
|
||||||
|
float centerX = obj.Left + (obj.Ancho / 2);
|
||||||
|
float centerY = obj.Top + (obj.Alto / 2);
|
||||||
|
|
||||||
|
// Si el objeto está rotado, calcular el centro real
|
||||||
|
if (obj.Angulo != 0)
|
||||||
|
{
|
||||||
|
// Obtener el centro después de la rotación
|
||||||
|
var rotatedX = obj.Left + (Math.Cos(angleRad) * obj.Ancho / 2 - Math.Sin(angleRad) * obj.Alto / 2);
|
||||||
|
var rotatedY = obj.Top + (Math.Sin(angleRad) * obj.Ancho / 2 + Math.Cos(angleRad) * obj.Alto / 2);
|
||||||
|
|
||||||
|
return new Point(rotatedX, rotatedY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Point(centerX, centerY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,32 @@
|
||||||
using System.Windows;
|
using CtrEditor.FuncionesBase;
|
||||||
|
using CtrEditor.ObjetosSim;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using System.Windows.Threading;
|
|
||||||
using CtrEditor.FuncionesBase;
|
|
||||||
using CtrEditor.ObjetosSim;
|
|
||||||
using Color = System.Windows.Media.Color;
|
using Color = System.Windows.Media.Color;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
|
|
||||||
namespace CtrEditor
|
namespace CtrEditor
|
||||||
{
|
{
|
||||||
|
public enum AlignmentType
|
||||||
|
{
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
CenterHorizontally,
|
||||||
|
CenterVertically,
|
||||||
|
DistributeHorizontally,
|
||||||
|
DistributeVertically,
|
||||||
|
EqualWidth,
|
||||||
|
EqualHeight,
|
||||||
|
EqualAngle,
|
||||||
|
JoinHorizontally,
|
||||||
|
JoinVertically
|
||||||
|
}
|
||||||
|
|
||||||
public class ObjectManipulationManager
|
public class ObjectManipulationManager
|
||||||
{
|
{
|
||||||
private enum ResizeMode
|
private enum ResizeMode
|
||||||
|
@ -50,6 +66,8 @@ namespace CtrEditor
|
||||||
private Rectangle _currentDraggingRectangle;
|
private Rectangle _currentDraggingRectangle;
|
||||||
private dataDebug _dataDebug = new dataDebug();
|
private dataDebug _dataDebug = new dataDebug();
|
||||||
private ObservableCollection<osBase> _selectedObjects = new ObservableCollection<osBase>();
|
private ObservableCollection<osBase> _selectedObjects = new ObservableCollection<osBase>();
|
||||||
|
private List<Rectangle> _selectionHighlightRectangles = new List<Rectangle>(); // Add this line
|
||||||
|
private List<(UserControl Control, Rectangle Highlight)> _selectionHighlightPairs = new List<(UserControl, Rectangle)>();
|
||||||
|
|
||||||
public ObjectManipulationManager(MainWindow mainWindow, Canvas canvas)
|
public ObjectManipulationManager(MainWindow mainWindow, Canvas canvas)
|
||||||
{
|
{
|
||||||
|
@ -67,7 +85,7 @@ namespace CtrEditor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSelectionVisuals()
|
public void UpdateSelectionVisuals()
|
||||||
{
|
{
|
||||||
RemoveResizeRectangles();
|
RemoveResizeRectangles();
|
||||||
if (_selectedObjects.Any())
|
if (_selectedObjects.Any())
|
||||||
|
@ -118,7 +136,7 @@ namespace CtrEditor
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
|
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
|
||||||
rectBox.Left -= (float)rectHighlightSize;
|
rectBox.Left -= (float)rectHighlightSize;
|
||||||
rectBox.Right += (float)rectHighlightSize;
|
rectBox.Right += (float)rectHighlightSize;
|
||||||
|
@ -324,6 +342,10 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
_selectedObjects.Add(obj);
|
_selectedObjects.Add(obj);
|
||||||
obj.IsSelected = true;
|
obj.IsSelected = true;
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
|
||||||
|
{
|
||||||
|
AddSelectionHighlight(obj.VisualRepresentation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +355,7 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
_selectedObjects.Remove(obj);
|
_selectedObjects.Remove(obj);
|
||||||
obj.IsSelected = false;
|
obj.IsSelected = false;
|
||||||
|
RemoveSelectionHighlight(obj.VisualRepresentation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +365,9 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
DeselectObject(obj);
|
DeselectObject(obj);
|
||||||
}
|
}
|
||||||
|
RemoveAllSelectionHighlights();
|
||||||
RemoveResizeRectangles();
|
RemoveResizeRectangles();
|
||||||
|
|
||||||
if (_mainWindow.DataContext is MainViewModel viewModel)
|
if (_mainWindow.DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
viewModel.SelectedItemOsList = null;
|
viewModel.SelectedItemOsList = null;
|
||||||
|
@ -361,6 +385,82 @@ namespace CtrEditor
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
SelectObject(lastSelected);
|
SelectObject(lastSelected);
|
||||||
}
|
}
|
||||||
|
RemoveAllSelectionHighlights();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agregar destacados de selección para los objetos ya seleccionados
|
||||||
|
foreach (var obj in _selectedObjects)
|
||||||
|
{
|
||||||
|
if (obj.VisualRepresentation != null)
|
||||||
|
{
|
||||||
|
AddSelectionHighlight(obj.VisualRepresentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddSelectionHighlight(UserControl userControl)
|
||||||
|
{
|
||||||
|
if (userControl == null) return;
|
||||||
|
|
||||||
|
// Primero remover cualquier highlight existente para este control
|
||||||
|
RemoveSelectionHighlight(userControl);
|
||||||
|
|
||||||
|
Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
|
||||||
|
GeneralTransform transform = userControl.TransformToAncestor(_canvas);
|
||||||
|
Rect transformedBoundingBox = transform.TransformBounds(boundingBox);
|
||||||
|
|
||||||
|
Rectangle highlightRect = new Rectangle
|
||||||
|
{
|
||||||
|
Width = transformedBoundingBox.Width,
|
||||||
|
Height = transformedBoundingBox.Height,
|
||||||
|
Fill = Brushes.Transparent,
|
||||||
|
Stroke = new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
|
||||||
|
StrokeThickness = 2,
|
||||||
|
Tag = "SelectionHighlight",
|
||||||
|
IsHitTestVisible = false
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.SetLeft(highlightRect, transformedBoundingBox.Left);
|
||||||
|
Canvas.SetTop(highlightRect, transformedBoundingBox.Top);
|
||||||
|
Canvas.SetZIndex(highlightRect, (int)ZIndexEnum.RectangulosPropiead - 1);
|
||||||
|
|
||||||
|
_selectionHighlightPairs.Add((userControl, highlightRect));
|
||||||
|
_canvas.Children.Add(highlightRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveSelectionHighlight(UserControl userControl)
|
||||||
|
{
|
||||||
|
var pairsToRemove = _selectionHighlightPairs.Where(p => p.Control == userControl).ToList();
|
||||||
|
foreach (var pair in pairsToRemove)
|
||||||
|
{
|
||||||
|
_canvas.Children.Remove(pair.Highlight);
|
||||||
|
_selectionHighlightPairs.Remove(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAllSelectionHighlights()
|
||||||
|
{
|
||||||
|
foreach (var pair in _selectionHighlightPairs)
|
||||||
|
{
|
||||||
|
_canvas.Children.Remove(pair.Highlight);
|
||||||
|
}
|
||||||
|
_selectionHighlightPairs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelectionHighlights()
|
||||||
|
{
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
|
||||||
|
{
|
||||||
|
RemoveAllSelectionHighlights();
|
||||||
|
foreach (var selectedObject in _selectedObjects)
|
||||||
|
{
|
||||||
|
if (selectedObject.VisualRepresentation != null)
|
||||||
|
{
|
||||||
|
AddSelectionHighlight(selectedObject.VisualRepresentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,6 +543,8 @@ namespace CtrEditor
|
||||||
var dx = currentPosition.X - _startPointUserControl.X;
|
var dx = currentPosition.X - _startPointUserControl.X;
|
||||||
var dy = currentPosition.Y - _startPointUserControl.Y;
|
var dy = currentPosition.Y - _startPointUserControl.Y;
|
||||||
|
|
||||||
|
RemoveAllSelectionHighlights(); // Remover antes de mover
|
||||||
|
|
||||||
foreach (var selectedObject in _selectedObjects)
|
foreach (var selectedObject in _selectedObjects)
|
||||||
{
|
{
|
||||||
var newX = Canvas.GetLeft(selectedObject.VisualRepresentation) + dx;
|
var newX = Canvas.GetLeft(selectedObject.VisualRepresentation) + dx;
|
||||||
|
@ -450,6 +552,8 @@ namespace CtrEditor
|
||||||
selectedObject.Move((float)newX, (float)newY);
|
selectedObject.Move((float)newX, (float)newY);
|
||||||
}
|
}
|
||||||
_startPointUserControl = currentPosition;
|
_startPointUserControl = currentPosition;
|
||||||
|
|
||||||
|
UpdateSelectionHighlights();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||||
|
@ -465,7 +569,18 @@ namespace CtrEditor
|
||||||
rectangle.ReleaseMouseCapture();
|
rectangle.ReleaseMouseCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveAllSelectionHighlights(); // Remover antes de actualizar
|
||||||
UpdateSelectionVisuals();
|
UpdateSelectionVisuals();
|
||||||
|
|
||||||
|
// Restaurar los rectángulos de selección si es necesario
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel && viewModel.IsMultiSelectionActive)
|
||||||
|
{
|
||||||
|
foreach (var selectedObject in _selectedObjects)
|
||||||
|
{
|
||||||
|
AddSelectionHighlight(selectedObject.VisualRepresentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_isDraggingUserControl = false;
|
_isDraggingUserControl = false;
|
||||||
_isMovingUserControl = false;
|
_isMovingUserControl = false;
|
||||||
_currentDraggingRectangle = null;
|
_currentDraggingRectangle = null;
|
||||||
|
@ -574,6 +689,8 @@ namespace CtrEditor
|
||||||
|
|
||||||
private void HandleResize(Point currentPosition, HandleMode mode)
|
private void HandleResize(Point currentPosition, HandleMode mode)
|
||||||
{
|
{
|
||||||
|
RemoveAllSelectionHighlights(); // Remover antes de redimensionar
|
||||||
|
|
||||||
foreach (var selectedObject in _selectedObjects)
|
foreach (var selectedObject in _selectedObjects)
|
||||||
{
|
{
|
||||||
bool resizeWidth = mode == HandleMode.ResizeWidth || mode == HandleMode.ResizeBoth;
|
bool resizeWidth = mode == HandleMode.ResizeWidth || mode == HandleMode.ResizeBoth;
|
||||||
|
@ -581,6 +698,8 @@ namespace CtrEditor
|
||||||
HandleResizeForObject(selectedObject, currentPosition, resizeWidth, resizeHeight);
|
HandleResizeForObject(selectedObject, currentPosition, resizeWidth, resizeHeight);
|
||||||
}
|
}
|
||||||
_startPointUserControl = currentPosition;
|
_startPointUserControl = currentPosition;
|
||||||
|
|
||||||
|
UpdateSelectionHighlights();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleResizeForObject(osBase obj, Point currentPosition, bool activateSizeWidth, bool activateSizeHeight)
|
private void HandleResizeForObject(osBase obj, Point currentPosition, bool activateSizeWidth, bool activateSizeHeight)
|
||||||
|
@ -593,6 +712,8 @@ namespace CtrEditor
|
||||||
|
|
||||||
private void HandleRotation(Point currentPosition)
|
private void HandleRotation(Point currentPosition)
|
||||||
{
|
{
|
||||||
|
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
|
||||||
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
|
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
|
||||||
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
|
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
|
||||||
|
@ -611,6 +732,61 @@ namespace CtrEditor
|
||||||
}
|
}
|
||||||
_lastAngle = (float)angle;
|
_lastAngle = (float)angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateSelectionHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlignObjects(AlignmentType alignmentType)
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
|
var alignment = new ObjectAlignment(_selectedObjects);
|
||||||
|
|
||||||
|
switch (alignmentType)
|
||||||
|
{
|
||||||
|
case AlignmentType.Left:
|
||||||
|
alignment.AlignLeft();
|
||||||
|
break;
|
||||||
|
case AlignmentType.Right:
|
||||||
|
alignment.AlignRight();
|
||||||
|
break;
|
||||||
|
case AlignmentType.Top:
|
||||||
|
alignment.AlignTop();
|
||||||
|
break;
|
||||||
|
case AlignmentType.Bottom:
|
||||||
|
alignment.AlignBottom();
|
||||||
|
break;
|
||||||
|
case AlignmentType.CenterHorizontally:
|
||||||
|
alignment.AlignCenterHorizontally();
|
||||||
|
break;
|
||||||
|
case AlignmentType.CenterVertically:
|
||||||
|
alignment.AlignCenterVertically();
|
||||||
|
break;
|
||||||
|
case AlignmentType.DistributeHorizontally:
|
||||||
|
alignment.DistributeHorizontally();
|
||||||
|
break;
|
||||||
|
case AlignmentType.DistributeVertically:
|
||||||
|
alignment.DistributeVertically();
|
||||||
|
break;
|
||||||
|
case AlignmentType.EqualWidth:
|
||||||
|
alignment.EqualWidth();
|
||||||
|
break;
|
||||||
|
case AlignmentType.EqualHeight:
|
||||||
|
alignment.EqualHeight();
|
||||||
|
break;
|
||||||
|
case AlignmentType.EqualAngle:
|
||||||
|
alignment.EqualAngle();
|
||||||
|
break;
|
||||||
|
case AlignmentType.JoinHorizontally:
|
||||||
|
alignment.JoinHorizontally();
|
||||||
|
break;
|
||||||
|
case AlignmentType.JoinVertically:
|
||||||
|
alignment.JoinVertically();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the selection visuals after alignment
|
||||||
|
UpdateSelectionVisuals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue