Agregado movimiento con flechas de los objetos seleccionados
This commit is contained in:
parent
326c615887
commit
38ca212d9f
|
@ -153,9 +153,17 @@
|
|||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
|
||||
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer" HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto" PanningMode="Both">
|
||||
<Canvas x:Name="ImagenEnTrabajoCanvas" Margin="0" Background="Transparent">
|
||||
<ScrollViewer Grid.Row="1" x:Name="ImagenEnTrabajoScrollViewer"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
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 -->
|
||||
<!-- asegurar que el Canvas reciba los eventos del botón derecho -->
|
||||
<Canvas.RenderTransform>
|
||||
|
|
|
@ -151,6 +151,7 @@ namespace CtrEditor
|
|||
// y no en otros controles
|
||||
if (e.Source == ImagenEnTrabajoCanvas || e.Source == imagenDeFondo)
|
||||
{
|
||||
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||
_isDraggingCanvas = true;
|
||||
_lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer);
|
||||
ImagenEnTrabajoCanvas.CaptureMouse();
|
||||
|
@ -259,6 +260,7 @@ namespace CtrEditor
|
|||
|
||||
private void ListaOs_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||
{
|
||||
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
|
||||
|
||||
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)
|
||||
{
|
||||
// Forzar el foco al canvas si no lo tiene
|
||||
if (!ImagenEnTrabajoCanvas.IsFocused)
|
||||
{
|
||||
ImagenEnTrabajoCanvas.Focus();
|
||||
}
|
||||
|
||||
if (DataContext is MainViewModel viewModel)
|
||||
{
|
||||
if (e.Key == Key.Delete)
|
||||
|
@ -294,16 +302,55 @@ namespace CtrEditor
|
|||
}
|
||||
else if (e.Key == Key.Escape)
|
||||
{
|
||||
// Limpiar la selección en el ListBox
|
||||
viewModel.SelectedItemOsList = null;
|
||||
|
||||
// Limpiar la selección múltiple
|
||||
_objectManager.ClearSelection();
|
||||
_objectManager.RemoveResizeRectangles();
|
||||
|
||||
|
||||
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) &&
|
||||
DataContext is MainViewModel viewModel)
|
||||
{
|
||||
ImagenEnTrabajoCanvas.Focus(); // Asegurar que el canvas tiene el foco
|
||||
e.Handled = true;
|
||||
ShowContextMenu(e.GetPosition(ImagenEnTrabajoCanvas));
|
||||
}
|
||||
|
@ -440,6 +488,63 @@ namespace CtrEditor
|
|||
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
|
||||
|
|
|
@ -83,31 +83,27 @@ namespace CtrEditor
|
|||
{
|
||||
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)
|
||||
Center = GetObjectCenter(obj),
|
||||
Dimensions = GetEffectiveDimensions(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);
|
||||
float totalDistance = rightMost - leftMost;
|
||||
float spacing = totalDistance / (_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;
|
||||
var obj = objectsWithCenters[i];
|
||||
var targetX = leftMost + (spacing * i);
|
||||
float deltaX = (float)(targetX - obj.Center.X);
|
||||
obj.Object.Left += deltaX;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,31 +111,27 @@ namespace CtrEditor
|
|||
{
|
||||
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)
|
||||
Center = GetObjectCenter(obj),
|
||||
Dimensions = GetEffectiveDimensions(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);
|
||||
float totalDistance = bottomMost - topMost;
|
||||
float spacing = totalDistance / (_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;
|
||||
var obj = objectsWithCenters[i];
|
||||
var targetY = topMost + (spacing * i);
|
||||
float deltaY = (float)(targetY - obj.Center.Y);
|
||||
obj.Object.Top += deltaY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,10 +139,11 @@ namespace CtrEditor
|
|||
{
|
||||
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)
|
||||
{
|
||||
obj.Ancho = averageWidth;
|
||||
var currentDims = GetEffectiveDimensions(obj);
|
||||
SetEffectiveDimensions(obj, averageWidth, currentDims.Height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,10 +151,11 @@ namespace CtrEditor
|
|||
{
|
||||
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)
|
||||
{
|
||||
obj.Alto = averageHeight;
|
||||
var currentDims = GetEffectiveDimensions(obj);
|
||||
SetEffectiveDimensions(obj, currentDims.Width, averageHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,14 +175,21 @@ namespace CtrEditor
|
|||
if (_selectedObjects.Count <= 1) return;
|
||||
|
||||
var sortedObjects = _selectedObjects
|
||||
.OrderBy(obj => obj.Left)
|
||||
.OrderBy(obj => GetObjectCenter(obj).X)
|
||||
.ToList();
|
||||
|
||||
for (int i = 1; i < sortedObjects.Count; i++)
|
||||
{
|
||||
var previousObj = sortedObjects[i - 1];
|
||||
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;
|
||||
|
||||
var sortedObjects = _selectedObjects
|
||||
.OrderBy(obj => obj.Top)
|
||||
.OrderBy(obj => GetObjectCenter(obj).Y)
|
||||
.ToList();
|
||||
|
||||
for (int i = 1; i < sortedObjects.Count; i++)
|
||||
{
|
||||
var previousObj = sortedObjects[i - 1];
|
||||
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 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);
|
||||
|
||||
|
@ -226,5 +232,35 @@ namespace CtrEditor
|
|||
|
||||
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()
|
||||
{
|
||||
// Asegurarse de que el canvas haya actualizado su layout
|
||||
_canvas.UpdateLayout();
|
||||
|
||||
RemoveResizeRectangles();
|
||||
if (_selectedObjects.Any())
|
||||
{
|
||||
AddResizeRectangles(_selectedObjects);
|
||||
UpdateSelectionHighlights();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue