private void ArrangeNodeVertically(RPNode node, Size finalSize) { if (node == null) { return; } if (!node.IsArrangedVertically()) { // We must resolve dependencies first. ArrangeNodeVertically(node.m_leftOfNode, finalSize); ArrangeNodeVertically(node.m_aboveNode, finalSize); ArrangeNodeVertically(node.m_rightOfNode, finalSize); ArrangeNodeVertically(node.m_belowNode, finalSize); ArrangeNodeVertically(node.m_alignLeftWithNode, finalSize); ArrangeNodeVertically(node.m_alignTopWithNode, finalSize); ArrangeNodeVertically(node.m_alignRightWithNode, finalSize); ArrangeNodeVertically(node.m_alignBottomWithNode, finalSize); ArrangeNodeVertically(node.m_alignHorizontalCenterWithNode, finalSize); ArrangeNodeVertically(node.m_alignVerticalCenterWithNode, finalSize); double nodeMeasureRectY, nodeMeasureRectHeight; CalculateMeasureRectVertically(node, finalSize, out nodeMeasureRectY, out nodeMeasureRectHeight); node.m_measureRect.Y = nodeMeasureRectY; node.m_measureRect.Height = nodeMeasureRectHeight; double nodeArrangeRectY, nodeArrangeRectHeight; CalculateArrangeRectVertically(node, out nodeArrangeRectY, out nodeArrangeRectHeight); node.m_arrangeRect.Y = nodeArrangeRectY; node.m_arrangeRect.Height = nodeArrangeRectHeight; node.SetArrangedVertically(true); } }
private void MeasureNode(RPNode node, Size availableSize) { if (node == null) { return; } if (node.IsPending()) { // If the node is already in the process of being resolved // but we tried to resolve it again, that means we are in the // middle of circular dependency and we must throw an // InvalidOperationException. We will fail fast here and let // the CRelativePanel handle the rest. throw new InvalidOperationException("Circular dependency found in RelativePanel"); } else if (node.IsUnresolved()) { Size constrainedAvailableSize = new Size(); // We must resolve the dependencies of this node first. // In the meantime, we will mark the state as pending. node.SetPending(true); MeasureNode(node.m_leftOfNode, availableSize); MeasureNode(node.m_aboveNode, availableSize); MeasureNode(node.m_rightOfNode, availableSize); MeasureNode(node.m_belowNode, availableSize); MeasureNode(node.m_alignLeftWithNode, availableSize); MeasureNode(node.m_alignTopWithNode, availableSize); MeasureNode(node.m_alignRightWithNode, availableSize); MeasureNode(node.m_alignBottomWithNode, availableSize); MeasureNode(node.m_alignHorizontalCenterWithNode, availableSize); MeasureNode(node.m_alignVerticalCenterWithNode, availableSize); node.SetPending(false); double nodeMeasureRectX, nodeMeasureRectWidth, nodeMeasureRectY, nodeMeasureRectHeight; CalculateMeasureRectHorizontally(node, availableSize, out nodeMeasureRectX, out nodeMeasureRectWidth); CalculateMeasureRectVertically(node, availableSize, out nodeMeasureRectY, out nodeMeasureRectHeight); node.m_measureRect.X = nodeMeasureRectX; node.m_measureRect.Y = nodeMeasureRectY; node.m_measureRect.Width = nodeMeasureRectWidth; node.m_measureRect.Height = nodeMeasureRectHeight; constrainedAvailableSize.Width = Math.Max(node.m_measureRect.Width, 0.0f); constrainedAvailableSize.Height = Math.Max(node.m_measureRect.Height, 0.0f); node.Measure(constrainedAvailableSize); node.SetMeasured(true); // (Pseudo-) Arranging against infinity does not make sense, so // we will skip the calculations of the ArrangeRects if // necessary. During the true arrange pass, we will be given a // non-infinite final size; we will do the necessary // calculations until then. if (availableSize.Width != double.PositiveInfinity) { double nodeArrangeRectX, nodeArrangeRectWidth; CalculateArrangeRectHorizontally(node, out nodeArrangeRectX, out nodeArrangeRectWidth); node.m_arrangeRect.X = nodeArrangeRectX; node.m_arrangeRect.Width = nodeArrangeRectWidth; node.SetArrangedHorizontally(true); } if (availableSize.Height != double.PositiveInfinity) { double nodeArrangeRectY, nodeArrangeRectHeight; CalculateArrangeRectVertically(node, out nodeArrangeRectY, out nodeArrangeRectHeight); node.m_arrangeRect.Y = nodeArrangeRectY; node.m_arrangeRect.Height = nodeArrangeRectHeight; node.SetArrangedVertically(true); } } }