/// <summary> /// Actually perform all of the <see cref="Layouts"/> for the given nodes and links. /// </summary> /// <param name="nodes"></param> /// <param name="links"></param> /// <remarks> /// This iterates over the layouts in <see cref="Layouts"/>. /// If the layout's <see cref="IDiagramLayout.ValidLayout"/> is false, /// it gets the subsets of nodes and links that apply to that particular layout /// and then calls <see cref="IDiagramLayout.DoLayout"/> on it. /// </remarks> public void DoLayout(IEnumerable <Node> nodes, IEnumerable <Link> links) { Diagram diagram = this.Diagram; if (diagram == null) { return; } if (diagram.Panel == null) { return; } LayoutManager mgr = diagram.LayoutManager; Northwoods.GoXam.Tool.DraggingTool tool = diagram.DraggingTool; if (tool == null) { tool = new Northwoods.GoXam.Tool.DraggingTool(); } Point pos = this.ArrangementOrigin; foreach (IDiagramLayout layout in this.Layouts) { bool invalidlayout = !layout.ValidLayout; if (invalidlayout || this.Arrangement != MultiArrangement.None) //??? need to move networks of valid layouts { IEnumerable <Node> subnodes = (mgr != null ? nodes.Where(n => mgr.CanLayoutPart(n, layout)) : nodes); IEnumerable <Link> sublinks = (mgr != null ? links.Where(l => mgr.CanLayoutPart(l, layout)) : links); if (invalidlayout) { //Diagram.Debug("multilayout " + layout.Id + " of " + Diagram.Str(layout.Group) + ": INVALID " + subnodes.Count().ToString() + " nodes " + sublinks.Count().ToString() + " links " + Diagram.Str(subnodes.ToArray()) + " at " + Diagram.Str(pos)); DiagramLayout dlay = layout as DiagramLayout; if (dlay != null) { dlay.ArrangementOrigin = pos; } layout.DoLayout(subnodes, sublinks); } //?? need to make sure all links are routed, so their Bounds aren't bogus Rect b = diagram.Panel.ComputeBounds(subnodes.OfType <Part>() /*.Concat<Part>(sublinks.OfType<Part>())*/); if (!invalidlayout && !b.IsEmpty) { //Diagram.Debug("multilayout " + layout.Id + " of " + Diagram.Str(layout.Group) + ": MOVING " + subnodes.Count().ToString() + " nodes " + sublinks.Count().ToString() + " links " + Diagram.Str(new Point(pos.X-b.X, pos.Y-b.Y)) + " computedBounds: " + Diagram.Str(b)); var dict = tool.ComputeEffectiveCollection(subnodes.OfType <Part>()); tool.MoveParts(dict, new Point(pos.X - b.X, pos.Y - b.Y)); } switch (this.Arrangement) { case MultiArrangement.None: break; case MultiArrangement.Horizontal: if (b.Width > 0) { pos.X += b.Width; pos.X += this.ArrangementSpacing.Width; } break; case MultiArrangement.Vertical: if (b.Height > 0) { pos.Y += b.Height; pos.Y += this.ArrangementSpacing.Height; } break; } } } }