private void Draw(double x, double y, double currentLineHeight, double contentXEnd, double contentYEnd, Queue <VisioShape> components) { while (components.Count > 0) { VisioShape toDraw = components.Dequeue(); double toDrawWidth = toDraw.MarginLeft + toDraw.Width + toDraw.MarginRight; //expected increase in x double toDrawHeight = toDraw.MarginTop + toDraw.Height + toDraw.MarginBottom; //expected height in y PrepareContainerExpansion(x, y, toDrawWidth, 0); //if the container streches to support the drawing, the container height does not need to change if ((toManage.CenterX + (toManage.Width / 2.0)) < (x + toDrawWidth)) //the new component does not fit next to the last component on the same line in the container { x = toManage.CenterX - (toManage.Width / 2.0); //go to a new line y -= currentLineHeight; //the new line of components should not overlap with the one above PrepareContainerExpansion(x, y, 0, toDrawHeight); } double dropX = x + toDraw.MarginLeft + (toDraw.Width / 2.0); double dropY = y - toDraw.MarginTop - (toDraw.Height / 2.0); double deltaX = dropX - toDraw.CenterX; double deltaY = dropY - toDraw.CenterY; toDraw.CenterX = dropX; toDraw.CenterY = dropY; if (toDraw is RationallyContainer) { foreach (VisioShape c in ((RationallyContainer)toDraw).Children) { c.CenterX += deltaX; c.CenterY += deltaY; c.MoveChildren(deltaX, deltaY); } } else { toDraw.MoveChildren(deltaX, deltaY); } x = x + toDrawWidth; currentLineHeight = Math.Max(currentLineHeight, toDrawHeight); contentXEnd = Math.Max(contentXEnd, dropX + (toDrawWidth / 2.0)); contentYEnd = Math.Min(contentYEnd, y - toDrawHeight); } //the container might still be not high enough, if the initial height is very small and expandX is true if (((toManage.UsedSizingPolicy & SizingPolicy.ExpandYIfNeeded) > 0) && (currentLineHeight > toManage.Height)) { double topLeftY = toManage.CenterY + (toManage.Height / 2.0); toManage.Height = currentLineHeight; toManage.CenterY = topLeftY - (toManage.Height / 2.0); } ShrinkContainer(contentXEnd, contentYEnd); }
/// <summary> /// Places the component first in line in the container, at (x,y) /// </summary> /// <param name="x">top left x-coordinate to start drawing the component.</param> /// <param name="y">top left y-coordinate to start drawing the component.</param> /// <param name="components">Queue of components to draw.</param> private void Draw(double x, double y, Queue <VisioShape> components) { while (components.Count > 0) { VisioShape toDraw = components.Dequeue(); double totalWidthToDraw = toDraw.MarginLeft + toDraw.Width + toDraw.MarginRight; double totalHeightToDraw = toDraw.MarginTop + toDraw.Height + toDraw.MarginBottom; //allow container to stretch horizontally and/or vertically if the content component overflows in those directions PrepareContainerExpansion(x, y, totalWidthToDraw, totalHeightToDraw); //this layout stacks components vertically and stretches them horizontally to the width of the container StretchComponentIfNeeded(toDraw, toManage.Width); //calculate position to draw this component double drawX = x + (toDraw.Width / 2.0) + toDraw.MarginLeft; double drawY = y - (toDraw.Height / 2.0) - toDraw.MarginTop; double deltaX = drawX - toDraw.CenterX; double deltaY = drawY - toDraw.CenterY; if (toDraw is RationallyContainer) { foreach (VisioShape c in ((RationallyContainer)toDraw).Children) { if (c.Shape.ContainerProperties != null) { //moving children will disband the composite pattern between the shapes => remember children and later rebuild the pattern c.StoreChildren(); c.MoveChildren(deltaX, deltaY); } c.CenterX += deltaX; c.CenterY += deltaY; if (c.Shape.ContainerProperties != null) { c.RestoreChildren(); } } } else { toDraw.MoveChildren(deltaX, deltaY); } toDraw.CenterX = drawX; toDraw.CenterY = drawY; //update x and y for the next component //x remains the same y = y - (toDraw.MarginTop + toDraw.Height + toDraw.MarginBottom); } ShrinkContainer(y); //y points below the last added component }