Esempio n. 1
0
    private void AccumulateNegativeDesiredWidth(RPNode node, double x)
    {
        double initialX = x;
        bool   isHorizontallyCenteredFromLeft  = false;
        bool   isHorizontallyCenteredFromRight = false;

        MUX_ASSERT(node.IsMeasured());

        // If we are going in the negative direction, move the cursor
        // left by the desired width of the node with which we are
        // currently working and refresh the minimum negative value.
        x     -= node.GetDesiredWidth();
        m_minX = Math.Min(m_minX, x);

        if (node.IsAlignRightWithPanel())
        {
            if (!m_isMinCapped)
            {
                m_minX        = x;
                m_isMinCapped = true;
            }
        }
        else if (node.IsAlignRightWith())
        {
            // If the AlignRightWithNode and AlignLeftWithNode are the
            // same element, we can skip the former, since we will move
            // through the latter later.
            if (node.m_alignRightWithNode != node.m_alignLeftWithNode)
            {
                AccumulatePositiveDesiredWidth(node.m_alignRightWithNode, x);
            }
        }
        else if (node.IsAlignHorizontalCenterWith())
        {
            isHorizontallyCenteredFromRight = true;
        }
        else if (node.IsLeftOf())
        {
            AccumulateNegativeDesiredWidth(node.m_leftOfNode, x);
        }

        if (node.IsAlignLeftWithPanel())
        {
            if (m_isMaxCapped)
            {
                m_maxX = Math.Max(m_maxX, initialX);
            }
            else
            {
                m_maxX        = initialX;
                m_isMaxCapped = true;
            }
        }
        else if (node.IsAlignLeftWith())
        {
            // If this element's left is aligned to some other element's
            // left, 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 left to calculate the minimum negative value,
            // so we will use the initial value of X.
            AccumulateNegativeDesiredWidth(node.m_alignLeftWithNode, initialX);
        }
        else if (node.IsAlignHorizontalCenterWith())
        {
            isHorizontallyCenteredFromLeft = true;
        }
        else if (node.IsRightOf())
        {
            // If this element is to the right of some other element,
            // now we will 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 left to calculate the minimum negative value, so
            // we will use the initial value of X.
            AccumulatePositiveDesiredWidth(node.m_rightOfNode, initialX);
        }

        if (isHorizontallyCenteredFromLeft && isHorizontallyCenteredFromRight)
        {
            double centerX = x + (node.GetDesiredWidth() / 2.0f);
            double edgeX   = centerX + (node.m_alignHorizontalCenterWithNode.GetDesiredWidth() / 2.0f);
            m_maxX = Math.Max(m_maxX, edgeX);
            AccumulateNegativeDesiredWidth(node.m_alignHorizontalCenterWithNode, edgeX);
        }
        else if (node.IsHorizontalCenterAnchored())
        {
            // If this node is horizontally 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. AlignLeftWithPanel
            // > AlignLeftWith
            // > RightOf
            // > AlignHorizontalCenterWithPanel
            // Thus, we can report its width as twice the width of
            // either the difference from center to left or the difference
            // from center to right, whichever is the greatest.
            double centerX = x + (node.GetDesiredWidth() / 2.0f);
            double upper   = m_maxX - centerX;
            double lower   = centerX - m_minX;
            m_maxX = Math.Max(upper, lower) * 2.0f;
            m_minX = 0.0f;
        }
    }
