CtrEditor/ObjectAlignment.cs

269 lines
9.0 KiB
C#
Raw Permalink 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;
private readonly osBase _referenceObject;
2025-02-18 17:52:27 -03:00
public ObjectAlignment(ObservableCollection<osBase> selectedObjects, osBase referenceObject = null)
2025-02-18 17:52:27 -03:00
{
_selectedObjects = selectedObjects;
_referenceObject = referenceObject ?? selectedObjects.FirstOrDefault();
2025-02-18 17:52:27 -03:00
}
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;
var objectsWithCenters = _selectedObjects
.Select(obj => new
{
Object = obj,
Center = GetObjectCenter(obj),
Dimensions = GetEffectiveDimensions(obj)
2025-02-18 17:52:27 -03:00
})
.OrderBy(x => x.Center.X)
.ToList();
float leftMost = (float)objectsWithCenters.First().Center.X;
float rightMost = (float)objectsWithCenters.Last().Center.X;
float totalDistance = rightMost - leftMost;
float spacing = totalDistance / (_selectedObjects.Count - 1);
2025-02-18 17:52:27 -03:00
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
{
var obj = objectsWithCenters[i];
var targetX = leftMost + (spacing * i);
float deltaX = (float)(targetX - obj.Center.X);
obj.Object.Left += deltaX;
2025-02-18 17:52:27 -03:00
}
}
public void DistributeVertically()
{
if (_selectedObjects.Count <= 2) return;
var objectsWithCenters = _selectedObjects
.Select(obj => new
{
Object = obj,
Center = GetObjectCenter(obj),
Dimensions = GetEffectiveDimensions(obj)
2025-02-18 17:52:27 -03:00
})
.OrderBy(x => x.Center.Y)
.ToList();
float topMost = (float)objectsWithCenters.First().Center.Y;
float bottomMost = (float)objectsWithCenters.Last().Center.Y;
float totalDistance = bottomMost - topMost;
float spacing = totalDistance / (_selectedObjects.Count - 1);
2025-02-18 17:52:27 -03:00
for (int i = 1; i < objectsWithCenters.Count - 1; i++)
{
var obj = objectsWithCenters[i];
var targetY = topMost + (spacing * i);
float deltaY = (float)(targetY - obj.Center.Y);
obj.Object.Top += deltaY;
2025-02-18 17:52:27 -03:00
}
}
public void EqualWidth()
{
if (_selectedObjects.Count <= 1) return;
float referenceWidth = GetEffectiveDimensions(_referenceObject).Width;
foreach (var obj in _selectedObjects.Where(o => o != _referenceObject))
{
var currentDims = GetEffectiveDimensions(obj);
SetEffectiveDimensions(obj, referenceWidth, currentDims.Height);
}
}
public void EqualHeight()
{
if (_selectedObjects.Count <= 1) return;
float referenceHeight = GetEffectiveDimensions(_referenceObject).Height;
foreach (var obj in _selectedObjects.Where(o => o != _referenceObject))
{
var currentDims = GetEffectiveDimensions(obj);
SetEffectiveDimensions(obj, currentDims.Width, referenceHeight);
}
}
public void EqualAngle()
{
if (_selectedObjects.Count <= 1) return;
float referenceAngle = _referenceObject.Angulo;
foreach (var obj in _selectedObjects.Where(o => o != _referenceObject))
{
obj.Angulo = referenceAngle;
}
}
public void JoinHorizontally()
{
if (_selectedObjects.Count <= 1) return;
var sortedObjects = _selectedObjects
.OrderBy(obj => GetObjectCenter(obj).X)
.ToList();
for (int i = 1; i < sortedObjects.Count; i++)
{
var previousObj = sortedObjects[i - 1];
var currentObj = sortedObjects[i];
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;
}
}
public void JoinVertically()
{
if (_selectedObjects.Count <= 1) return;
var sortedObjects = _selectedObjects
.OrderBy(obj => GetObjectCenter(obj).Y)
.ToList();
for (int i = 1; i < sortedObjects.Count; i++)
{
var previousObj = sortedObjects[i - 1];
var currentObj = sortedObjects[i];
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;
}
}
2025-02-18 17:52:27 -03:00
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);
if (obj.Angulo != 0)
{
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);
}
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;
}
}
2025-02-18 17:52:27 -03:00
}
}