Пример #1
0
        public SMRect EnforceDocking(BorderNodeGeometry geometry)
        {
            float constrainedY = Math.Max(StructureThickness.Top, geometry.Bounds.Y);

            // _rect.Bottom already accounts for StructureThickness - see the constructor.
            constrainedY = Math.Min(constrainedY, _rect.Bottom - geometry.Bounds.Height);
            switch (geometry.Docking)
            {
            case BorderNodeDocking.Left:
                return(new SMRect(-EdgeOverflow, constrainedY, geometry.Bounds.Width, geometry.Bounds.Height));

            case BorderNodeDocking.Right:
                return(new SMRect(_rect.Width - geometry.Bounds.Width + EdgeOverflow, constrainedY, geometry.Bounds.Width, geometry.Bounds.Height));

            default:
                break;
            }
            return(geometry.Bounds);
        }
Пример #2
0
        public BorderNodeGeometry ConstrainBounds(BorderNodeGeometry geom, RectDifference oldMinusNew)
        {
            // ShiftRegisters cannot change docking, so first force the geometry to dock, this coerces crazy X values
            SMRect coercedInput = EnforceDocking(geom);

            // Now we are going to iterate up and down the side of the structure, looking for a location in which
            // both the left and the right registers are clear. We start with the right being the coerced input
            // and the left being the actual left shift register's bounds _except_ it's Y, which we want to move in sync with it's pair
            SMRect rightBounds = coercedInput;
            SMRect leftBounds  = PairedBeginLifetimeTunnel.Bounds;

            leftBounds.Y = rightBounds.Y;

            // Before we start scanning, make sure our current location doesn't just work, if it does we're done
            if (IsGood(leftBounds, rightBounds))
            {
                return(new BorderNodeGeometry(rightBounds, BorderNodeDocking.Right));
            }

            const float DistanceToIterateBy  = StockDiagramGeometries.GridSize;
            SMRect      rightSideUpIteration = rightBounds;

            rightSideUpIteration.Y -= DistanceToIterateBy;

            SMRect leftSideUpIteration = leftBounds;

            leftSideUpIteration.Y -= DistanceToIterateBy;

            SMRect rightSideDownIteration = rightBounds;

            rightSideDownIteration.Y += DistanceToIterateBy;

            SMRect leftSideDownIteration = leftBounds;

            leftSideDownIteration.Y += DistanceToIterateBy;

            bool favorUp      = oldMinusNew.Y > 0 || oldMinusNew.X > 0;
            bool favorDown    = oldMinusNew.Y < 0 || oldMinusNew.X < 0;
            bool favorNeither = !favorUp && !favorDown;

            // prevent overlap. Starting from our bounds calculation, move outward to find closest. Make sure we don't leave structure.
            while (true)
            {
                if (favorUp || favorNeither)
                {
                    if (IsGood(leftSideUpIteration, rightSideUpIteration))
                    {
                        return(new BorderNodeGeometry(rightSideUpIteration, BorderNodeDocking.Right));
                    }
                    if (!IsInBounds(leftSideUpIteration, rightSideUpIteration))
                    {
                        favorUp = false;
                    }
                    rightSideUpIteration.Y -= DistanceToIterateBy;
                    leftSideUpIteration.Y  -= DistanceToIterateBy;
                }
                if (favorDown || favorNeither)
                {
                    if (IsGood(leftSideDownIteration, rightSideDownIteration))
                    {
                        return(new BorderNodeGeometry(rightSideDownIteration, BorderNodeDocking.Right));
                    }
                    if (!IsInBounds(leftSideDownIteration, rightSideDownIteration))
                    {
                        favorDown = false;
                    }
                    rightSideDownIteration.Y += DistanceToIterateBy;
                    leftSideDownIteration.Y  += DistanceToIterateBy;
                }

                if (favorNeither && !IsInBounds(leftSideUpIteration, rightSideUpIteration) && !IsInBounds(leftSideDownIteration, rightSideDownIteration))
                {
                    // Give up, neither is within bounds.
                    break;
                }

                favorNeither = !favorUp && !favorDown;
            }
            return(new BorderNodeGeometry(rightBounds, BorderNodeDocking.Right));
        }