Esempio n. 2
0
    private void CalculateMeasureRectHorizontally(RPNode node, Size availableSize, out double x, out double width)
    {
        bool isHorizontallyCenteredFromLeft  = false;
        bool isHorizontallyCenteredFromRight = 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.
        x     = 0.0f;
        width = availableSize.Width;

        // If we have infinite available width, then the Width of the
        // MeasureRect is also infinite; we do not have to rain it.
        if (availableSize.Width != double.PositiveInfinity)
        {
            // Constrain the left side of the available space, i.e.
            // a) The child has its left edge aligned with the panel (default),
            // b) The child has its left edge aligned with the left edge of a sibling,
            // or c) The child is positioned to the right of a sibling.
            //
            //  |;;                 |               |
            //  |;;                 |               |
            //  |;;                 |:::::::::::::::|                       ;;:::::::::::::;;
            //  |;;                 |;             ;|       .               ;;             ;;
            //  |;;                 |;             ;|     .;;............   ;;             ;;
            //  |;;                 |;             ;|   .;;;;::::::::::::   ;;             ;;
            //  |;;                 |;             ;|    ':;;::::::::::::   ;;             ;;
            //  |;;                 |;             ;|      ':               ;;             ;;
            //  |;;                 |:::::::::::::::|                       :::::::::::::::::
            //  |;;                 |               |
            //  |;;                 |               |
            //  AlignLeftWithPanel  AlignLeftWith   RightOf
            //
            if (!node.IsAlignLeftWithPanel())
            {
                if (node.IsAlignLeftWith())
                {
                    RPNode alignLeftWithNeighbor     = node.m_alignLeftWithNode;
                    double restrictedHorizontalSpace = alignLeftWithNeighbor.m_arrangeRect.X;

                    x      = restrictedHorizontalSpace;
                    width -= restrictedHorizontalSpace;
                }
                else if (node.IsAlignHorizontalCenterWith())
                {
                    isHorizontallyCenteredFromLeft = true;
                }
                else if (node.IsRightOf())
                {
                    RPNode rightOfNeighbor           = node.m_rightOfNode;
                    double restrictedHorizontalSpace = rightOfNeighbor.m_arrangeRect.X + rightOfNeighbor.m_arrangeRect.Width;

                    x      = restrictedHorizontalSpace;
                    width -= restrictedHorizontalSpace;
                }
            }

            // Constrain the right side of the available space, i.e.
            // a) The child has its right edge aligned with the panel (default),
            // b) The child has its right edge aligned with the right edge of a sibling,
            // or c) The child is positioned to the left of a sibling.
            //
            //                                          |               |                   ;;|
            //                                          |               |                   ;;|
            //  ;;:::::::::::::;;                       |;:::::::::::::;|                   ;;|
            //  ;;             ;;               .       |;             ;|                   ;;|
            //  ;;             ;;   ............;;.     |;             ;|                   ;;|
            //  ;;             ;;   ::::::::::::;;;;.   |;             ;|                   ;;|
            //  ;;             ;;   ::::::::::::;;:'    |;             ;|                   ;;|
            //  ;;             ;;               :'      |;             ;|                   ;;|
            //  :::::::::::::::::                       |:::::::::::::::|                   ;;|
            //                                          |               |                   ;;|
            //                                          |               |                   ;;|
            //                                          LeftOf          AlignRightWith      AlignRightWithPanel
            //
            if (!node.IsAlignRightWithPanel())
            {
                if (node.IsAlignRightWith())
                {
                    RPNode alignRightWithNeighbor = node.m_alignRightWithNode;

                    width -= availableSize.Width - (alignRightWithNeighbor.m_arrangeRect.X + alignRightWithNeighbor.m_arrangeRect.Width);
                }
                else if (node.IsAlignHorizontalCenterWith())
                {
                    isHorizontallyCenteredFromRight = true;
                }
                else if (node.IsLeftOf())
                {
                    RPNode leftOfNeighbor = node.m_leftOfNode;

                    width -= availableSize.Width - leftOfNeighbor.m_arrangeRect.X;
                }
            }

            if (isHorizontallyCenteredFromLeft && isHorizontallyCenteredFromRight)
            {
                RPNode alignHorizontalCenterWithNeighbor = node.m_alignHorizontalCenterWithNode;
                double centerOfNeighbor = alignHorizontalCenterWithNeighbor.m_arrangeRect.X + (alignHorizontalCenterWithNeighbor.m_arrangeRect.Width / 2.0f);
                width = Math.Min(centerOfNeighbor, availableSize.Width - centerOfNeighbor) * 2.0f;
                x     = centerOfNeighbor - (width / 2.0f);
            }
        }
    }