Exemplo n.º 1
0
        /// <summary>
        /// Applies layout changes to a given box and its children.
        /// </summary>
        public override void ApplyHorizontalLayout([NotNull] LayoutState state, [NotNull] LayoutState.LayoutLevel level)
        {
            var node = level.BranchRoot;

            if (node.AssistantsRoot != null)
            {
                LayoutAlgorithm.HorizontalLayout(state, node.AssistantsRoot);
            }

            for (var i = 0; i < node.State.NumberOfSiblings; i++)
            {
                var child = node.Children[i];
                // re-enter layout algorithm for child branch
                LayoutAlgorithm.HorizontalLayout(state, child);
            }

            if (node.Level > 0 && node.ChildCount > 0)
            {
                var rect          = node.State;
                var leftmost      = node.Children[0].State.CenterH;
                var rightmost     = node.Children[node.State.NumberOfSiblings - 1].State.CenterH;
                var desiredCenter =
                    node.State.NumberOfSiblings == 1 || ParentAlignment == BranchParentAlignment.Center
                    ? leftmost + (rightmost - leftmost) / 2
                    : ParentAlignment == BranchParentAlignment.Left
                    ? leftmost + ChildConnectorHookLength
                    : rightmost - ChildConnectorHookLength;
                var center = rect.CenterH;
                var diff   = center - desiredCenter;
                LayoutAlgorithm.MoveChildrenOnly(state, level, diff);

                // vertical connector from parent
                var verticalSpacer = node.Children[node.State.NumberOfSiblings];
                verticalSpacer.State.AdjustSpacer(
                    center - ParentConnectorShield / 2, rect.Bottom,
                    ParentConnectorShield, node.Children[0].State.SiblingsRowV.From - rect.Bottom);

                state.MergeSpacer(verticalSpacer);

                // horizontal protector
                var firstInRow = node.Children[0].State;

                var horizontalSpacer = node.Children[node.State.NumberOfSiblings + 1];
                horizontalSpacer.State.AdjustSpacer(
                    firstInRow.Left,
                    firstInRow.SiblingsRowV.From - ParentChildSpacing,
                    node.Children[node.State.NumberOfSiblings - 1].State.Right - firstInRow.Left,
                    ParentChildSpacing);
                state.MergeSpacer(horizontalSpacer);
            }
        }
        /// <summary>
        /// Applies layout changes to a given box and its children.
        /// </summary>
        public override void ApplyHorizontalLayout([NotNull] LayoutState state, [NotNull] LayoutState.LayoutLevel level)
        {
            var node = level.BranchRoot;

            var nodeState = node.State;

            if (node.AssistantsRoot != null)
            {
                LayoutAlgorithm.HorizontalLayout(state, node.AssistantsRoot);
            }

            // first, perform horizontal layout for every node in this column
            for (var row = 0; row < nodeState.NumberOfSiblings; row++)
            {
                var child = node.Children[row];

                // re-enter layout algorithm for child branch
                // siblings are guaranteed not to offend each other
                LayoutAlgorithm.HorizontalLayout(state, child);
            }

            // now align the column
            var edges = LayoutAlgorithm.AlignHorizontalCenters(state, level, EnumerateColumn(node));

            if (node.Level > 0 && node.ChildCount > 0)
            {
                var    rect = node.State;
                double diff;
                if (ParentAlignment == BranchParentAlignment.Left)
                {
                    var desiredLeft = rect.CenterH + ParentConnectorShield / 2;
                    diff = desiredLeft - edges.From;
                }
                else if (ParentAlignment == BranchParentAlignment.Right)
                {
                    var desiredRight = rect.CenterH - ParentConnectorShield / 2;
                    diff = desiredRight - edges.To;
                }
                else
                {
                    throw new InvalidOperationException("Invalid ParentAlignment setting");
                }

                // vertical connector from parent
                LayoutAlgorithm.MoveChildrenOnly(state, level, diff);

                // spacer for the vertical carrier
                var verticalSpacer = node.Level > 0 ? node.Children[node.ChildCount - 1] : null;
                if (verticalSpacer != null)
                {
                    var spacerTop    = node.State.Bottom;
                    var spacerBottom = node.Children[node.ChildCount - 2].State.Bottom;
                    verticalSpacer.State.AdjustSpacer(
                        rect.CenterH - ParentConnectorShield / 2, spacerTop,
                        ParentConnectorShield, spacerBottom - spacerTop);
                    state.MergeSpacer(verticalSpacer);
                }
            }
        }
        /// <summary>
        /// Applies layout changes to a given box and its children.
        /// </summary>
        public override void ApplyHorizontalLayout([NotNull] LayoutState state, [NotNull] LayoutState.LayoutLevel level)
        {
            var node = level.BranchRoot;

            if (node.State.NumberOfSiblings <= MaxSiblingsPerRow)
            {
                // fall back to linear layout, only have one row of boxes
                base.ApplyHorizontalLayout(state, level);
                return;
            }

            if (node.AssistantsRoot != null)
            {
                LayoutAlgorithm.HorizontalLayout(state, node.AssistantsRoot);
            }

            for (var col = 0; col < node.State.NumberOfSiblingColumns; col++)
            {
                // first, perform horizontal layout for every node in this column
                for (var row = 0; row < node.State.NumberOfSiblingRows; row++)
                {
                    var ix = row * node.State.NumberOfSiblingColumns + col;
                    if (ix >= node.State.NumberOfSiblings)
                    {
                        break;
                    }

                    var child = node.Children[ix];
                    // re-enter layout algorithm for child branch
                    LayoutAlgorithm.HorizontalLayout(state, child);
                }

                LayoutAlgorithm.AlignHorizontalCenters(state, level, EnumerateColumn(node, col));
            }

            // now align children under parent
            var rect          = node.State;
            var spacer        = node.Children[node.State.NumberOfSiblingColumns / 2];
            var desiredCenter = spacer.State.CenterH;
            var diff          = rect.CenterH - desiredCenter;

            LayoutAlgorithm.MoveChildrenOnly(state, level, diff);

            // vertical connector from parent
            var verticalSpacer = node.Children[node.State.NumberOfSiblings];

            verticalSpacer.State.AdjustSpacer(
                rect.CenterH - ParentConnectorShield / 2, rect.Bottom,
                ParentConnectorShield, node.Children[0].State.SiblingsRowV.From - rect.Bottom);
            state.MergeSpacer(verticalSpacer);

            // horizontal row carrier protectors
            var spacing = ParentChildSpacing;

            for (var firstInRowIndex = 0; firstInRowIndex < node.State.NumberOfSiblings; firstInRowIndex += node.State.NumberOfSiblingColumns)
            {
                var firstInRow = node.Children[firstInRowIndex].State;
                var lastInRow  = node.Children[Math.Min(firstInRowIndex + node.State.NumberOfSiblingColumns - 1, node.State.NumberOfSiblings - 1)].State;

                var horizontalSpacer = node.Children[1 + node.State.NumberOfSiblings + firstInRowIndex / node.State.NumberOfSiblingColumns];

                var width = lastInRow.Right >= verticalSpacer.State.Right
                    ? lastInRow.Right - firstInRow.Left
                    : // extend protector at least to the central carrier
                            verticalSpacer.State.Right - firstInRow.Left;

                horizontalSpacer.State.AdjustSpacer(
                    firstInRow.Left, firstInRow.SiblingsRowV.From - spacing,
                    width, spacing);
                state.MergeSpacer(horizontalSpacer);

                spacing = SiblingSpacing;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Applies layout changes to a given box and its children.
        /// </summary>
        public override void ApplyHorizontalLayout([NotNull] LayoutState state, [NotNull] LayoutState.LayoutLevel level)
        {
            var node = level.BranchRoot;

            if (node.State.NumberOfSiblings <= MaxGroups * 2)
            {
                base.ApplyHorizontalLayout(state, level);
                return;
            }

            if (node.Level == 0)
            {
                node.State.SiblingsRowV = new Dimensions(node.State.Top, node.State.Bottom);
            }

            if (node.AssistantsRoot != null)
            {
                LayoutAlgorithm.HorizontalLayout(state, node.AssistantsRoot);
            }

            var adapter = new SingleFishboneLayoutAdapter(node);

            while (adapter.NextGroup())
            {
                LayoutAlgorithm.HorizontalLayout(state, adapter.SpecialRoot);
            }

            var rect = node.State;

            // now align child nodes under the parent
            if (node.Level > 0)
            {
                double diff;
                if (node.State.NumberOfSiblingColumns > 1)
                {
                    var leftCarrier  = node.Children[node.State.NumberOfSiblings + 1].State.CenterH;
                    var rightCarrier = node.Children[node.State.NumberOfSiblings + node.State.NumberOfSiblingColumns].State.CenterH;

                    var desiredCenter =
                        node.State.NumberOfSiblings == 1 || ParentAlignment == BranchParentAlignment.Center
                    ? leftCarrier + (rightCarrier - leftCarrier) / 2
                    : ParentAlignment == BranchParentAlignment.Left
                    ? leftCarrier + ChildConnectorHookLength
                    : rightCarrier - ChildConnectorHookLength;

                    //var desiredCenter = (leftCarrier + rightCarrier)/2.0;
                    diff = rect.CenterH - desiredCenter;
                }
                else
                {
                    var carrier       = node.Children[1 + node.State.NumberOfSiblings].State.CenterH;
                    var desiredCenter = rect.CenterH;
                    diff = desiredCenter - carrier;
                }
                LayoutAlgorithm.MoveChildrenOnly(state, level, diff);
            }

            if (node.Level > 0)
            {
                // vertical connector from parent
                var ix             = node.State.NumberOfSiblings;
                var verticalSpacer = node.Children[ix];
                verticalSpacer.State.AdjustSpacer(
                    rect.CenterH - ParentConnectorShield / 2, rect.Bottom,
                    ParentConnectorShield, node.Children[0].State.SiblingsRowV.From - rect.Bottom);
                state.MergeSpacer(verticalSpacer);
                ix++;

                // vertical carriers already merged in
                ix += node.State.NumberOfSiblingColumns;

                if (node.State.NumberOfSiblingColumns > 1)
                {
                    // have a horizontal carrier
                    var horizontalSpacer = node.Children[ix];
                    var leftmost         = node.Children[node.State.NumberOfSiblings + 1].State.TopLeft;
                    var rightmost        = node.Children[ix - 1].State.Right;
                    horizontalSpacer.State.AdjustSpacer(
                        leftmost.X, leftmost.Y - ParentChildSpacing,
                        rightmost - leftmost.X, ParentChildSpacing);
                    state.MergeSpacer(horizontalSpacer);
                }
            }
        }