Esempio n. 1
0
    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);
            }
        }
    }