using CtrEditor.ObjetosSim; using System.Collections.ObjectModel; using System.Windows; namespace CtrEditor { public class ObjectAlignment { private readonly ObservableCollection _selectedObjects; public ObjectAlignment(ObservableCollection 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; var objectsWithCenters = _selectedObjects .Select(obj => new { Object = obj, Center = GetObjectCenter(obj), Dimensions = GetEffectiveDimensions(obj) }) .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); 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; } } public void DistributeVertically() { if (_selectedObjects.Count <= 2) return; var objectsWithCenters = _selectedObjects .Select(obj => new { Object = obj, Center = GetObjectCenter(obj), Dimensions = GetEffectiveDimensions(obj) }) .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); 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; } } public void EqualWidth() { if (_selectedObjects.Count <= 1) return; float averageWidth = _selectedObjects.Average(obj => GetEffectiveDimensions(obj).Width); foreach (var obj in _selectedObjects) { var currentDims = GetEffectiveDimensions(obj); SetEffectiveDimensions(obj, averageWidth, currentDims.Height); } } public void EqualHeight() { if (_selectedObjects.Count <= 1) return; float averageHeight = _selectedObjects.Average(obj => GetEffectiveDimensions(obj).Height); foreach (var obj in _selectedObjects) { var currentDims = GetEffectiveDimensions(obj); SetEffectiveDimensions(obj, currentDims.Width, averageHeight); } } public void EqualAngle() { if (_selectedObjects.Count <= 1) return; float referenceAngle = _selectedObjects.First().Angulo; foreach (var obj in _selectedObjects) { 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; } } 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; } } } }