CtrEditor/ObjectAlignment.cs

166 lines
5.5 KiB
C#
Raw Normal View History

2025-02-18 17:52:27 -03:00
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;
}
}
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);
}
}
}