public override void OnDroppableDrop(IUIDroppable droppable) { base.OnDroppableDrop(droppable); if (_snapDroppablesToAreaOnDrop) { Vector2 boundaryOverlap = RectBoundariesUtility.GetRectSpaceOverlap( new RectSpace(droppable.droppableRect), new RectSpace(depositAreaTransform), RectContainerElement.DragElementContainerBoundary.Edge); droppable.droppableRect.position -= (Vector3)boundaryOverlap; } }
/// <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); }
Tuple<Vector2, bool, bool> IUIDynamicElementPositionFilter.GetFilteredPosition() { // Refersh container if (_group != null) { RefreshGroupFreeSpaces(); } else { _positionEvaluationSpace = _containerSpace; } // Find the overlap with the current container Vector2 boundaryOverlap = RectBoundariesUtility.GetRectSpaceOverlap( new RectSpace(_source.dynamicTransform), _positionEvaluationSpace, _boundaryMode); return new Tuple<Vector2, bool, bool>( boundaryOverlap, boundaryOverlap.x != 0, boundaryOverlap.y != 0); }
/// <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]); }