Esempio n. 1
0
    void AccumulateNegativeDesiredHeight(RPNode node, double y)
    {
        double initialY = y;
        bool   isVerticallyCenteredFromTop    = false;
        bool   isVerticallyCenteredFromBottom = false;

        MUX_ASSERT(node.IsMeasured());

        // If we are going in the negative direction, move the cursor
        // down by the desired height of the node with which we are
        // currently working and refresh the minimum negative value.
        y     -= node.GetDesiredHeight();
        m_minY = Math.Min(m_minY, y);

        if (node.IsAlignBottomWithPanel())
        {
            if (!m_isMinCapped)
            {
                m_minY        = y;
                m_isMinCapped = true;
            }
        }
        else if (node.IsAlignBottomWith())
        {
            // If the AlignBottomWithNode and AlignTopWithNode are the
            // same element, we can skip the former, since we will move
            // through the latter later.
            if (node.m_alignBottomWithNode != node.m_alignTopWithNode)
            {
                AccumulatePositiveDesiredHeight(node.m_alignBottomWithNode, y);
            }
        }
        else if (node.IsAlignVerticalCenterWith())
        {
            isVerticallyCenteredFromBottom = true;
        }
        else if (node.IsAbove())
        {
            AccumulateNegativeDesiredHeight(node.m_aboveNode, y);
        }

        if (node.IsAlignTopWithPanel())
        {
            if (m_isMaxCapped)
            {
                m_maxY = Math.Max(m_maxY, initialY);
            }
            else
            {
                m_maxY        = initialY;
                m_isMaxCapped = true;
            }
        }
        else if (node.IsAlignTopWith())
        {
            // If this element's top is aligned to some other element's
            // top, now we will be going in the negative direction to
            // that other element in order to continue the traversal of
            // the dependency chain. But first, since we arrived to the
            // node where we currently are by going in the negative
            // direction, that means that we have already moved the
            // cursor down to calculate the minimum negative value,
            // so we will use the initial value of Y.
            AccumulateNegativeDesiredHeight(node.m_alignTopWithNode, initialY);
        }
        else if (node.IsAlignVerticalCenterWith())
        {
            isVerticallyCenteredFromTop = true;
        }
        else if (node.IsBelow())
        {
            // If this element is below some other element, now we'll
            // be going in the positive direction to that other element
            // in order to continue the traversal of the dependency
            // chain. But first, since we arrived to the node where we
            // currently are by going in the negative direction, that
            // means that we have already moved the cursor down to
            // calculate the minimum negative value, so we will use
            // the initial value of Y.
            AccumulatePositiveDesiredHeight(node.m_belowNode, initialY);
        }

        if (isVerticallyCenteredFromTop && isVerticallyCenteredFromBottom)
        {
            double centerY = y + (node.GetDesiredHeight() / 2.0f);
            double edgeY   = centerY + (node.m_alignVerticalCenterWithNode.GetDesiredHeight() / 2.0f);
            m_maxY = Math.Max(m_maxY, edgeY);
            AccumulateNegativeDesiredHeight(node.m_alignVerticalCenterWithNode, edgeY);
        }
        else if (node.IsVerticalCenterAnchored())
        {
            // If this node is vertically anchored to the center, then it
            // means that it is the root of this dependency chain based on
            // the current definition of precedence for raints:
            // e.g. AlignTopWithPanel
            // > AlignTopWith
            // > Below
            // > AlignVerticalCenterWithPanel
            // Thus, we can report its height as twice the height of
            // either the difference from center to top or the difference
            // from center to bottom, whichever is the greatest.
            double centerY = y + (node.GetDesiredHeight() / 2.0f);
            double upper   = m_maxY - centerY;
            double lower   = centerY - m_minY;
            m_maxY = Math.Max(upper, lower) * 2.0f;
            m_minY = 0.0f;
        }
    }
