public static Vector2 GetRectSpaceOverlap( RectSpace element, RectSpace container, RectContainerElement.DragElementContainerBoundary mode) { Vector2 overlap = Vector2.zero; if (mode == RectContainerElement.DragElementContainerBoundary.Edge) { // X overlap if (element.left < container.left) { overlap = new Vector2(element.left - container.left, overlap.y); } if (element.right > container.right) { overlap = new Vector2(element.right - container.right, overlap.y); } // Y overlap if (element.top > container.top) { overlap = new Vector2(overlap.x, element.top - container.top); } if (element.bottom < container.bottom) { overlap = new Vector2(overlap.x, element.bottom - container.bottom); } } else { // X overlap if (element.center.x < container.left) { overlap = new Vector2(element.center.x - container.left, overlap.y); } if (element.center.x > container.right) { overlap = new Vector2(element.center.x - container.right, overlap.y); } // Y overlap if (element.center.y > container.top) { overlap = new Vector2(overlap.x, element.center.y - container.top); } if (element.center.y < container.bottom) { overlap = new Vector2(overlap.x, element.center.y - container.bottom); } } return(overlap); }
/// <summary> /// Calculates and returns a list of the freespaces within which the given element is /// completely contained (not overlapping any edges). /// </summary> private static List <RectSpace> CalculateEnclosingFreeSpacesForGroupedElement( RectContainerElement activeElement, RectContainerElement.DragElementContainerBoundary boundaryMode, RectSpace element, RectSpace[] freespaces) { List <RectSpace> containingSpaces = new List <RectSpace>(); foreach (RectSpace space in freespaces) { if (RectBoundariesUtility.GetRectSpaceOverlap(element, space, boundaryMode) == Vector2.zero) { containingSpaces.Add(space); } } return(containingSpaces); }
/// <summary> /// Returns the FreeSpaces within which the given element is completely contained, AFTER /// any overlap corrects have been applied. /// </summary> public RectSpace GetGroupedElementEvaluationBoundary( RectContainerElement activeElement, RectContainerElement.DragElementContainerBoundary boundaryMode, RectSpace activeSpace, RectSpace containerSpace, List <RectSpace> previousFreeSpaces, out List <RectSpace> newFreeSpaces) { // Get the free spaces RectSpace[] freespaces = CalculateFreeSpacesForGroupedElement( activeElement, _elements, containerSpace); // Is our element fully contained within any space? List <RectSpace> fs = CalculateEnclosingFreeSpacesForGroupedElement( activeElement, boundaryMode, activeSpace, freespaces); // If we didn't find a space, that means our element is overlapping // We want to apply the correction temporarily, re-check to find the correct space, // And then try again to find the new evaluation container space if (fs.Count == 0) { // Get overlap distances for each previous freespace Vector2[] overlapDistances = new Vector2[previousFreeSpaces.Count]; for (int i = 0; i < previousFreeSpaces.Count; i++) { overlapDistances [i] = RectBoundariesUtility.GetRectSpaceOverlap( activeSpace, previousFreeSpaces[i], boundaryMode); } // Which overlap distance was closest? That's the one we want! RectSpace evalSpace = previousFreeSpaces[0]; Vector2 evalDistance = Vector2.zero; float currentClosestDistance = float.MaxValue; for (int i = 0; i < previousFreeSpaces.Count; i++) { if (overlapDistances[i].sqrMagnitude < currentClosestDistance) { currentClosestDistance = overlapDistances[i].sqrMagnitude; evalDistance = overlapDistances[i]; evalSpace = previousFreeSpaces[i]; } } // Now we can re-evaluate current spaces for transformed element RectSpace corrected = new RectSpace(activeSpace).TransformWithOffset(evalDistance); List <RectSpace> postCorrectionFS = CalculateEnclosingFreeSpacesForGroupedElement( activeElement, boundaryMode, corrected, freespaces); newFreeSpaces = postCorrectionFS.Count > 0 ? postCorrectionFS : new List <RectSpace> { containerSpace }; // return(evalSpace); } newFreeSpaces = fs.Count > 0 ? fs : new List <RectSpace> { containerSpace }; return(fs[0]); }