public void RecalcPositions() { DependencyTree <IRectangleSizeDecorator> deps = BuildDependenciesTree(); // 1. Make sure each node's initial size is the same as its rectangle size. deps.WalkTreeRootFirst(CopyPhysicalSize); // 2. Arrange the nodes in groups with known width and height. deps.WalkTreeChildrenFirst(ArrangeNodes); // 3. Calculate the physical size of all the nodes. // Treat the nodes decendants as part of the node itself. //deps.WalkTreeChildrenFirst(CalcPhysicalSizeRecursive); // 4. Sort everything by its physical size. //deps.WalkTreeChildrenFirst(SortByPhysicalSize); // 5. Set the positions of the nodes. deps.WalkTreeRootFirst(SetupPositions); deps.WalkTreeRootFirst(MoveSubTreeByParentPosition); float y = 0; foreach (DependencyTreeNode <IRectangleSizeDecorator> group in deps.Root.Dependants) { if (group.Item == null) { continue; } MoveSubTreeBy(group, 0, y); y += group.Item.Height + YSpacing; } }
private void MoveSubTreeBy(DependencyTreeNode <IRectangleSizeDecorator> root, float x, float y) { DependencyTree <IRectangleSizeDecorator> .WalkTreeRootFirst( root, delegate(IRectangleSizeDecorator rect) { if (rect == null) { return; } rect.Rectangle.X += x; rect.Rectangle.Y += y; }); }
private DependencyTree <IRectangleSizeDecorator> BuildDependenciesTree() { DependencyTree <IRectangleSizeDecorator> deps = new DependencyTree <IRectangleSizeDecorator>(); foreach (Route r in routes) { deps.AddDependency(new IRectangleSizeDecorator(r.From), new IRectangleSizeDecorator(r.To)); } foreach (IRectangle r in rects) { deps.AddDependency(new IRectangleSizeDecorator(r), deps.Root.Item); } return(deps); }