Beispiel #1
0
        // Surchage pour pouvoir accéder à la méthode protégée de PortPlacementHelper
        /// <summary>
        /// Gets the next edge children.
        /// </summary>
        /// <param name="currentEdge">The current edge.</param>
        /// <param name="parentShape">The parent shape.</param>
        /// <param name="edgeList">The edge list.</param>
        /// <param name="center">The center.</param>
        /// <returns></returns>
        protected override PortPlacement GetNextEdgeChildren(PortPlacement currentEdge, NodeShape parentShape,
                                                             out ArrayList edgeList, out PointD center)
        {
            PortPlacement placement = PortPlacement.None;

            do
            {
                placement = base.GetNextEdgeChildren(currentEdge, parentShape, out edgeList, out center);
            } while (placement == PortPlacement.Top || placement == PortPlacement.Bottom);

            return(placement);
        }
Beispiel #2
0
        /// <summary>
        /// This function corrects the given proposed location if the given child shape is a relative shape and
        /// is only allowed to be placed on the edge of its parent.
        /// </summary>
        /// <param name="parentShape">Parent shape.</param>
        /// <param name="childShape">Child shape.</param>
        /// <param name="proposedLocation">Proposed location.</param>
        /// <remarks>
        /// This function needs to be called withing a modeling transaction.
        ///
        /// This function assigns new values to Location and PortPlacement if necessary.
        /// </remarks>
        /// <returns>
        /// Location that was assigned to the shape. It might have the same value as the location
        /// the shape had before calling this function.
        /// </returns>
        public static PointD CorrectPortLocation(NodeShape parentShape, NodeShape childShape, PointD proposedLocation)
        {
            if (parentShape == null)
            {
                throw new ArgumentNullException("parentShape");
            }

            if (childShape == null)
            {
                throw new ArgumentNullException("childShape");
            }

            if (!childShape.IsRelativeChildShape || childShape.MovementBehaviour != ShapeMovementBehaviour.PositionOnEdgeOfParent)
            {
                return(proposedLocation);
            }

            RectangleD rectParent     = parentShape.Bounds;
            RectangleD proposedBounds = new RectangleD(proposedLocation, childShape.Size);

            PortPlacement placement = NodeShape.GetPortPlacement(rectParent, proposedBounds);

            return(CorrectPortLocation(placement, parentShape, childShape, proposedLocation));
        }
