Пример #1
0
        // Set x,y,width,height of each Node
        public static CanvasDefinition GenerateLayout(
            IList <Node> Nodes,
            double Padding,
            CanvasDefinition.LayoutDirection Direction = CanvasDefinition.LayoutDirection.LeftToRight
            )
        {
            CanvasDefinition Canvas = null;

            if (Nodes == null || Nodes.Count == 0)
            {
                return(null);
            }

            var RootNodes = from n in Nodes
                            where n.ParentNodes.Count == 0
                            select n;

            if (RootNodes != null)
            {
                #region Assign individual Node to slots, and update Node.x/Node.y
                GridSizingInfo SizingInfo = GenerateGraph(RootNodes, Direction, Padding);

                Canvas = new CanvasDefinition()
                {
                    Direction = Direction
                };
                Canvas.NumSlotsHorizontal = (from Entry in SizingInfo.MaxColumnWidths
                                             select Entry.Value).Count();
                Canvas.NumSlotsVertical = (from Entry in SizingInfo.MaxRowHeights
                                           select Entry.Value).Count();
                Canvas.Width = (from Entry in SizingInfo.MaxColumnWidths
                                select Entry.Value).Sum() + Canvas.NumSlotsHorizontal * Padding;
                Canvas.Height = (from Entry in SizingInfo.MaxRowHeights
                                 select Entry.Value).Sum() + Canvas.NumSlotsVertical * Padding;
                #endregion
            }
            else
            {
                throw new ArgumentException("There must be at least one root node");
            }

            return(Canvas);
        }
Пример #2
0
        protected static GridSizingInfo GenerateGraph(
            IEnumerable <Node> RootNodes,
            CanvasDefinition.LayoutDirection Direction,
            double Padding)
        {
            int            i          = 0;
            int            j          = 0;
            GridSizingInfo SizingInfo = new GridSizingInfo();

            foreach (Node RootNode in RootNodes)
            {
                RootNode.Width  = RootNode.Width * 1.25;
                RootNode.Height = RootNode.Height * 1.25;
            }

            RecursiveGenerateGrid(RootNodes, SizingInfo, Direction, i, j);
            RecursivePositionSlots(RootNodes, SizingInfo, Direction, Padding);

            return(SizingInfo);
        }
Пример #3
0
        // Employ "Depth First" strategy (As supposed to "Breath First")
        protected static void RecursiveGenerateGrid(
            IEnumerable <Node> Nodes,
            GridSizingInfo SizingInfo,
            CanvasDefinition.LayoutDirection Direction,
            int i, int j)
        {
            int NumDecendantsLeaveNodes = 0;

            foreach (Node n in Nodes)
            {
                NumDecendantsLeaveNodes = FindNumDecendantsLeaveNodes(n);

                #region Set Slot
                switch (Direction)
                {
                case CanvasDefinition.LayoutDirection.LeftToRight:
                    n.xSlot = i;
                    n.ySlot = j;

                    SizingInfo.UpdateSizingInfo(n);

                    RecursiveGenerateGrid(n.ChildNodes, SizingInfo, Direction, i + 1, j);
                    j += NumDecendantsLeaveNodes > 0 ? NumDecendantsLeaveNodes : 1;
                    break;

                case CanvasDefinition.LayoutDirection.TopToBottom:
                    n.xSlot = i;
                    n.ySlot = j;

                    SizingInfo.UpdateSizingInfo(n);

                    RecursiveGenerateGrid(n.ChildNodes, SizingInfo, Direction, i, j + 1);
                    i += NumDecendantsLeaveNodes > 0 ? NumDecendantsLeaveNodes : 1;
                    break;
                }
                #endregion
            }

            return;
        }
Пример #4
0
        protected static void RecursivePositionSlots(
            IEnumerable <Node> Nodes,
            GridSizingInfo SizingInfo,
            CanvasDefinition.LayoutDirection Direction,
            double Padding
            )
        {
            double CumulativeWidth  = 0;
            double CumulativeHeight = 0;

            foreach (Node n in Nodes)
            {
                #region Set Slot Position
                CumulativeWidth  = 0;
                CumulativeHeight = 0;

                CumulativeWidth = 0;
                for (int i = 0; i < n.xSlot; i++)
                {
                    CumulativeWidth += (SizingInfo.MaxColumnWidths[i] + Padding);
                }

                for (int j = 0; j < n.ySlot; j++)
                {
                    CumulativeHeight += (SizingInfo.MaxRowHeights[j] + Padding);
                }

                n.x = CumulativeWidth;
                n.y = CumulativeHeight;

                if (n.ChildNodes.Count > 0)
                {
                    #region Center node alignment
                    double Offset = 0;
                    int    k      = 0;
                    switch (Direction)
                    {
                    case CanvasDefinition.LayoutDirection.LeftToRight:
                        double ChildNodeHeight = 0;
                        foreach (Node ChildNode in n.ChildNodes)
                        {
                            ChildNodeHeight = FindChildHeight(ChildNode, Padding);
                            if (k < n.ChildNodes.Count - 1)
                            {
                                Offset += (ChildNodeHeight + Padding);
                            }
                            else
                            {
                                Offset += (ChildNodeHeight);
                            }

                            k++;
                        }

                        Offset -= (n.Height);
                        n.y    += (Offset / 2.0);
                        break;

                    case CanvasDefinition.LayoutDirection.TopToBottom:
                        double ChildNodeWidth = 0;
                        foreach (Node ChildNode in n.ChildNodes)
                        {
                            ChildNodeWidth = FindChildWidth(ChildNode, Padding);
                            if (k < n.ChildNodes.Count - 1)
                            {
                                Offset += (ChildNodeWidth + Padding);
                            }
                            else
                            {
                                Offset += (ChildNodeWidth);
                            }

                            k++;
                        }

                        Offset -= (n.Width);
                        n.x    += (Offset / 2.0);
                        break;
                    }
                    #endregion
                }

                RecursivePositionSlots(n.ChildNodes, SizingInfo, Direction, Padding);
                #endregion
            }

            return;
        }