void UpdateRightOffsetCount(ZNode rightChildNode, ref float rightIndex) { List <ZNode> children = rightChildNode.GetChildren(); int childCount = children.Count; if (childCount > 0) { if (childCount > 1) { rightIndex += (childCount / 2) * _nodeEditor.SkinItem.autoLayoutWidth; } UpdateLeftOffsetCount(children[children.Count - 1], ref rightIndex); UpdateRightOffsetCount(children[children.Count - 1], ref rightIndex); } }
void DoAutoArrangeHorizontal(ZNode parentNode) { float parentX = parentNode.GetOriginalRect().x; float parentY = parentNode.GetOriginalRect().y; List <ZNode> children = parentNode.GetChildren(); int childCount = children.Count; // Case 1: no children if (childCount == 0) { return; } // Case 2: one child if (childCount <= 1) { children[0].SetPosition(parentX + _nodeEditor.SkinItem.autoLayoutHeight, parentY); DoAutoArrangeHorizontal(children[0]); return; } // Case 3: multiple children bool isEvenTree = (childCount % 2 == 0); int mid = childCount / 2; if (!isEvenTree) { // middle child of this tree stays under parent position children[mid].SetPosition(parentX + _nodeEditor.SkinItem.autoLayoutHeight, parentY); DoAutoArrangeHorizontal(children[mid]); } // process left children int i = mid - 1; while (i >= 0) { float startY = parentY; if (i < mid - 1) { startY = children[i + 1].GetOriginalRect().y; } float y = startY - _nodeEditor.SkinItem.autoLayoutWidth; // Check my rightmost child float rightIndex = 0; UpdateRightOffsetCount(children[i], ref rightIndex); y -= rightIndex; if ((isEvenTree && i < mid - 1) || (!isEvenTree)) { // Check my right neighbors left most child ZNode rightNbr = children[i + 1]; float rightNbrLeftIndex = 0; UpdateLeftOffsetCount(rightNbr, ref rightNbrLeftIndex); y -= rightNbrLeftIndex; } children[i].SetPosition(parentX + _nodeEditor.SkinItem.autoLayoutHeight, y); DoAutoArrangeHorizontal(children[i]); i--; } // process right children i = isEvenTree?mid:mid + 1; while (i < children.Count) { float startY = parentY; if ((isEvenTree && i > mid) || (!isEvenTree && i > mid + 1)) { startY = children[i - 1].GetOriginalRect().y; } float y = startY + _nodeEditor.SkinItem.autoLayoutWidth; // Shift to the right based on left most child (recursive check) float leftIndex = 0; UpdateLeftOffsetCount(children[i], ref leftIndex); y += leftIndex; if ((isEvenTree && i > mid) || (!isEvenTree)) { // Check left neighbor's rightmost child for another right shift for spacing ZNode leftNbr = children[i - 1]; float leftNbrLeftIndex = 0; UpdateRightOffsetCount(leftNbr, ref leftNbrLeftIndex); y += leftNbrLeftIndex; } children[i].SetPosition(parentX + _nodeEditor.SkinItem.autoLayoutHeight, y); DoAutoArrangeHorizontal(children[i]); i++; } }