Beispiel #3
0
        private static bool SetPortAtFreePositionOnParent(NodeShape shape, PortPlacement side, RectangleF freeRectangle)
        {
            List <RectangleF> freeRectangles = new List <RectangleF>();

            freeRectangles.Add(freeRectangle);

            for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++)
            {
                if (shape.Parent.RelativeChildren[i] == shape)
                {
                    continue;
                }

                if (shape.Parent.RelativeChildren[i].PlacementSide != side)
                {
                    continue;
                }

                RectangleF s = shape.Parent.RelativeChildren[i].Bounds.ToRectangleF();
                for (int y = freeRectangles.Count - 1; y >= 0; y--)
                {
                    RectangleF r = freeRectangles[y];
                    RectangleF t = r;
                    r.Intersect(s);

                    if (!r.IsEmpty)
                    {
                        // remove r from freeRectangley[y] --> yields <=2 rects
                        // add 2 rects to freeRectangles
                        freeRectangles.RemoveAt(y);

                        switch (side)
                        {
                        case PortPlacement.Left:
                        case PortPlacement.Right:
                            if (t.Y < r.Y)
                            {
                                // first r
                                RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y);
                                freeRectangles.Add(r1);
                            }

                            if (r.Bottom < t.Bottom)
                            {
                                // second r
                                RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom);
                                freeRectangles.Add(r2);
                            }
                            break;

                        case PortPlacement.Top:
                        case PortPlacement.Bottom:
                            if (t.X < r.X)
                            {
                                // first r
                                RectangleF r1 = new RectangleF(t.X, t.Y, r.X - t.X, t.Height);
                                freeRectangles.Add(r1);
                            }

                            if (r.Right < t.Right)
                            {
                                // second r
                                RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right - r.Right, t.Height);
                                freeRectangles.Add(r2);
                            }
                            break;
                        }
                    }
                }
            }

            // try to place at a fitting free rectangle
            foreach (RectangleF r in freeRectangles)
            {
                if (r.Width >= shape.Bounds.Width && r.Height >= shape.Bounds.Height)
                {
                    shape.Location      = new PointD(r.X, r.Y);
                    shape.PlacementSide = side;
                    shape.UpdateAbsoluteLocation();
                    return(true);
                }
            }

            return(false);
        }
        private static bool SetPortAtFreePositionOnParent(NodeShape shape, PortPlacement side, RectangleF freeRectangle)
        {
            List<RectangleF> freeRectangles = new List<RectangleF>();
            freeRectangles.Add(freeRectangle);

            for (int i = 0; i < shape.Parent.RelativeChildren.Count; i++)
            {
                if (shape.Parent.RelativeChildren[i] == shape)
                    continue;

                if (shape.Parent.RelativeChildren[i].PlacementSide != side)
                    continue;

                RectangleF s = shape.Parent.RelativeChildren[i].Bounds.ToRectangleF();
                for (int y = freeRectangles.Count - 1; y >= 0; y--)
                {
                    RectangleF r = freeRectangles[y];
                    RectangleF t = r;
                    r.Intersect(s);

                    if (!r.IsEmpty)
                    {
                        // remove r from freeRectangley[y] --> yields <=2 rects
                        // add 2 rects to freeRectangles
                        freeRectangles.RemoveAt(y);

                        switch (side)
                        {
                            case PortPlacement.Left:
                            case PortPlacement.Right:
                                if (t.Y < r.Y)
                                {
                                    // first r
                                    RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y);
                                    freeRectangles.Add(r1);
                                }

                                if (r.Bottom < t.Bottom)
                                {
                                    // second r
                                    RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom);
                                    freeRectangles.Add(r2);
                                }
                                break;

                            case PortPlacement.Top:
                            case PortPlacement.Bottom:
                                if (t.X < r.X)
                                {
                                    // first r
                                    RectangleF r1 = new RectangleF(t.X, t.Y, r.X - t.X, t.Height);
                                    freeRectangles.Add(r1);
                                }

                                if (r.Right < t.Right)
                                {
                                    // second r
                                    RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right - r.Right, t.Height);
                                    freeRectangles.Add(r2);
                                }
                                break;
                        }

                    }
                }
            }

            // try to place at a fitting free rectangle
            foreach (RectangleF r in freeRectangles)
            {
                if (r.Width >= shape.Bounds.Width && r.Height >= shape.Bounds.Height)
                {
                    shape.Location = new PointD(r.X, r.Y);
                    shape.PlacementSide = side;
                    shape.UpdateAbsoluteLocation();
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// This function corrects the given proposed location if the given child shape is a relative shape and
        /// is only allowed to be placed on the edge of its parent.
        /// </summary>
        /// <param name="placement">Proposed placement.</param>
        /// <param name="parentShape">Parent shape.</param>
        /// <param name="childShape">Child shape.</param>
        /// <param name="proposedLocation">Proposed location.</param>
        /// <remarks>
        /// This function needs to be called withing a modeling transaction.
        /// 
        /// This function assigns new values to Location and PortPlacement if necessary.
        /// </remarks>
        /// <returns>
        /// Location that was assigned to the shape. It might have the same value as the location 
        /// the shape had before calling this function.
        /// </returns>
        public static PointD CorrectPortLocation(PortPlacement placement, NodeShape parentShape, NodeShape childShape, PointD proposedLocation)
        {
            PointD newLocation = proposedLocation;
            RectangleD rectParent = parentShape.Bounds;

            switch (placement)
            {
                case PortPlacement.Left:
                    newLocation.X = -childShape.Size.Width / 2.0;
                    if (newLocation.Y < 0.0)
                        newLocation.Y = 0.0;
                    else if (newLocation.Y > (rectParent.Height - childShape.Size.Height))
                        newLocation.Y = rectParent.Height - childShape.Size.Height;
                    break;

                case PortPlacement.Top:
                    newLocation.Y = -childShape.Size.Height / 2.0;
                    if (newLocation.X < 0.0)
                        newLocation.X = 0.0;
                    else if (newLocation.X > (rectParent.Width - childShape.Size.Width))
                        newLocation.X = rectParent.Width - childShape.Size.Width;
                    break;

                case PortPlacement.Right:
                    newLocation.X = rectParent.Width - (childShape.Size.Width / 2.0);
                    if (newLocation.Y < 0.0)
                        newLocation.Y = 0.0;
                    else if (newLocation.Y > (rectParent.Height - childShape.Size.Height))
                        newLocation.Y = rectParent.Height - childShape.Size.Height;
                    break;

                case PortPlacement.Bottom:
                    newLocation.Y = rectParent.Height - (childShape.Size.Height / 2.0);
                    if (newLocation.X < 0.0)
                        newLocation.X = 0.0;
                    else if (newLocation.X > (rectParent.Width - childShape.Size.Width))
                        newLocation.X = rectParent.Width - childShape.Size.Width;
                    break;
            }

            if (childShape.Location != newLocation)
            {
                childShape.Location = newLocation;
                childShape.PlacementSide = placement;
                childShape.UpdateAbsoluteLocation();
            }

            return newLocation;
        }
Beispiel #6
0
        /// <summary>
        /// This function corrects the given proposed location if the given child shape is a relative shape and
        /// is only allowed to be placed on the edge of its parent.
        /// </summary>
        /// <param name="placement">Proposed placement.</param>
        /// <param name="parentShape">Parent shape.</param>
        /// <param name="childShape">Child shape.</param>
        /// <param name="proposedLocation">Proposed location.</param>
        /// <remarks>
        /// This function needs to be called withing a modeling transaction.
        ///
        /// This function assigns new values to Location and PortPlacement if necessary.
        /// </remarks>
        /// <returns>
        /// Location that was assigned to the shape. It might have the same value as the location
        /// the shape had before calling this function.
        /// </returns>
        public static PointD CorrectPortLocation(PortPlacement placement, NodeShape parentShape, NodeShape childShape, PointD proposedLocation)
        {
            PointD     newLocation = proposedLocation;
            RectangleD rectParent  = parentShape.Bounds;

            switch (placement)
            {
            case PortPlacement.Left:
                newLocation.X = -childShape.Size.Width / 2.0;
                if (newLocation.Y < 0.0)
                {
                    newLocation.Y = 0.0;
                }
                else if (newLocation.Y > (rectParent.Height - childShape.Size.Height))
                {
                    newLocation.Y = rectParent.Height - childShape.Size.Height;
                }
                break;

            case PortPlacement.Top:
                newLocation.Y = -childShape.Size.Height / 2.0;
                if (newLocation.X < 0.0)
                {
                    newLocation.X = 0.0;
                }
                else if (newLocation.X > (rectParent.Width - childShape.Size.Width))
                {
                    newLocation.X = rectParent.Width - childShape.Size.Width;
                }
                break;

            case PortPlacement.Right:
                newLocation.X = rectParent.Width - (childShape.Size.Width / 2.0);
                if (newLocation.Y < 0.0)
                {
                    newLocation.Y = 0.0;
                }
                else if (newLocation.Y > (rectParent.Height - childShape.Size.Height))
                {
                    newLocation.Y = rectParent.Height - childShape.Size.Height;
                }
                break;

            case PortPlacement.Bottom:
                newLocation.Y = rectParent.Height - (childShape.Size.Height / 2.0);
                if (newLocation.X < 0.0)
                {
                    newLocation.X = 0.0;
                }
                else if (newLocation.X > (rectParent.Width - childShape.Size.Width))
                {
                    newLocation.X = rectParent.Width - childShape.Size.Width;
                }
                break;
            }

            if (childShape.Location != newLocation)
            {
                childShape.Location      = newLocation;
                childShape.PlacementSide = placement;
                childShape.UpdateAbsoluteLocation();
            }

            return(newLocation);
        }