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);
        }