/// <summary> /// Applies layout changes to a given box and its children. /// </summary> public override void ApplyVerticalLayout([NotNull] LayoutState state, [NotNull] LayoutState.LayoutLevel level) { var node = level.BranchRoot; if (node.State.NumberOfSiblings <= MaxGroups * 2) { base.ApplyVerticalLayout(state, level); return; } if (node.Level == 0) { node.State.SiblingsRowV = new Dimensions(node.State.Top, node.State.Bottom); } if (node.AssistantsRoot != null) { // assistants root has to be initialized with main node's exterior node.AssistantsRoot.State.CopyExteriorFrom(node.State); LayoutAlgorithm.VerticalLayout(state, node.AssistantsRoot); } var adapter = new SingleFishboneLayoutAdapter(node); while (adapter.NextGroup()) { LayoutAlgorithm.VerticalLayout(state, adapter.SpecialRoot); } }
/// <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); } } }