Multiseleccion funcionando
This commit is contained in:
parent
89745d15bf
commit
3dab570f5d
|
@ -112,8 +112,17 @@ namespace CtrEditor
|
||||||
private bool habilitarEliminarUserControl;
|
private bool habilitarEliminarUserControl;
|
||||||
|
|
||||||
private MainWindow mainWindow;
|
private MainWindow mainWindow;
|
||||||
|
private ObjectManipulationManager _objectManager; // Add this line
|
||||||
|
|
||||||
public MainWindow MainWindow { get => mainWindow; set => mainWindow = value; }
|
public MainWindow MainWindow
|
||||||
|
{
|
||||||
|
get => mainWindow;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mainWindow = value;
|
||||||
|
_objectManager = mainWindow._objectManager; // Initialize _objectManager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public ICollectionView vistaFiltrada;
|
public ICollectionView vistaFiltrada;
|
||||||
|
@ -273,6 +282,14 @@ namespace CtrEditor
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public ObservableCollection<osBase> objetosSimulables;
|
public ObservableCollection<osBase> objetosSimulables;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool isMultiSelectionActive;
|
||||||
|
|
||||||
|
partial void OnIsMultiSelectionActiveChanged(bool value)
|
||||||
|
{
|
||||||
|
_objectManager?.OnMultiSelectionModeChanged(value);
|
||||||
|
}
|
||||||
|
|
||||||
partial void OnObjetosSimulablesChanged(ObservableCollection<osBase> value)
|
partial void OnObjetosSimulablesChanged(ObservableCollection<osBase> value)
|
||||||
{
|
{
|
||||||
VistaFiltrada = CollectionViewSource.GetDefaultView(ObjetosSimulables);
|
VistaFiltrada = CollectionViewSource.GetDefaultView(ObjetosSimulables);
|
||||||
|
|
|
@ -155,8 +155,9 @@
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto"
|
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto"
|
||||||
VerticalScrollBarVisibility="Auto" PanningMode="Both">
|
VerticalScrollBarVisibility="Auto" PanningMode="Both">
|
||||||
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="0">
|
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="0" Background="Transparent">
|
||||||
<!-- El Margin puede ser ajustado según el espacio adicional que quieras proporcionar -->
|
<!-- Agregar Background="Transparent" para que capture los eventos del mouse y -->
|
||||||
|
<!-- asegurar que el Canvas reciba los eventos del botón derecho -->
|
||||||
<Canvas.RenderTransform>
|
<Canvas.RenderTransform>
|
||||||
<TransformGroup>
|
<TransformGroup>
|
||||||
<ScaleTransform x:Name="CanvasScaleTransform" ScaleX="1" ScaleY="1" />
|
<ScaleTransform x:Name="CanvasScaleTransform" ScaleX="1" ScaleY="1" />
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,616 @@
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using CtrEditor.FuncionesBase;
|
||||||
|
using CtrEditor.ObjetosSim;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace CtrEditor
|
||||||
|
{
|
||||||
|
public class ObjectManipulationManager
|
||||||
|
{
|
||||||
|
private enum ResizeMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Move,
|
||||||
|
Rotate,
|
||||||
|
ResizeWidth,
|
||||||
|
ResizeHeight,
|
||||||
|
ResizeBoth
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum HandleMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Move,
|
||||||
|
ResizeWidth,
|
||||||
|
ResizeHeight,
|
||||||
|
ResizeBoth,
|
||||||
|
Rotate
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResizeMode _currentResizeMode;
|
||||||
|
private readonly MainWindow _mainWindow;
|
||||||
|
private readonly Canvas _canvas;
|
||||||
|
private Point _lastMousePosition;
|
||||||
|
private bool _isDrawingCanvas = false;
|
||||||
|
private bool _isDraggingUserControl = false;
|
||||||
|
private bool _isMovingUserControl = false;
|
||||||
|
private UserControl _currentDraggingControl;
|
||||||
|
private Point _startPointUserControl;
|
||||||
|
private Point _transformedBoundingBoxCenter;
|
||||||
|
private float _lastAngle;
|
||||||
|
private List<Rectangle> _resizeRectangles = new List<Rectangle>();
|
||||||
|
private List<Rectangle> _highlightRectangles = new List<Rectangle>();
|
||||||
|
private System.Threading.Timer _timerRemoveHighlight = null;
|
||||||
|
private Rectangle _currentDraggingRectangle;
|
||||||
|
private dataDebug _dataDebug = new dataDebug();
|
||||||
|
private ObservableCollection<osBase> _selectedObjects = new ObservableCollection<osBase>();
|
||||||
|
|
||||||
|
public ObjectManipulationManager(MainWindow mainWindow, Canvas canvas)
|
||||||
|
{
|
||||||
|
_mainWindow = mainWindow;
|
||||||
|
_canvas = canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<osBase> SelectedObjects
|
||||||
|
{
|
||||||
|
get => _selectedObjects;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_selectedObjects = value;
|
||||||
|
UpdateSelectionVisuals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelectionVisuals()
|
||||||
|
{
|
||||||
|
RemoveResizeRectangles();
|
||||||
|
if (_selectedObjects.Any())
|
||||||
|
{
|
||||||
|
AddResizeRectangles(_selectedObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SuscribirEventos(UserControl userControl)
|
||||||
|
{
|
||||||
|
userControl.MouseEnter += UserControl_MouseEnter;
|
||||||
|
userControl.MouseLeave += UserControl_MouseLeave;
|
||||||
|
userControl.Cursor = Cursors.Hand;
|
||||||
|
|
||||||
|
userControl.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
|
||||||
|
userControl.MouseLeftButtonUp += UserControl_MouseLeftButtonUp;
|
||||||
|
userControl.MouseMove += UserControl_MouseMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_MouseEnter(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is UserControl userControl && userControl is IDataContainer dataContainer)
|
||||||
|
{
|
||||||
|
dataContainer.Highlight(true);
|
||||||
|
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel)
|
||||||
|
{
|
||||||
|
var selectedObject = viewModel.SelectedItemOsList;
|
||||||
|
|
||||||
|
if (selectedObject?.VisualRepresentation != userControl)
|
||||||
|
{
|
||||||
|
AddHighlightRectangles(userControl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_MouseLeave(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is UserControl userControl && userControl is IDataContainer dataContainer)
|
||||||
|
dataContainer.Highlight(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddResizeRectangles(IEnumerable<osBase> selectedObjects)
|
||||||
|
{
|
||||||
|
double rectHighlightSize = 1;
|
||||||
|
RemoveResizeRectangles();
|
||||||
|
|
||||||
|
// Calcular el bounding box que contenga todos los objetos seleccionados
|
||||||
|
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
|
||||||
|
|
||||||
|
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
|
||||||
|
rectBox.Left -= (float)rectHighlightSize;
|
||||||
|
rectBox.Right += (float)rectHighlightSize;
|
||||||
|
rectBox.Top -= (float)rectHighlightSize;
|
||||||
|
rectBox.Bottom += (float)rectHighlightSize;
|
||||||
|
|
||||||
|
_transformedBoundingBoxCenter = new Point(
|
||||||
|
boundingBox.Left + boundingBox.Width / 2,
|
||||||
|
boundingBox.Top + boundingBox.Height / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
// Selection rectangle
|
||||||
|
Rectangle selectionRect = CreateSelectionRectangle(rectBox, rectHighlightSize);
|
||||||
|
_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);
|
||||||
|
|
||||||
|
// Add resize/rotation handles
|
||||||
|
AddResizeHandles(rectBox, 10, rotationCursorRx, rotationCursorSx);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect CalculateTotalBoundingBox(IEnumerable<osBase> selectedObjects)
|
||||||
|
{
|
||||||
|
double left = double.MaxValue;
|
||||||
|
double top = double.MaxValue;
|
||||||
|
double right = double.MinValue;
|
||||||
|
double bottom = double.MinValue;
|
||||||
|
|
||||||
|
foreach (var obj in selectedObjects)
|
||||||
|
{
|
||||||
|
if (obj.VisualRepresentation != null && obj.Show_On_This_Page)
|
||||||
|
{
|
||||||
|
// Obtener el bounding box del objeto actual
|
||||||
|
Rect objectBounds = VisualTreeHelper.GetDescendantBounds(obj.VisualRepresentation);
|
||||||
|
GeneralTransform transform = obj.VisualRepresentation.TransformToAncestor(_canvas);
|
||||||
|
Rect transformedBounds = transform.TransformBounds(objectBounds);
|
||||||
|
|
||||||
|
// Actualizar los límites del bounding box total
|
||||||
|
left = Math.Min(left, transformedBounds.Left);
|
||||||
|
top = Math.Min(top, transformedBounds.Top);
|
||||||
|
right = Math.Max(right, transformedBounds.Right);
|
||||||
|
bottom = Math.Max(bottom, transformedBounds.Bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rect(
|
||||||
|
new Point(left, top),
|
||||||
|
new Point(right, bottom)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rectangle CreateSelectionRectangle(FuncionesBase.MutableRect rectBox, double rectHighlightSize)
|
||||||
|
{
|
||||||
|
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)),
|
||||||
|
StrokeThickness = 1.5,
|
||||||
|
Tag = "Selection",
|
||||||
|
IsHitTestVisible = false,
|
||||||
|
StrokeDashArray = new DoubleCollection(new double[] { 3, 3 })
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.SetLeft(rect, rectBox.Left - rectHighlightSize);
|
||||||
|
Canvas.SetTop(rect, rectBox.Top - rectHighlightSize);
|
||||||
|
Canvas.SetZIndex(rect, ((int)ZIndexEnum.RectangulosPropiead - 1));
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddResizeHandles(FuncionesBase.MutableRect rectBox, double rectSize,
|
||||||
|
Cursor rotationCursorRx, Cursor rotationCursorSx)
|
||||||
|
{
|
||||||
|
var positions = new List<(Point Position, string Tag, Cursor Cursor, Brush Stroke)>
|
||||||
|
{
|
||||||
|
(new Point(rectBox.Left, rectBox.Top), "TopLeft", Cursors.Arrow, Brushes.Gray),
|
||||||
|
(new Point(rectBox.Right, rectBox.Top), "TopRight", rotationCursorRx, Brushes.Red),
|
||||||
|
(new Point(rectBox.Left, rectBox.Bottom), "BottomLeft", rotationCursorSx, Brushes.DarkRed),
|
||||||
|
(new Point(rectBox.Right, rectBox.Bottom), "BottomRight", Cursors.SizeNWSE, Brushes.Blue),
|
||||||
|
(new Point(rectBox.Left + rectBox.Width / 2, rectBox.Top), "TopCenter", Cursors.Arrow, Brushes.Gray),
|
||||||
|
(new Point(rectBox.Left + rectBox.Width / 2, rectBox.Bottom), "BottomCenter", Cursors.SizeNS, Brushes.Blue),
|
||||||
|
(new Point(rectBox.Left, rectBox.Top + rectBox.Height / 2), "CenterLeft", rotationCursorRx, Brushes.Red),
|
||||||
|
(new Point(rectBox.Right, rectBox.Top + rectBox.Height / 2), "CenterRight", Cursors.SizeWE, Brushes.Blue)
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var (Position, Tag, Cursor, Stroke) in positions)
|
||||||
|
{
|
||||||
|
var handle = CreateResizeHandle(rectSize, Tag, Cursor, Stroke);
|
||||||
|
SetHandlePosition(handle, Position, rectSize);
|
||||||
|
_resizeRectangles.Add(handle);
|
||||||
|
_canvas.Children.Add(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rectangle CreateResizeHandle(double rectSize, string tag, Cursor cursor, Brush stroke)
|
||||||
|
{
|
||||||
|
var handle = new Rectangle
|
||||||
|
{
|
||||||
|
Width = rectSize,
|
||||||
|
Height = rectSize,
|
||||||
|
Fill = Brushes.Transparent,
|
||||||
|
Stroke = stroke,
|
||||||
|
StrokeThickness = 1,
|
||||||
|
Tag = tag,
|
||||||
|
Cursor = cursor
|
||||||
|
};
|
||||||
|
|
||||||
|
handle.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
|
||||||
|
handle.MouseMove += UserControl_MouseMove;
|
||||||
|
handle.MouseLeftButtonUp += UserControl_MouseLeftButtonUp;
|
||||||
|
handle.MouseLeave += ResizeRectangle_MouseLeave;
|
||||||
|
|
||||||
|
Canvas.SetZIndex(handle, (int)ZIndexEnum.RectangulosPropiead);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetHandlePosition(Rectangle handle, Point position, double rectSize)
|
||||||
|
{
|
||||||
|
if (!double.IsInfinity(position.X) && !double.IsNaN(position.X))
|
||||||
|
Canvas.SetLeft(handle, position.X - rectSize / 2);
|
||||||
|
if (!double.IsInfinity(position.Y) && !double.IsNaN(position.Y))
|
||||||
|
Canvas.SetTop(handle, position.Y - rectSize / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveResizeRectangles()
|
||||||
|
{
|
||||||
|
if (_resizeRectangles == null || _resizeRectangles.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var rect in _resizeRectangles)
|
||||||
|
{
|
||||||
|
_canvas.Children.Remove(rect);
|
||||||
|
}
|
||||||
|
_resizeRectangles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MakeResizeRectanglesTransparent()
|
||||||
|
{
|
||||||
|
if (_resizeRectangles == null || _resizeRectangles.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var rect in _resizeRectangles)
|
||||||
|
{
|
||||||
|
rect.Opacity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MakeResizeRectanglesNormal()
|
||||||
|
{
|
||||||
|
if (_resizeRectangles == null || _resizeRectangles.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var rect in _resizeRectangles)
|
||||||
|
{
|
||||||
|
rect.Opacity = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleObjectSelection(UserControl userControl, osBase datos)
|
||||||
|
{
|
||||||
|
var viewModel = _mainWindow.DataContext as MainViewModel;
|
||||||
|
if (viewModel == null) return;
|
||||||
|
|
||||||
|
bool isControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
|
||||||
|
|
||||||
|
if (viewModel.IsMultiSelectionActive)
|
||||||
|
{
|
||||||
|
if (isControlPressed)
|
||||||
|
{
|
||||||
|
// Deseleccionar objeto si está presionada la tecla Ctrl
|
||||||
|
if (_selectedObjects.Contains(datos))
|
||||||
|
{
|
||||||
|
DeselectObject(datos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!_selectedObjects.Contains(datos))
|
||||||
|
{
|
||||||
|
// Seleccionar objeto si no está ya seleccionado
|
||||||
|
SelectObject(datos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Modo selección única
|
||||||
|
ClearSelection();
|
||||||
|
SelectObject(datos);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.SelectedItemOsList = datos;
|
||||||
|
UpdateSelectionVisuals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectObject(osBase obj)
|
||||||
|
{
|
||||||
|
if (!_selectedObjects.Contains(obj))
|
||||||
|
{
|
||||||
|
_selectedObjects.Add(obj);
|
||||||
|
obj.IsSelected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectObject(osBase obj)
|
||||||
|
{
|
||||||
|
if (_selectedObjects.Contains(obj))
|
||||||
|
{
|
||||||
|
_selectedObjects.Remove(obj);
|
||||||
|
obj.IsSelected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearSelection()
|
||||||
|
{
|
||||||
|
foreach (var obj in _selectedObjects.ToList())
|
||||||
|
{
|
||||||
|
DeselectObject(obj);
|
||||||
|
}
|
||||||
|
RemoveResizeRectangles();
|
||||||
|
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel)
|
||||||
|
{
|
||||||
|
viewModel.SelectedItemOsList = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMultiSelectionModeChanged(bool isActive)
|
||||||
|
{
|
||||||
|
if (!isActive)
|
||||||
|
{
|
||||||
|
// Mantener solo el último objeto seleccionado
|
||||||
|
if (_selectedObjects.Count > 1)
|
||||||
|
{
|
||||||
|
var lastSelected = _selectedObjects.Last();
|
||||||
|
ClearSelection();
|
||||||
|
SelectObject(lastSelected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isDrawingCanvas)
|
||||||
|
{
|
||||||
|
if (_resizeRectangles != null && _resizeRectangles.Contains(sender))
|
||||||
|
{
|
||||||
|
_currentDraggingRectangle = sender as Rectangle;
|
||||||
|
_lastMousePosition = e.GetPosition(_canvas);
|
||||||
|
_currentDraggingRectangle.CaptureMouse();
|
||||||
|
_isMovingUserControl = true;
|
||||||
|
_startPointUserControl = e.GetPosition(_canvas);
|
||||||
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userControl = sender as UserControl;
|
||||||
|
if (userControl != null)
|
||||||
|
{
|
||||||
|
if (userControl.DataContext is osBase datos)
|
||||||
|
{
|
||||||
|
HandleObjectSelection(userControl, datos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solo iniciar el arrastre si no se presionó Ctrl
|
||||||
|
if (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
|
||||||
|
{
|
||||||
|
userControl.CaptureMouse();
|
||||||
|
_currentDraggingControl = userControl;
|
||||||
|
_isMovingUserControl = true;
|
||||||
|
InitializeDrag(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeDrag(MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
_isDraggingUserControl = true;
|
||||||
|
_startPointUserControl = e.GetPosition(_canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_MouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (_isMovingUserControl)
|
||||||
|
{
|
||||||
|
var currentPosition = e.GetPosition(_canvas);
|
||||||
|
MakeResizeRectanglesTransparent();
|
||||||
|
|
||||||
|
if (_isDraggingUserControl)
|
||||||
|
{
|
||||||
|
HandleDrag(currentPosition);
|
||||||
|
}
|
||||||
|
else if (_currentDraggingRectangle != null)
|
||||||
|
{
|
||||||
|
string resizeDirection = _currentDraggingRectangle.Tag as string;
|
||||||
|
if (resizeDirection != null)
|
||||||
|
{
|
||||||
|
var mode = DetermineHandleMode(resizeDirection);
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case HandleMode.Rotate:
|
||||||
|
HandleRotation(currentPosition);
|
||||||
|
break;
|
||||||
|
case HandleMode.ResizeWidth:
|
||||||
|
case HandleMode.ResizeHeight:
|
||||||
|
case HandleMode.ResizeBoth:
|
||||||
|
HandleResize(currentPosition, mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDrag(Point currentPosition)
|
||||||
|
{
|
||||||
|
var dx = currentPosition.X - _startPointUserControl.X;
|
||||||
|
var dy = currentPosition.Y - _startPointUserControl.Y;
|
||||||
|
|
||||||
|
foreach (var selectedObject in _selectedObjects)
|
||||||
|
{
|
||||||
|
var newX = Canvas.GetLeft(selectedObject.VisualRepresentation) + dx;
|
||||||
|
var newY = Canvas.GetTop(selectedObject.VisualRepresentation) + dy;
|
||||||
|
selectedObject.Move((float)newX, (float)newY);
|
||||||
|
}
|
||||||
|
_startPointUserControl = currentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (_isMovingUserControl)
|
||||||
|
{
|
||||||
|
if (sender is UserControl userControl)
|
||||||
|
{
|
||||||
|
userControl.ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
else if (sender is Rectangle rectangle)
|
||||||
|
{
|
||||||
|
rectangle.ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateSelectionVisuals();
|
||||||
|
_isDraggingUserControl = false;
|
||||||
|
_isMovingUserControl = false;
|
||||||
|
_currentDraggingRectangle = null;
|
||||||
|
_currentResizeMode = ResizeMode.None;
|
||||||
|
_lastAngle = 0;
|
||||||
|
}
|
||||||
|
MarkUnsavedChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MarkUnsavedChanges()
|
||||||
|
{
|
||||||
|
if (_mainWindow.DataContext is MainViewModel viewModel)
|
||||||
|
{
|
||||||
|
if (_isMovingUserControl || _isDraggingUserControl)
|
||||||
|
{
|
||||||
|
viewModel.HasUnsavedChanges = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResizeRectangle_MouseLeave(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
var rect = sender as Rectangle;
|
||||||
|
if (rect != null)
|
||||||
|
{
|
||||||
|
rect.Fill = Brushes.Transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddHighlightRectangles(UserControl userControl)
|
||||||
|
{
|
||||||
|
double rectSize = 1;
|
||||||
|
RemoveHighlightRectangles();
|
||||||
|
|
||||||
|
if (userControl is IDataContainer dataContainer && dataContainer.Datos is osBase mvBase && mvBase.Show_On_This_Page)
|
||||||
|
{
|
||||||
|
Rect boundingBox = VisualTreeHelper.GetDescendantBounds(userControl);
|
||||||
|
GeneralTransform transform = userControl.TransformToAncestor(_canvas);
|
||||||
|
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;
|
||||||
|
|
||||||
|
Rectangle highlightRect = new Rectangle
|
||||||
|
{
|
||||||
|
Width = rectBox.Width,
|
||||||
|
Height = rectBox.Height,
|
||||||
|
Fill = Brushes.Transparent,
|
||||||
|
Stroke = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)),
|
||||||
|
StrokeThickness = 1,
|
||||||
|
Tag = "Highlight",
|
||||||
|
IsHitTestVisible = false,
|
||||||
|
StrokeDashArray = new DoubleCollection(new double[] { 2, 2 })
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.SetLeft(highlightRect, rectBox.Left);
|
||||||
|
Canvas.SetTop(highlightRect, rectBox.Top); // Corregido: usando rectBox.Top en lugar de highlightRect.Top
|
||||||
|
|
||||||
|
_highlightRectangles.Add(highlightRect);
|
||||||
|
_canvas.Children.Add(highlightRect);
|
||||||
|
Canvas.SetZIndex(highlightRect, ((int)ZIndexEnum.RectangulosPropiead));
|
||||||
|
|
||||||
|
if (_timerRemoveHighlight == null)
|
||||||
|
_timerRemoveHighlight = new System.Threading.Timer(TimerCallbackRemoveHighlight, null, Timeout.Infinite, Timeout.Infinite);
|
||||||
|
|
||||||
|
_timerRemoveHighlight.Change(2000, Timeout.Infinite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TimerCallbackRemoveHighlight(object state)
|
||||||
|
{
|
||||||
|
if (Application.Current != null)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(RemoveHighlightRectangles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveHighlightRectangles()
|
||||||
|
{
|
||||||
|
if (_highlightRectangles == null || _highlightRectangles.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var rect in _highlightRectangles)
|
||||||
|
{
|
||||||
|
_canvas.Children.Remove(rect);
|
||||||
|
}
|
||||||
|
_highlightRectangles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HandleMode DetermineHandleMode(string resizeDirection)
|
||||||
|
{
|
||||||
|
return resizeDirection switch
|
||||||
|
{
|
||||||
|
"TopLeft" => HandleMode.None,
|
||||||
|
"TopRight" or "BottomLeft" or "CenterLeft" => HandleMode.Rotate,
|
||||||
|
"BottomRight" => HandleMode.ResizeBoth,
|
||||||
|
"TopCenter" => HandleMode.None,
|
||||||
|
"BottomCenter" => HandleMode.ResizeHeight,
|
||||||
|
"CenterRight" => HandleMode.ResizeWidth,
|
||||||
|
_ => HandleMode.None
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleResize(Point currentPosition, HandleMode mode)
|
||||||
|
{
|
||||||
|
foreach (var selectedObject in _selectedObjects)
|
||||||
|
{
|
||||||
|
bool resizeWidth = mode == HandleMode.ResizeWidth || mode == HandleMode.ResizeBoth;
|
||||||
|
bool resizeHeight = mode == HandleMode.ResizeHeight || mode == HandleMode.ResizeBoth;
|
||||||
|
HandleResizeForObject(selectedObject, currentPosition, resizeWidth, resizeHeight);
|
||||||
|
}
|
||||||
|
_startPointUserControl = currentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleResizeForObject(osBase obj, Point currentPosition, bool activateSizeWidth, bool activateSizeHeight)
|
||||||
|
{
|
||||||
|
double widthChange = activateSizeWidth ? currentPosition.X - _startPointUserControl.X : 0;
|
||||||
|
double heightChange = activateSizeHeight ? currentPosition.Y - _startPointUserControl.Y : 0;
|
||||||
|
|
||||||
|
obj.Resize(widthChange, heightChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleRotation(Point currentPosition)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
double angle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI);
|
||||||
|
|
||||||
|
if ((_lastAngle == 0 && angle != 0) || Math.Abs(angle - _lastAngle) > 45)
|
||||||
|
{
|
||||||
|
_lastAngle = (float)angle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double deltaAngle = angle - _lastAngle;
|
||||||
|
foreach (var selectedObject in _selectedObjects)
|
||||||
|
{
|
||||||
|
selectedObject.Rotate(deltaAngle);
|
||||||
|
}
|
||||||
|
_lastAngle = (float)angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -509,6 +509,8 @@ namespace CtrEditor.ObjetosSim
|
||||||
[property: Hidden]
|
[property: Hidden]
|
||||||
UniqueId cloned_from;
|
UniqueId cloned_from;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool isSelected;
|
||||||
|
|
||||||
private async void TimerCallback(object state)
|
private async void TimerCallback(object state)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue