static Vector2 GetMaxPos(Rect rect, SnapReference reference)
        {
            switch (reference)
            {
            case SnapReference.LeftEdge:
                return(new Vector2(rect.x, rect.yMax));

            case SnapReference.HorizontalCenter:
                return(new Vector2(rect.center.x, rect.yMax));

            case SnapReference.RightEdge:
                return(new Vector2(rect.xMax, rect.yMax));

            case SnapReference.TopEdge:
                return(new Vector2(rect.xMax, rect.y));

            case SnapReference.VerticalCenter:
                return(new Vector2(rect.xMax, rect.center.y));

            case SnapReference.BottomEdge:
                return(new Vector2(rect.xMax, rect.yMax));

            default:
                return(Vector2.zero);
            }
        }
        void ComputeSpacingPositions(ReferenceRects referenceRects, Rect sourceRect)
        {
            SnapReference startReference = referenceRects.Orientation == Orientation.Vertical ? SnapReference.TopEdge : SnapReference.LeftEdge;
            SnapReference endReference   = referenceRects.Orientation == Orientation.Vertical ? SnapReference.BottomEdge : SnapReference.RightEdge;

            for (int i = 0; i < referenceRects.Rects.Count; ++i)
            {
                Rect firstRect     = referenceRects.Rects[i];
                int  nextRectIndex = i + 1;                // After rect i is done, we don't consider it anymore for the next iterations

                for (int j = nextRectIndex; j < referenceRects.Rects.Count; ++j)
                {
                    Rect secondRect = referenceRects.Rects[j];

                    // For each rect i, we find the 3 spacing positions: (examples are for horizontal orientation)
                    //        - 1. position before rect i
                    //              +-----+    +-----+    +-----+
                    //              | pos |    |  i  |    |  j  |
                    //              +-----+    +-----+    +-----+
                    //        - 2. position between rect i and rect j
                    //              +-----+    +-----+    +-----+
                    //              |  i  |    | pos |    |  j  |
                    //              +-----+    +-----+    +-----+
                    //        - 3. position after rect j
                    //              +-----+    +-----+    +-----+
                    //              |  i  |    |  j  |    | pos |
                    //              +-----+    +-----+    +-----+

                    List <float> spacingPositions = GetSpacingPositions(sourceRect, firstRect, secondRect, startReference, endReference, referenceRects.Orientation);
                    AddSpacingPositions(spacingPositions, sourceRect, firstRect, secondRect, referenceRects.Orientation);
                }
            }
        }
Esempio n. 3
0
        Line2 GetSnapLine(Rect r1, SnapReference reference1, Rect r2, SnapReference reference2)
        {
            bool    horizontal = reference1 <= SnapReference.RightEdge;
            Line2   line1      = GetSnapLine(r1, reference1);
            Line2   line2      = GetSnapLine(r2, reference2);
            Vector2 p11        = line1.start
            , p12   = line1.end
            , p21   = line2.start
            , p22   = line2.end
            , start = Vector2.zero
            , end   = Vector2.zero;

            if (horizontal)
            {
                float x    = p21.x;
                float yMin = Math.Min(p22.y, Math.Min(p21.y, Math.Min(p11.y, p12.y)));
                float yMax = Math.Max(p22.y, Math.Max(p21.y, Math.Max(p11.y, p12.y)));
                start = new Vector2(x, yMin);
                end   = new Vector2(x, yMax);
            }
            else
            {
                float y    = p22.y;
                float xMin = Math.Min(p22.x, Math.Min(p21.x, Math.Min(p11.x, p12.x)));
                float xMax = Math.Max(p22.x, Math.Max(p21.x, Math.Max(p11.x, p12.x)));
                start = new Vector2(xMin, y);
                end   = new Vector2(xMax, y);
            }
            return(new Line2(start, end));
        }
Esempio n. 4
0
        internal static float GetPos(Rect rect, SnapReference reference)
        {
            switch (reference)
            {
            case SnapReference.LeftEdge:
                return(rect.x);

            case SnapReference.HorizontalCenter:
                return(rect.center.x);

            case SnapReference.RightEdge:
                return(rect.xMax);

            case SnapReference.TopEdge:
                return(rect.y);

            case SnapReference.VerticalCenter:
                return(rect.center.y);

            case SnapReference.BottomEdge:
                return(rect.yMax);

            default:
                return(0);
            }
        }
Esempio n. 5
0
        List <SnapResult> GetClosestSnapElements(Rect sourceRect, Orientation orientation)
        {
            SnapReference     startReference  = orientation == Orientation.Horizontal ? SnapReference.LeftEdge : SnapReference.TopEdge;
            SnapReference     centerReference = orientation == Orientation.Horizontal ? SnapReference.HorizontalCenter : SnapReference.VerticalCenter;
            SnapReference     endReference    = orientation == Orientation.Horizontal ? SnapReference.RightEdge : SnapReference.BottomEdge;
            List <SnapResult> results         = new List <SnapResult>(3);
            SnapResult        result          = GetClosestSnapElement(sourceRect, startReference, startReference, centerReference, endReference);

            if (result != null)
            {
                results.Add(result);
            }
            result = GetClosestSnapElement(sourceRect, centerReference, startReference, centerReference, endReference);
            if (result != null)
            {
                results.Add(result);
            }
            result = GetClosestSnapElement(sourceRect, endReference, startReference, centerReference, endReference);
            if (result != null)
            {
                results.Add(result);
            }
            // Look for the minimum
            if (results.Count > 0)
            {
                results.Sort((a, b) => a.distance.CompareTo(b.distance));
                float minDistance = results[0].distance;
                results.RemoveAll(r => Math.Abs(r.distance - minDistance) > 0.01f);
            }
            return(results);
        }
Esempio n. 6
0
        SnapResult GetClosestSnapElement(Rect sourceRect, SnapReference sourceRef, Rect snappableRect, SnapReference startReference, SnapReference centerReference, SnapReference endReference)
        {
            float         sourcePos             = GetPos(sourceRect, sourceRef);
            float         offsetStart           = sourcePos - GetPos(snappableRect, startReference);
            float         offsetEnd             = sourcePos - GetPos(snappableRect, endReference);
            float         minOffset             = offsetStart;
            SnapReference minSnappableReference = startReference;

            if (Math.Abs(minOffset) > Math.Abs(offsetEnd))
            {
                minOffset             = offsetEnd;
                minSnappableReference = endReference;
            }
            SnapResult minResult = new SnapResult
            {
                sourceRect         = sourceRect,
                sourceReference    = sourceRef,
                snappableRect      = snappableRect,
                snappableReference = minSnappableReference,
                offset             = minOffset
            };

            if (minResult.distance <= snapDistance * 1 / m_CurrentScale)
            {
                return(minResult);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        float GetClosestGridLine(Rect rect, SnapReference reference)
        {
            switch (reference)
            {
            case SnapReference.LeftEdge:
                return(GetClosestGridLine(rect.xMin));

            case SnapReference.HorizontalCenter:
                return(GetClosestGridLine(rect.center.x));

            case SnapReference.RightEdge:
                return(GetClosestGridLine(rect.xMax));

            case SnapReference.TopEdge:
                return(GetClosestGridLine(rect.yMin));

            case SnapReference.VerticalCenter:
                return(GetClosestGridLine(rect.center.y));

            case SnapReference.BottomEdge:
                return(GetClosestGridLine(rect.yMax));

            default:
                return(0);
            }
        }
Esempio n. 8
0
        float GetPositionWithBorder(Rect rect, SnapReference reference)
        {
            // We need to take account of the selected element's content container's border width to snap on it
            switch (reference)
            {
            case SnapReference.LeftEdge:
                return(rect.x - m_BorderWidth.Left);

            case SnapReference.HorizontalCenter:
                return(rect.center.x);

            case SnapReference.RightEdge:
                return(rect.xMax + m_BorderWidth.Right);

            case SnapReference.TopEdge:
                return(rect.y - m_BorderWidth.Top);

            case SnapReference.VerticalCenter:
                return(rect.center.y);

            case SnapReference.BottomEdge:
                return(rect.yMax + m_BorderWidth.Bottom);

            default:
                return(0);
            }
        }
Esempio n. 9
0
        SnapResult GetClosestSnapElement(Rect sourceRect, SnapReference sourceRef, SnapReference startReference, SnapReference centerReference, SnapReference endReference)
        {
            SnapResult minResult   = null;
            float      minDistance = float.MaxValue;

            foreach (Rect snappableRect in m_SnappableRects)
            {
                SnapResult result = GetClosestSnapElement(sourceRect, sourceRef, snappableRect, startReference, centerReference, endReference);
                if (result != null && minDistance > result.distance)
                {
                    minDistance = result.distance;
                    minResult   = result;
                }
            }
            return(minResult);
        }
Esempio n. 10
0
        List <SpacingLine> GetSpacingLines(List <Rect> rects, Orientation orientation)
        {
            SnapReference startReference = orientation == Orientation.Vertical ? SnapReference.BottomEdge : SnapReference.RightEdge;
            SnapReference endReference   = orientation == Orientation.Vertical ? SnapReference.TopEdge : SnapReference.LeftEdge;

            float maxCoordinate         = rects.Max(rect => orientation == Orientation.Vertical ? rect.xMax : rect.yMax) + SpacingLine.DefaultSpacingLineSideLength;
            float spacingLineSideLength = SpacingLine.DefaultSpacingLineSideLength / m_CurrentScale;

            Vector2 firstSidePos  = GetMaxPos(rects[0], startReference);
            Vector2 secondSidePos = GetMaxPos(rects[1], endReference);
            Vector2 thirdSidePos  = GetMaxPos(rects[1], startReference);
            Vector2 fourthSidePos = GetMaxPos(rects[2], endReference);

            return(new List <SpacingLine>
            {
                GetSpacingLine(maxCoordinate, spacingLineSideLength, firstSidePos, secondSidePos, orientation),
                GetSpacingLine(maxCoordinate, spacingLineSideLength, thirdSidePos, fourthSidePos, orientation)
            });
        }
Esempio n. 11
0
        Line2 GetSnapLine(Rect r, SnapReference reference)
        {
            Vector2 start = Vector2.zero,
                    end   = Vector2.zero;

            switch (reference)
            {
            case SnapReference.LeftEdge:
                start = r.position;
                end   = new Vector2(r.x, r.yMax);
                break;

            case SnapReference.HorizontalCenter:
                start = r.center;
                end   = start;
                break;

            case SnapReference.RightEdge:
                start = new Vector2(r.xMax, r.yMin);
                end   = new Vector2(r.xMax, r.yMax);
                break;

            case SnapReference.TopEdge:
                start = r.position;
                end   = new Vector2(r.xMax, r.yMin);
                break;

            case SnapReference.VerticalCenter:
                start = r.center;
                end   = start;
                break;

            default:     // case SnapReference.BottomEdge:
                start = new Vector2(r.x, r.yMax);
                end   = new Vector2(r.xMax, r.yMax);
                break;
            }
            return(new Line2(start, end));
        }
Esempio n. 12
0
        SnapToGridResult GetClosestGridLine(Rect sourceRect, SnapReference sourceRef, SnapReference startReference, SnapReference endReference)
        {
            float sourcePos   = GetPositionWithBorder(sourceRect, sourceRef);
            float offsetStart = sourcePos - GetClosestGridLine(sourceRect, startReference);
            float offsetEnd   = sourcePos - GetClosestGridLine(sourceRect, endReference);
            float minOffset   = offsetStart;

            SnapReference minSnappableReference = startReference;

            if (Math.Abs(minOffset) > Math.Abs(offsetEnd))
            {
                minOffset             = offsetEnd;
                minSnappableReference = endReference;
            }

            SnapToGridResult minResult = new SnapToGridResult()
            {
                SnappableReference = minSnappableReference,
                Offset             = minOffset
            };

            return(minResult.Distance <= SnapDistance * 1 / m_CurrentScale ? minResult : null);
        }
Esempio n. 13
0
        static List <float> GetSpacingPositions(Rect sourceRect, Rect firstRect, Rect secondRect, SnapReference startReference, SnapReference endReference, Orientation orientation)
        {
            if (AreElementsSuperposed(firstRect, secondRect, orientation))
            {
                return(null);
            }

            Vector2 firstRectStartPos  = GetMaxPos(firstRect, startReference);
            Vector2 firstRectEndPos    = GetMaxPos(firstRect, endReference);
            Vector2 secondRectStartPos = GetMaxPos(secondRect, startReference);
            Vector2 secondRectEndPos   = GetMaxPos(secondRect, endReference);

            List <float> positions = orientation == Orientation.Vertical ?
                                     ComputeSpacingPositions(firstRectStartPos.y, firstRectEndPos.y, secondRectStartPos.y, secondRectEndPos.y, sourceRect.height * 0.5f) :
                                     ComputeSpacingPositions(firstRectStartPos.x, firstRectEndPos.x, secondRectStartPos.x, secondRectEndPos.x, sourceRect.width * 0.5f);

            return(positions);
        }