예제 #1
0
        /// <summary>
        /// Organizes the shapes added with <see cref="AddShape(ShapeElement)"/> or similar methods.
        /// </summary>
        /// <param name="ignoreExistingShapes">Do not adjust for existing shapes</param>
        /// <param name="referenceShape">Layout shapes to the right of this shape.</param>
        /// <param name="layoutRightOfReferenceShape">Set to layout to the right of the <paramref name="referenceShape"/></param>
        /// <param name="layoutBelowReferenceShape">Set to layout below the <paramref name="referenceShape"/></param>
        public void Layout(bool ignoreExistingShapes, NodeShape referenceShape, bool layoutRightOfReferenceShape, bool layoutBelowReferenceShape)
        {
            LayoutShape     backupRoot = null;
            LayoutShapeList allShapes  = myLayoutShapes;

            switch (allShapes.Count)
            {
            case 0:
                return;

            default:
                backupRoot = allShapes[0];
                break;
            }
            myLayoutEngine.LateBind(myDiagram, allShapes);

            SizeD margin = myDiagram.NestedShapesMargin;

            if (referenceShape != null &&
                (layoutRightOfReferenceShape || layoutBelowReferenceShape))
            {
                RectangleD referenceBounds = referenceShape.AbsoluteBounds;
                if (layoutRightOfReferenceShape)
                {
                    margin.Width = Math.Max(margin.Width, referenceBounds.Right);
                }
                if (layoutBelowReferenceShape)
                {
                    margin.Height = Math.Max(margin.Height, referenceBounds.Bottom);
                }
            }
            PointD     minimumPoint    = new PointD(margin.Width, margin.Height);
            RectangleD layoutRectangle = new RectangleD(minimumPoint, SizeD.Empty);
            bool       firstPass       = true;

            for (; ;)
            {
                LayoutShape mostRelatives = myLayoutEngine.ResolveReferences(allShapes);
                LayoutShape root          = null;
                // If the root shape was set by the user, AND the shape exists in our shape list
                if (myRootShape == null || !allShapes.TryGetValue(myRootShape, out root))
                {
                    root = GetRoot(mostRelatives);
                }
                if (root == null)
                {
                    if (backupRoot == null)
                    {
                        myLayoutEngine.PostLayout(minimumPoint);
                        break;
                    }
                    root = backupRoot;
                }

                // run the layout of base shapes
                myLayoutEngine.PerformLayout(root, new PointD(margin.Width, layoutRectangle.Bottom + (firstPass ? 0 : root.Shape.Size.Height)), ref layoutRectangle);
                firstPass   = false;
                backupRoot  = null;
                myRootShape = null;
            }

            Reflow(ignoreExistingShapes);
        }