/// <summary> /// Help making a copy of a <see cref="DiagramLayout"/>. /// </summary> /// <param name="layout"></param> /// <remarks> /// This is just called by the copy-constructors of classes that inherit from this one. /// </remarks> protected DiagramLayout(DiagramLayout layout) { if (layout != null) { this.Id = layout.Id; this.ArrangementOrigin = layout.ArrangementOrigin; } }
/// <summary> /// This predicate is true if <see cref="IDiagramLayout.CanLayoutPart"/> /// is true for any of its <see cref="Layouts"/>. /// </summary> /// <param name="part"></param> /// <returns></returns> public bool CanLayoutPart(Part part) { foreach (IDiagramLayout layout in this.Layouts) { if (layout is MultiLayout) { Diagram.Error("MultiLayouts cannot be nested"); return(false); } DiagramLayout lay = layout as DiagramLayout; if (lay != null) { lay.DataContext = this.DataContext; //?? support databinding of Layout properties } if (layout.CanLayoutPart(part)) { return(true); } } return(false); }
/// <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; } } } }
internal void AddUpdateLinks(DiagramLayout layout, Action update) { if (!this.Animated) return; // just for top-level layout, not for groups if (layout.Group == null) { if (this.UpdateLinksActions == null) this.UpdateLinksActions = new List<Action>(); this.UpdateLinksActions.Add(update); } }