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 the array of navigable RectSpaces formed in a group by all of the /// group elements, excluding the given active element. /// </summary> private static RectSpace[] CalculateFreeSpacesForGroupedElement( RectContainerElement activeElement, List <RectContainerElement> allGroupElements, RectSpace activeElementContainer) { // Gather list of obstacles List <RectSpace> obstacles = new List <RectSpace>(); foreach (RectContainerElement e in allGroupElements) { if (e != activeElement) { obstacles.Add(new RectSpace(e._source.dynamicTransform)); } } List <RectSpace> freeSpaces = new List <RectSpace>(); freeSpaces.Add(activeElementContainer); foreach (RectSpace obstacle in obstacles) { // Is this obstacle overlapping with any known freespaces? List <RectSpace> createdFreeSpaces = new List <RectSpace>(); foreach (var space in freeSpaces) { if (RectBoundariesUtility.GetRectSpacesDoOverlap(obstacle, space)) { space.markedForRemoval = true; createdFreeSpaces.AddRange( RectBoundariesUtility.GetSplitSpacesFromObstacle(obstacle, space)); } } // Remove marked spaces for (int i = freeSpaces.Count - 1; i >= 0; i--) { if (freeSpaces[i].markedForRemoval) { freeSpaces.Remove(freeSpaces[i]); } } // Add created spaces freeSpaces.AddRange(createdFreeSpaces); } return(freeSpaces.ToArray()); }
/// <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); }
public void SetContainerType( DragElementContainerType containerType, RectTransform container, IUIDynamicElement dynamicContainer) { _explicitContainer = container; _dynamicContainer = dynamicContainer; _containerType = containerType; switch (_containerType) { case DragElementContainerType.Screen: case DragElementContainerType.SafeArea: _containerSpace = new RectSpace(RectBoundariesUtility.GetScreenCorners()); GourdUI.Device.RegisterScreenUpdateListener(this); break; case DragElementContainerType.Parent: _containerSpace = new RectSpace(_explicitContainer); _dynamicContainer?.SubscribeDynamicElementListener(this); break; } _currentElementFreeSpaces.Add(_containerSpace); }
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); }
void IScreenRectUpdateListener.OnScreenRectUpdated(Rect rect) { _containerSpace = new RectSpace(RectBoundariesUtility.GetScreenCorners()); _source.ForceUpdate(); }
/// <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]); }