Esempio n. 2
0
    private void CalculateMeasureRectVertically(RPNode node, Size availableSize, out double y, out double height)
    {
        bool isVerticallyCenteredFromTop    = false;
        bool isVerticallyCenteredFromBottom = false;

        // The initial values correspond to the entire available space. In
        // other words, the edges of the element are aligned to the edges
        // of the panel by default. We will now rain each side of this
        // space as necessary.
        y      = 0.0f;
        height = availableSize.Height;

        // If we have infinite available height, then the Height of the
        // MeasureRect is also infinite; we do not have to rain it.
        if (availableSize.Height != double.PositiveInfinity)
        {
            // Constrain the top of the available space, i.e.
            // a) The child has its top edge aligned with the panel (default),
            // b) The child has its top edge aligned with the top edge of a sibling,
            // or c) The child is positioned to the below a sibling.
            //
            //  ================================== AlignTopWithPanel
            //  .................
            //
            //
            //
            //  --------;;=============;;--------- AlignTopWith
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //  --------.=============.--------- Below
            //                  .
            //                .:;:.
            //              .:;;;;;:.
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //
            //          ;;......:;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ........:
            //
            if (!node.IsAlignTopWithPanel())
            {
                if (node.IsAlignTopWith())
                {
                    RPNode alignTopWithNeighbor    = node.m_alignTopWithNode;
                    double restrictedVerticalSpace = alignTopWithNeighbor.m_arrangeRect.Y;

                    y       = restrictedVerticalSpace;
                    height -= restrictedVerticalSpace;
                }
                else if (node.IsAlignVerticalCenterWith())
                {
                    isVerticallyCenteredFromTop = true;
                }
                else if (node.IsBelow())
                {
                    RPNode belowNeighbor           = node.m_belowNode;
                    double restrictedVerticalSpace = belowNeighbor.m_arrangeRect.Y + belowNeighbor.m_arrangeRect.Height;

                    y       = restrictedVerticalSpace;
                    height -= restrictedVerticalSpace;
                }
            }

            // Constrain the bottom of the available space, i.e.
            // a) The child has its bottom edge aligned with the panel (default),
            // b) The child has its bottom edge aligned with the bottom edge of a sibling,
            // or c) The child is positioned to the above a sibling.
            //
            //          ;;......:;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ........:
            //
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //                ;;;;;
            //              ..;;;;;..
            //               '..:'
            //                 ':`
            //
            //  --------;;=============;;--------- Above
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //          ;;             ;;
            //  --------.=============.--------- AlignBottomWith
            //
            //
            //
            //  .................
            //  ================================== AlignBottomWithPanel
            //
            if (!node.IsAlignBottomWithPanel())
            {
                if (node.IsAlignBottomWith())
                {
                    RPNode alignBottomWithNeighbor = node.m_alignBottomWithNode;

                    height -= availableSize.Height - (alignBottomWithNeighbor.m_arrangeRect.Y + alignBottomWithNeighbor.m_arrangeRect.Height);
                }
                else if (node.IsAlignVerticalCenterWith())
                {
                    isVerticallyCenteredFromBottom = true;
                }
                else if (node.IsAbove())
                {
                    RPNode aboveNeighbor = node.m_aboveNode;

                    height -= availableSize.Height - aboveNeighbor.m_arrangeRect.Y;
                }
            }

            if (isVerticallyCenteredFromTop && isVerticallyCenteredFromBottom)
            {
                RPNode alignVerticalCenterWithNeighbor = node.m_alignVerticalCenterWithNode;
                double centerOfNeighbor = alignVerticalCenterWithNeighbor.m_arrangeRect.Y + (alignVerticalCenterWithNeighbor.m_arrangeRect.Height / 2.0f);
                height = Math.Min(centerOfNeighbor, availableSize.Height - centerOfNeighbor) * 2.0f;
                y      = centerOfNeighbor - (height / 2.0f);
            }
        }
    }