Agregado movimiento con flechas de los objetos seleccionados
This commit is contained in:
parent
326c615887
commit
38ca212d9f
|
@ -153,9 +153,17 @@
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
</ToolBarTray>
|
</ToolBarTray>
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto"
|
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer"
|
||||||
VerticalScrollBarVisibility="Auto" PanningMode="Both">
|
HorizontalScrollBarVisibility="Auto"
|
||||||
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="0" Background="Transparent">
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
PanningMode="Both"
|
||||||
|
PreviewKeyDown="ScrollViewer_PreviewKeyDown">
|
||||||
|
<Canvas x:Name="ImagenEnTrabajoCanvas"
|
||||||
|
Margin="0"
|
||||||
|
Background="Transparent"
|
||||||
|
Focusable="True"
|
||||||
|
FocusVisualStyle="{x:Null}"
|
||||||
|
KeyDown="Canvas_KeyDown">
|
||||||
<!-- Agregar Background="Transparent" para que capture los eventos del mouse y -->
|
<!-- Agregar Background="Transparent" para que capture los eventos del mouse y -->
|
||||||
<!-- asegurar que el Canvas reciba los eventos del botón derecho -->
|
<!-- asegurar que el Canvas reciba los eventos del botón derecho -->
|
||||||
<Canvas.RenderTransform>
|
<Canvas.RenderTransform>
|
||||||
|
|
|
@ -151,6 +151,7 @@ namespace CtrEditor
|
||||||
// y no en otros controles
|
// y no en otros controles
|
||||||
if (e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo)
|
if (e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo)
|
||||||
{
|
{
|
||||||
|
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||||
_isDraggingCanvas = true;
|
_isDraggingCanvas = true;
|
||||||
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
|
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
|
||||||
ImagenEnTrabajoCanvas.CaptureMouse();
|
ImagenEnTrabajoCanvas.CaptureMouse();
|
||||||
|
@ -259,6 +260,7 @@ namespace CtrEditor
|
||||||
|
|
||||||
private void ListaOs_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private void ListaOs_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||||
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
|
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
|
||||||
|
|
||||||
if (e.AddedItems.Count > 0 && e.AddedItems[0] is osBase selectedObject)
|
if (e.AddedItems.Count > 0 && e.AddedItems[0] is osBase selectedObject)
|
||||||
|
@ -285,6 +287,12 @@ namespace CtrEditor
|
||||||
|
|
||||||
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
|
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
|
// Forzar el foco al canvas si no lo tiene
|
||||||
|
if (!ImagenEnTrabajoCanvas.IsFocused)
|
||||||
|
{
|
||||||
|
ImagenEnTrabajoCanvas.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
if (DataContext is MainViewModel viewModel)
|
if (DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.Delete)
|
if (e.Key == Key.Delete)
|
||||||
|
@ -294,16 +302,55 @@ namespace CtrEditor
|
||||||
}
|
}
|
||||||
else if (e.Key == Key.Escape)
|
else if (e.Key == Key.Escape)
|
||||||
{
|
{
|
||||||
// Limpiar la selección en el ListBox
|
|
||||||
viewModel.SelectedItemOsList = null;
|
viewModel.SelectedItemOsList = null;
|
||||||
|
|
||||||
// Limpiar la selección múltiple
|
|
||||||
_objectManager.ClearSelection();
|
_objectManager.ClearSelection();
|
||||||
_objectManager.RemoveResizeRectangles();
|
_objectManager.RemoveResizeRectangles();
|
||||||
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
else if (_objectManager.SelectedObjects.Any())
|
||||||
|
{
|
||||||
|
const float moveDistance = 0.1f;
|
||||||
|
switch (e.Key)
|
||||||
|
{
|
||||||
|
case Key.Left:
|
||||||
|
MoveSelectedObjects(-moveDistance, 0);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Right:
|
||||||
|
MoveSelectedObjects(moveDistance, 0);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Up:
|
||||||
|
MoveSelectedObjects(0, -moveDistance);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Down:
|
||||||
|
MoveSelectedObjects(0, moveDistance);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveSelectedObjects(float deltaX, float deltaY)
|
||||||
|
{
|
||||||
|
// Mover todos los objetos primero
|
||||||
|
foreach (var obj in _objectManager.SelectedObjects)
|
||||||
|
{
|
||||||
|
obj.Left += deltaX;
|
||||||
|
obj.Top += deltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forzar una actualización del layout antes de actualizar los visuales
|
||||||
|
ImagenEnTrabajoCanvas.UpdateLayout();
|
||||||
|
|
||||||
|
// Ahora actualizar los visuales de selección
|
||||||
|
_objectManager.UpdateSelectionVisuals();
|
||||||
|
|
||||||
|
if (DataContext is MainViewModel viewModel)
|
||||||
|
{
|
||||||
|
viewModel.HasUnsavedChanges = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +424,7 @@ namespace CtrEditor
|
||||||
if ((e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo || e.Source is UserControl) &&
|
if ((e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo || e.Source is UserControl) &&
|
||||||
DataContext is MainViewModel viewModel)
|
DataContext is MainViewModel viewModel)
|
||||||
{
|
{
|
||||||
|
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
ShowContextMenu(e.GetPosition(ImagenEnTrabajoCanvas));
|
ShowContextMenu(e.GetPosition(ImagenEnTrabajoCanvas));
|
||||||
}
|
}
|
||||||
|
@ -440,6 +488,63 @@ namespace CtrEditor
|
||||||
contextMenu.IsOpen = true;
|
contextMenu.IsOpen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Canvas_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
HandleKeyDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScrollViewer_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
// Prevenir que el ScrollViewer maneje las teclas de flecha
|
||||||
|
if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down)
|
||||||
|
{
|
||||||
|
HandleKeyDown(e);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleKeyDown(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (DataContext is MainViewModel viewModel)
|
||||||
|
{
|
||||||
|
if (e.Key == Key.Delete)
|
||||||
|
{
|
||||||
|
viewModel.EliminarObjetoSeleccionado();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
else if (e.Key == Key.Escape)
|
||||||
|
{
|
||||||
|
viewModel.SelectedItemOsList = null;
|
||||||
|
_objectManager.ClearSelection();
|
||||||
|
_objectManager.RemoveResizeRectangles();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
else if (_objectManager.SelectedObjects.Any())
|
||||||
|
{
|
||||||
|
const float moveDistance = 0.01f;
|
||||||
|
switch (e.Key)
|
||||||
|
{
|
||||||
|
case Key.Left:
|
||||||
|
MoveSelectedObjects(-moveDistance, 0);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Right:
|
||||||
|
MoveSelectedObjects(moveDistance, 0);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Up:
|
||||||
|
MoveSelectedObjects(0, -moveDistance);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
case Key.Down:
|
||||||
|
MoveSelectedObjects(0, moveDistance);
|
||||||
|
e.Handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FloatValidationRule : ValidationRule
|
public class FloatValidationRule : ValidationRule
|
||||||
|
|
|
@ -83,31 +83,27 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
if (_selectedObjects.Count <= 2) return;
|
if (_selectedObjects.Count <= 2) return;
|
||||||
|
|
||||||
// Ordenar objetos por su centro X real (considerando rotación)
|
|
||||||
var objectsWithCenters = _selectedObjects
|
var objectsWithCenters = _selectedObjects
|
||||||
.Select(obj => new
|
.Select(obj => new
|
||||||
{
|
{
|
||||||
Object = obj,
|
Object = obj,
|
||||||
Center = GetObjectCenter(obj)
|
Center = GetObjectCenter(obj),
|
||||||
|
Dimensions = GetEffectiveDimensions(obj)
|
||||||
})
|
})
|
||||||
.OrderBy(x => x.Center.X)
|
.OrderBy(x => x.Center.X)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Calcular el espacio total y el espaciado
|
|
||||||
float leftMost = (float)objectsWithCenters.First().Center.X;
|
float leftMost = (float)objectsWithCenters.First().Center.X;
|
||||||
float rightMost = (float)objectsWithCenters.Last().Center.X;
|
float rightMost = (float)objectsWithCenters.Last().Center.X;
|
||||||
float totalWidth = rightMost - leftMost;
|
float totalDistance = rightMost - leftMost;
|
||||||
float spacing = totalWidth / (_selectedObjects.Count - 1);
|
float spacing = totalDistance / (_selectedObjects.Count - 1);
|
||||||
|
|
||||||
// Distribuir objetos basados en sus centros
|
|
||||||
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
||||||
{
|
{
|
||||||
var obj = objectsWithCenters[i].Object;
|
var obj = objectsWithCenters[i];
|
||||||
var targetCenterX = leftMost + (spacing * i);
|
var targetX = leftMost + (spacing * i);
|
||||||
var currentCenter = GetObjectCenter(obj);
|
float deltaX = (float)(targetX - obj.Center.X);
|
||||||
var deltaX = targetCenterX - currentCenter.X;
|
obj.Object.Left += deltaX;
|
||||||
|
|
||||||
obj.Left += (float)deltaX;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,31 +111,27 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
if (_selectedObjects.Count <= 2) return;
|
if (_selectedObjects.Count <= 2) return;
|
||||||
|
|
||||||
// Ordenar objetos por su centro Y real (considerando rotación)
|
|
||||||
var objectsWithCenters = _selectedObjects
|
var objectsWithCenters = _selectedObjects
|
||||||
.Select(obj => new
|
.Select(obj => new
|
||||||
{
|
{
|
||||||
Object = obj,
|
Object = obj,
|
||||||
Center = GetObjectCenter(obj)
|
Center = GetObjectCenter(obj),
|
||||||
|
Dimensions = GetEffectiveDimensions(obj)
|
||||||
})
|
})
|
||||||
.OrderBy(x => x.Center.Y)
|
.OrderBy(x => x.Center.Y)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Calcular el espacio total y el espaciado
|
|
||||||
float topMost = (float)objectsWithCenters.First().Center.Y;
|
float topMost = (float)objectsWithCenters.First().Center.Y;
|
||||||
float bottomMost = (float)objectsWithCenters.Last().Center.Y;
|
float bottomMost = (float)objectsWithCenters.Last().Center.Y;
|
||||||
float totalHeight = bottomMost - topMost;
|
float totalDistance = bottomMost - topMost;
|
||||||
float spacing = totalHeight / (_selectedObjects.Count - 1);
|
float spacing = totalDistance / (_selectedObjects.Count - 1);
|
||||||
|
|
||||||
// Distribuir objetos basados en sus centros
|
|
||||||
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
|
||||||
{
|
{
|
||||||
var obj = objectsWithCenters[i].Object;
|
var obj = objectsWithCenters[i];
|
||||||
var targetCenterY = topMost + (spacing * i);
|
var targetY = topMost + (spacing * i);
|
||||||
var currentCenter = GetObjectCenter(obj);
|
float deltaY = (float)(targetY - obj.Center.Y);
|
||||||
var deltaY = targetCenterY - currentCenter.Y;
|
obj.Object.Top += deltaY;
|
||||||
|
|
||||||
obj.Top += (float)deltaY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +139,11 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
if (_selectedObjects.Count <= 1) return;
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
float averageWidth = _selectedObjects.Average(obj => obj.Ancho);
|
float averageWidth = _selectedObjects.Average(obj => GetEffectiveDimensions(obj).Width);
|
||||||
foreach (var obj in _selectedObjects)
|
foreach (var obj in _selectedObjects)
|
||||||
{
|
{
|
||||||
obj.Ancho = averageWidth;
|
var currentDims = GetEffectiveDimensions(obj);
|
||||||
|
SetEffectiveDimensions(obj, averageWidth, currentDims.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +151,11 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
if (_selectedObjects.Count <= 1) return;
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
float averageHeight = _selectedObjects.Average(obj => obj.Alto);
|
float averageHeight = _selectedObjects.Average(obj => GetEffectiveDimensions(obj).Height);
|
||||||
foreach (var obj in _selectedObjects)
|
foreach (var obj in _selectedObjects)
|
||||||
{
|
{
|
||||||
obj.Alto = averageHeight;
|
var currentDims = GetEffectiveDimensions(obj);
|
||||||
|
SetEffectiveDimensions(obj, currentDims.Width, averageHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,14 +175,21 @@ namespace CtrEditor
|
||||||
if (_selectedObjects.Count <= 1) return;
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
var sortedObjects = _selectedObjects
|
var sortedObjects = _selectedObjects
|
||||||
.OrderBy(obj => obj.Left)
|
.OrderBy(obj => GetObjectCenter(obj).X)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
for (int i = 1; i < sortedObjects.Count; i++)
|
for (int i = 1; i < sortedObjects.Count; i++)
|
||||||
{
|
{
|
||||||
var previousObj = sortedObjects[i - 1];
|
var previousObj = sortedObjects[i - 1];
|
||||||
var currentObj = sortedObjects[i];
|
var currentObj = sortedObjects[i];
|
||||||
currentObj.Left = previousObj.Left + previousObj.Ancho;
|
var previousCenter = GetObjectCenter(previousObj);
|
||||||
|
var currentCenter = GetObjectCenter(currentObj);
|
||||||
|
var previousDims = GetEffectiveDimensions(previousObj);
|
||||||
|
|
||||||
|
float offset = previousDims.Width / 2;
|
||||||
|
float newX = (float)(previousCenter.X + offset);
|
||||||
|
float deltaX = (float)(newX - (currentCenter.X - GetEffectiveDimensions(currentObj).Width / 2));
|
||||||
|
currentObj.Left += deltaX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,14 +198,21 @@ namespace CtrEditor
|
||||||
if (_selectedObjects.Count <= 1) return;
|
if (_selectedObjects.Count <= 1) return;
|
||||||
|
|
||||||
var sortedObjects = _selectedObjects
|
var sortedObjects = _selectedObjects
|
||||||
.OrderBy(obj => obj.Top)
|
.OrderBy(obj => GetObjectCenter(obj).Y)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
for (int i = 1; i < sortedObjects.Count; i++)
|
for (int i = 1; i < sortedObjects.Count; i++)
|
||||||
{
|
{
|
||||||
var previousObj = sortedObjects[i - 1];
|
var previousObj = sortedObjects[i - 1];
|
||||||
var currentObj = sortedObjects[i];
|
var currentObj = sortedObjects[i];
|
||||||
currentObj.Top = previousObj.Top + previousObj.Alto;
|
var previousCenter = GetObjectCenter(previousObj);
|
||||||
|
var currentCenter = GetObjectCenter(currentObj);
|
||||||
|
var previousDims = GetEffectiveDimensions(previousObj);
|
||||||
|
|
||||||
|
float offset = previousDims.Height / 2;
|
||||||
|
float newY = (float)(previousCenter.Y + offset);
|
||||||
|
float deltaY = (float)(newY - (currentCenter.Y - GetEffectiveDimensions(currentObj).Height / 2));
|
||||||
|
currentObj.Top += deltaY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,10 +222,8 @@ namespace CtrEditor
|
||||||
float centerX = obj.Left + (obj.Ancho / 2);
|
float centerX = obj.Left + (obj.Ancho / 2);
|
||||||
float centerY = obj.Top + (obj.Alto / 2);
|
float centerY = obj.Top + (obj.Alto / 2);
|
||||||
|
|
||||||
// Si el objeto está rotado, calcular el centro real
|
|
||||||
if (obj.Angulo != 0)
|
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 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);
|
var rotatedY = obj.Top + (Math.Sin(angleRad) * obj.Ancho / 2 + Math.Cos(angleRad) * obj.Alto / 2);
|
||||||
|
|
||||||
|
@ -226,5 +232,35 @@ namespace CtrEditor
|
||||||
|
|
||||||
return new Point(centerX, centerY);
|
return new Point(centerX, centerY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsObjectVertical(osBase obj)
|
||||||
|
{
|
||||||
|
double normalizedAngle = obj.Angulo % 180;
|
||||||
|
if (normalizedAngle < 0) normalizedAngle += 180;
|
||||||
|
return normalizedAngle >= 45 && normalizedAngle < 135;
|
||||||
|
}
|
||||||
|
|
||||||
|
private (float Width, float Height) GetEffectiveDimensions(osBase obj)
|
||||||
|
{
|
||||||
|
if (IsObjectVertical(obj))
|
||||||
|
{
|
||||||
|
return (obj.Alto, obj.Ancho);
|
||||||
|
}
|
||||||
|
return (obj.Ancho, obj.Alto);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEffectiveDimensions(osBase obj, float width, float height)
|
||||||
|
{
|
||||||
|
if (IsObjectVertical(obj))
|
||||||
|
{
|
||||||
|
obj.Alto = width;
|
||||||
|
obj.Ancho = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj.Ancho = width;
|
||||||
|
obj.Alto = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,14 @@ namespace CtrEditor
|
||||||
|
|
||||||
public void UpdateSelectionVisuals()
|
public void UpdateSelectionVisuals()
|
||||||
{
|
{
|
||||||
|
// Asegurarse de que el canvas haya actualizado su layout
|
||||||
|
_canvas.UpdateLayout();
|
||||||
|
|
||||||
RemoveResizeRectangles();
|
RemoveResizeRectangles();
|
||||||
if (_selectedObjects.Any())
|
if (_selectedObjects.Any())
|
||||||
{
|
{
|
||||||
AddResizeRectangles(_selectedObjects);
|
AddResizeRectangles(_selectedObjects);
|
||||||
|
UpdateSelectionHighlights();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue