Exemplo n.º 1
0
        private void MeasureHorizontal(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
        {
            var   widthMode            = widthMeasureSpec.Mode;
            var   heightMode           = heightMeasureSpec.Mode;
            bool  isExactly            = (widthMode == MeasureSpecification.ModeType.Exactly);
            bool  matchHeight          = false;
            bool  allFillParent        = true;
            float maxHeight            = 0.0f;
            float alternativeMaxHeight = 0.0f;
            float weightedMaxHeight    = 0.0f;
            float totalWeight          = 0.0f;
            int   childrenCount        = IterateLayoutChildren().Count();

            // Reset measure variables
            totalLength = 0.0f;
            float usedExcessSpace          = 0.0f;
            HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
                                                                     MeasuredSize.StateType.MeasuredSizeOK);

            // 1st phase:
            // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs
            // to accumulate total used space in totalLength based on measured sizes and margins.
            // Weighted children are not measured at this phase.
            // Available space for weighted children will be calculated in the phase 2 based on totalLength value.
            // Max height of children is stored.
            foreach (LayoutItem childLayout in IterateLayoutChildren())
            {
                int     childDesiredHeight = childLayout.Owner.HeightSpecification;
                float   childWeight        = childLayout.Owner.Weight;
                Extents childMargin        = childLayout.Margin;
                totalWeight += childWeight;

                bool useExcessSpace = (childLayout.Owner.WidthSpecification == 0) && (childWeight > 0);
                if (isExactly && useExcessSpace)
                {
                    // Children to be laid out with excess space can be measured later
                    totalLength = Math.Max(totalLength, (totalLength + childMargin.Start + childMargin.End));
                }
                else
                {
                    if (useExcessSpace)
                    {
                        // Parent is not defined!!!
                        // The widthMode is either Unspecified or AtMost, and
                        // this child is only laid out using excess space. Measure
                        // using WrapContent so that we can find out the view's
                        // optimal width.
                        MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(
                            new MeasureSpecification(
                                new LayoutLength(widthMeasureSpec.Size - (childLayout.Margin.Start + childLayout.Margin.End)),
                                widthMeasureSpec.Mode),
                            new LayoutLength(Padding.Start + Padding.End),
                            new LayoutLength(LayoutParamPolicies.WrapContent));

                        MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(
                            new MeasureSpecification(
                                new LayoutLength(heightMeasureSpec.Size - (childLayout.Margin.Top + childLayout.Margin.Bottom)),
                                heightMeasureSpec.Mode),
                            new LayoutLength(Padding.Top + Padding.Bottom),
                            new LayoutLength(childDesiredHeight));

                        childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
                        usedExcessSpace += childLayout.MeasuredWidth.Size.AsDecimal();
                    }
                    else
                    {
                        MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
                    }

                    LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                    LayoutLength length     = childWidth + childMargin.Start + childMargin.End;

                    totalLength = Math.Max(totalLength, totalLength + length.AsDecimal());
                }

                bool matchHeightLocally = false;
                if (heightMode != MeasureSpecification.ModeType.Exactly && childDesiredHeight == LayoutParamPolicies.MatchParent)
                {
                    // A child has set to MatchParent on it's height.
                    // Will have to re-measure at least this child when we know exact height.
                    matchHeight        = true;
                    matchHeightLocally = true;
                }

                float marginHeight = childMargin.Top + childMargin.Bottom;
                float childHeight  = childLayout.MeasuredHeight.Size.AsDecimal() + marginHeight;

                if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                {
                    childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                }
                if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                {
                    childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                }

                maxHeight     = Math.Max(maxHeight, childHeight);
                allFillParent = (allFillParent && childDesiredHeight == LayoutParamPolicies.MatchParent);

                if (childWeight > 0)
                {
                    // Heights of weighted Views are invalid if we end up remeasuring, so store them separately.
                    weightedMaxHeight = Math.Max(weightedMaxHeight, matchHeightLocally ? marginHeight : childHeight);
                }
                else
                {
                    alternativeMaxHeight = Math.Max(alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight);
                }
            } // foreach

            totalLength = Math.Max(totalLength, totalLength + CellPadding.Width * (childrenCount - 1));
            float widthSize = totalLength;

            widthSize = Math.Max(widthSize, SuggestedMinimumWidth.AsDecimal());
            MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(widthSize + Padding.Start + Padding.End), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);

            widthSize = widthSizeAndState.Size.AsDecimal();

            // 2nd phase:
            // Expand children with weight to take up available space
            // We cycle through weighted children now (children with weight > 0).
            // The children are measured with exact size equal to their share of the available space based on their weights.
            // _totalLength is updated to include weighted children measured sizes.
            float remainingExcess = widthSize - totalLength + usedExcessSpace - (Padding.Start + Padding.End);

            if (remainingExcess != 0 && totalWeight > 0)
            {
                float remainingWeight = totalWeight;
                maxHeight   = 0;
                totalLength = 0;

                foreach (LayoutItem childLayout in IterateLayoutChildren())
                {
                    float desiredChildHeight = childLayout.Owner.HeightSpecification;

                    float   childWeight = childLayout.Owner.Weight;
                    Extents childMargin = childLayout.Margin;

                    if (childWeight > 0)
                    {
                        MeasureWeightedChild(childLayout, remainingExcess, remainingWeight, childWeight,
                                             widthMeasureSpec, heightMeasureSpec, childState,
                                             Orientation.Horizontal);
                    }

                    float length = childLayout.MeasuredWidth.Size.AsDecimal() + childMargin.Start + childMargin.End;
                    totalLength += length;

                    bool  matchHeightLocally = (heightMode != MeasureSpecification.ModeType.Exactly) && (desiredChildHeight == LayoutParamPolicies.MatchParent);
                    float marginHeight       = childMargin.Top + childMargin.Bottom;
                    float childHeight        = childLayout.MeasuredHeight.Size.AsDecimal() + marginHeight;

                    maxHeight            = Math.Max(maxHeight, childHeight);
                    alternativeMaxHeight = Math.Max(alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight);
                    allFillParent        = (allFillParent && desiredChildHeight == LayoutParamPolicies.MatchParent);
                } // for loop
                totalLength = Math.Max(totalLength, totalLength + CellPadding.Width * (childrenCount - 1));
            }
            else
            {
                // No excess space or no weighted children
                alternativeMaxHeight = Math.Max(alternativeMaxHeight, weightedMaxHeight);
            }

            if (!allFillParent && heightMode != MeasureSpecification.ModeType.Exactly)
            {
                maxHeight = alternativeMaxHeight;
            }



            // Padding should be concerned when specification is Wrapcontent.
            maxHeight += (Owner.HeightSpecification == LayoutParamPolicies.WrapContent) ? (Padding.Top + Padding.Bottom) : 0;
            maxHeight  = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue());

            widthSizeAndState.State = childState.widthState;

            SetMeasuredDimensions(widthSizeAndState,
                                  ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childState.heightState));

            if (matchHeight)
            {
                ForceUniformHeight(widthMeasureSpec);
            }
        } // MeasureHorizontal
Exemplo n.º 2
0
 /// <summary>
 /// Performs the layouting positioning
 /// </summary>
 private void PerformLayout(View root, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
 {
     root.Layout?.Layout(left, top, right, bottom);
 }
Exemplo n.º 3
0
 /// <summary>
 /// Layout should assign a size and position to each of its children.<br />
 /// </summary>
 /// <param name="changed">This is a new size or position for this layout.</param>
 /// <param name="left">Left position, relative to parent.</param>
 /// <param name="top"> Top position, relative to parent.</param>
 /// <param name="right">Right position, relative to parent.</param>
 /// <param name="bottom">Bottom position, relative to parent.</param>
 /// <since_tizen> 6 </since_tizen>
 protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
 {
     if (linearOrientation == Orientation.Horizontal)
     {
         LayoutHorizontal(left, top, right, bottom);
     }
     else
     {
         LayoutVertical(left, top, right, bottom);
     }
 }
Exemplo n.º 4
0
        // Starts of the actual measuring and layouting from the given root node.
        // Can be called from multiple starting roots but in series.
        void MeasureAndLayout(View root)
        {
            if (root != null)
            {
                // Get parent MeasureSpecification, this could be the Window or View with an exact size.
                Container  parentNode = root.GetParent();
                Size2D     rootSize;
                Position2D rootPosition = root.Position2D;
                View       parentView   = parentNode as View;
                if (parentView)
                {
                    // Get parent View's Size.  If using Legacy size negotiation then should have been set already.
                    rootSize = new Size2D(parentView.Size2D.Width, parentView.Size2D.Height);
                }
                else
                {
                    // Parent not a View so assume it's a Layer which is the size of the window.
                    rootSize = new Size2D(_window.Size.Width, _window.Size.Height);
                }

                // Determine measure specification for root.
                // The root layout policy could be an exact size, be match parent or wrap children.
                // If wrap children then at most it can be the root parent size.
                // If match parent then should be root parent size.
                // If exact then should be that size limited by the root parent size.

                LayoutLength width  = new LayoutLength(rootSize.Width);
                LayoutLength height = new LayoutLength(rootSize.Height);
                MeasureSpecification.ModeType widthMode  = MeasureSpecification.ModeType.AtMost;
                MeasureSpecification.ModeType heightMode = MeasureSpecification.ModeType.AtMost;

                if (root.WidthSpecification >= 0)
                {
                    // exact size provided so match width exactly
                    width     = new LayoutLength(root.WidthSpecification);
                    widthMode = MeasureSpecification.ModeType.Exactly;
                }
                else if (root.WidthSpecification == LayoutParamPolicies.MatchParent)
                {
                    widthMode = MeasureSpecification.ModeType.Exactly;
                }

                if (root.HeightSpecification >= 0)
                {
                    // exact size provided so match height exactly
                    height     = new LayoutLength(root.HeightSpecification);
                    heightMode = MeasureSpecification.ModeType.Exactly;
                }
                else if (root.HeightSpecification == LayoutParamPolicies.MatchParent)
                {
                    heightMode = MeasureSpecification.ModeType.Exactly;
                }

                MeasureSpecification parentWidthSpecification =
                    new MeasureSpecification(width, widthMode);

                MeasureSpecification parentHeightSpecification =
                    new MeasureSpecification(height, heightMode);

                // Start at root with it's parent's widthSpecification and heightSpecification
                MeasureHierarchy(root, parentWidthSpecification, parentHeightSpecification);

                // Start at root which was just measured.
                PerformLayout(root, new LayoutLength(rootPosition.X),
                              new LayoutLength(rootPosition.Y),
                              new LayoutLength(rootPosition.X) + root.Layout.MeasuredWidth.Size,
                              new LayoutLength(rootPosition.Y) + root.Layout.MeasuredHeight.Size);

                bool readyToPlay = SetupCoreAnimation();

                if (readyToPlay && OverrideCoreAnimation == false)
                {
                    PlayAnimation();
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Assign a size and position to each of its children.<br />
        /// </summary>
        /// <param name="changed">This is a new size or position for this layout.</param>
        /// <param name="left">Left position, relative to parent.</param>
        /// <param name="top"> Top position, relative to parent.</param>
        /// <param name="right">Right position, relative to parent.</param>
        /// <param name="bottom">Bottom position, relative to parent.</param>
        /// <since_tizen> 6 </since_tizen>
        protected override void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
        {

            bool isLayoutRtl = Owner.LayoutDirection == ViewLayoutDirectionType.RTL;
            LayoutLength width = right - left;
            LayoutLength height = bottom - top;

            // Call to FlexLayout implementation to calculate layout values for later retrieval.
            Interop.FlexLayout.FlexLayout_CalculateLayout( swigCPtr, width.AsDecimal(), height.AsDecimal(), isLayoutRtl );

            int count = LayoutChildren.Count;
            for( int childIndex = 0; childIndex < count; childIndex++)
            {
                LayoutItem childLayout = LayoutChildren[childIndex];
                if( childLayout != null )
                {
                    // Get the frame for the child, start, top, end, bottom.
                    Vector4 frame = new Vector4(Interop.FlexLayout.FlexLayout_GetNodeFrame(swigCPtr, childIndex ), true);
                    childLayout.Layout( new LayoutLength(frame.X), new LayoutLength(frame.Y), new LayoutLength(frame.Z), new LayoutLength(frame.W) );
                }
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Called from Layout() when this layout should assign a size and position to each of its children. <br />
 /// Derived classes with children should override this method and call Layout() on each of their children. <br />
 /// </summary>
 /// <param name="changed">This is a new size or position for this layout.</param>
 /// <param name="left">Left position, relative to parent.</param>
 /// <param name="top">Top position, relative to parent.</param>
 /// <param name="right">Right position, relative to parent.</param>
 /// <param name="bottom">Bottom position, relative to parent.</param>
 protected virtual void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
 {
 }
Exemplo n.º 7
0
        } // LayoutHorizontally

        private void LayoutVertical(LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
        {
            LayoutLength childTop  = new LayoutLength(Padding.Top);
            LayoutLength childLeft = new LayoutLength(Padding.Start);

            // Where end of child should go
            LayoutLength width = new LayoutLength(right - left);

            // Space available for child
            LayoutLength childSpace = new LayoutLength(width - Padding.Start - Padding.End);

            int count = LayoutChildren.Count;

            switch (LinearAlignment)
            {
            case Alignment.Bottom:
                // totalLength contains the padding already
                childTop = new LayoutLength(Padding.Top + bottom.AsDecimal() - top.AsDecimal() - totalLength);
                break;

            case Alignment.CenterVertical:     // FALL THROUGH
            case Alignment.Center:
                // totalLength contains the padding already
                childTop = new LayoutLength(Padding.Top + (bottom.AsDecimal() - top.AsDecimal() - totalLength) / 2.0f);
                break;

            case Alignment.Top:      // FALL THROUGH (default)
            default:
                // totalLength contains the padding already
                childTop = new LayoutLength(Padding.Top);
                break;
            }

            for (int i = 0; i < count; i++)
            {
                LayoutItem childLayout = LayoutChildren[i];
                if (childLayout != null)
                {
                    LayoutLength childWidth  = childLayout.MeasuredWidth.Size;
                    LayoutLength childHeight = childLayout.MeasuredHeight.Size;
                    Extents      childMargin = childLayout.Margin;

                    childTop += childMargin.Top;
                    switch (LinearAlignment)
                    {
                    case Alignment.Begin:
                    default:
                    {
                        childLeft = new LayoutLength(Padding.Start + childMargin.Start);
                        break;
                    }

                    case Alignment.End:
                    {
                        childLeft = new LayoutLength(width - Padding.End - childWidth - childMargin.End);
                        break;
                    }

                    case Alignment.CenterHorizontal:
                    case Alignment.Center:     // FALL THROUGH
                    {
                        childLeft = new LayoutLength(Padding.Start + ((childSpace - childWidth).AsDecimal() / 2.0f) + childMargin.Start - childMargin.End);
                        break;
                    }
                    }
                    childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
                    childTop += childHeight + childMargin.Bottom + ((i < count - 1) ? CellPadding.Height : 0);
                }
            }
        } // LayoutVertical
Exemplo n.º 8
0
        } // MeasureVertical

        private void LayoutHorizontal(LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
        {
            bool isLayoutRtl = Owner.LayoutDirection == ViewLayoutDirectionType.RTL;

            LayoutLength childTop  = new LayoutLength(Padding.Top);
            LayoutLength childLeft = new LayoutLength(Padding.Start);

            // Where bottom of child should go
            LayoutLength height = new LayoutLength(bottom - top);

            // Space available for child
            LayoutLength childSpace = new LayoutLength(height - Padding.Top - Padding.Bottom);

            int count = LayoutChildren.Count;

            switch (LinearAlignment)
            {
            case Alignment.End:
                // totalLength contains the padding already
                // In case of RTL map END alignment to the left edge
                if (isLayoutRtl)
                {
                    childLeft = new LayoutLength(Padding.Start);
                }
                else
                {
                    childLeft = new LayoutLength(Padding.Start + right.AsDecimal() - left.AsDecimal() - totalLength);
                }
                break;

            case Alignment.CenterHorizontal:     // FALL THROUGH
            case Alignment.Center:
                // totalLength contains the padding already
                childLeft = new LayoutLength(Padding.Start + (right.AsDecimal() - left.AsDecimal() - totalLength) / 2.0f);
                break;

            case Alignment.Begin:     // FALL THROUGH (default)
            default:
                // totalLength contains the padding already
                // In case of RTL map BEGIN alignment to the right edge
                if (isLayoutRtl)
                {
                    childLeft = new LayoutLength(Padding.Start + right.AsDecimal() - left.AsDecimal() - totalLength);
                }
                else
                {
                    childLeft = new LayoutLength(Padding.Start);
                }
                break;
            }

            int start = 0;
            int dir   = 1;

            // In case of RTL, start drawing from the last child.
            if (isLayoutRtl)
            {
                start = count - 1;
                dir   = -1;
            }

            for (int i = 0; i < count; i++)
            {
                int childIndex = start + dir * i;
                // Get a reference to the childLayout at the given index
                LayoutItem childLayout = LayoutChildren[childIndex];
                if (childLayout != null)
                {
                    LayoutLength childWidth  = childLayout.MeasuredWidth.Size;
                    LayoutLength childHeight = childLayout.MeasuredHeight.Size;
                    Extents      childMargin = childLayout.Margin;

                    switch (LinearAlignment)
                    {
                    case Alignment.Bottom:
                        childTop = new LayoutLength(height - Padding.Bottom - childHeight - childMargin.Bottom);
                        break;

                    case Alignment.CenterVertical:
                    case Alignment.Center:     // FALLTHROUGH
                        childTop = new LayoutLength(Padding.Top + ((childSpace - childHeight).AsDecimal() / 2.0f) + childMargin.Top - childMargin.Bottom);
                        break;

                    case Alignment.Top:     // FALLTHROUGH default
                    default:
                        childTop = new LayoutLength(Padding.Top + childMargin.Top);
                        break;
                    }
                    childLeft += childMargin.Start;
                    childLayout.Layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
                    childLeft += childWidth + childMargin.End + ((i < count - 1) ? CellPadding.Width : 0);
                }
            }
        } // LayoutHorizontally
Exemplo n.º 9
0
        } // MeasureHorizontal

        private void MeasureVertical(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
        {
            var   widthMode           = widthMeasureSpec.Mode;
            var   heightMode          = heightMeasureSpec.Mode;
            bool  isExactly           = (heightMode == MeasureSpecification.ModeType.Exactly);
            bool  matchWidth          = false;
            bool  allFillParent       = true;
            float maxWidth            = 0.0f;
            float alternativeMaxWidth = 0.0f;
            float weightedMaxWidth    = 0.0f;
            float totalWeight         = 0.0f;

            // Reset total length
            totalLength = 0.0f;
            float usedExcessSpace          = 0.0f;
            HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
                                                                     MeasuredSize.StateType.MeasuredSizeOK);


            // measure children, and determine if further resolution is required

            // 1st phase:
            // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs
            // to accumulate total used space in _totalLength.
            // Weighted children are not measured in this phase.
            // Available space for weighted children will be calculated in the phase 2 based on _totalLength value.
            for (int i = 0; i < LayoutChildren.Count; i++)
            {
                LayoutItem childLayout       = LayoutChildren[i];
                int        childDesiredWidth = childLayout.Owner.WidthSpecification;
                float      childWeight       = childLayout.Owner.Weight;
                Extents    childMargin       = childLayout.Margin;
                totalWeight += childWeight;

                bool useExcessSpace = (childLayout.Owner.HeightSpecification == 0) && (childWeight > 0);
                if (isExactly && useExcessSpace)
                {
                    totalLength = Math.Max(totalLength, (totalLength + childMargin.Top + childMargin.Bottom));
                }
                else
                {
                    if (useExcessSpace)
                    {
                        // The heightMode is either Unspecified or AtMost, and
                        // this child is only laid out using excess space. Measure
                        // using WrapContent so that we can find out the view's
                        // optimal height.
                        // We'll restore the original height of 0 after measurement.
                        MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(
                            new MeasureSpecification(
                                new LayoutLength(widthMeasureSpec.Size - (childLayout.Margin.Start + childLayout.Margin.End)),
                                widthMeasureSpec.Mode),
                            new LayoutLength(Padding.Start + Padding.End),
                            new LayoutLength(childDesiredWidth));

                        MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(
                            new MeasureSpecification(
                                new LayoutLength(heightMeasureSpec.Size - (childLayout.Margin.Top + childLayout.Margin.Bottom)),
                                heightMeasureSpec.Mode),
                            new LayoutLength(Padding.Top + Padding.Bottom),
                            new LayoutLength(LayoutParamPolicies.WrapContent));

                        childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
                        usedExcessSpace += childLayout.MeasuredHeight.Size.AsDecimal();
                    }
                    else
                    {
                        MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
                    }

                    LayoutLength childHeight = childLayout.MeasuredHeight.Size;
                    LayoutLength length      = childHeight + childMargin.Top + childMargin.Bottom;


                    if (isExactly)
                    {
                        totalLength += length.AsDecimal();
                    }
                    else
                    {
                        totalLength = Math.Max(totalLength, totalLength + length.AsDecimal() + (i < LayoutChildren.Count - 1 ? CellPadding.Height : 0));
                    }
                }

                bool matchWidthLocally = false;
                if (widthMode != MeasureSpecification.ModeType.Exactly && childDesiredWidth == LayoutParamPolicies.MatchParent)
                {
                    // Will have to re-measure at least this child when we know exact height.
                    matchWidth        = true;
                    matchWidthLocally = true;
                }

                float marginWidth = childLayout.Margin.Start + childLayout.Margin.End;
                float childWidth  = childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth;

                if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                {
                    childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                }
                if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                {
                    childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                }

                maxWidth      = Math.Max(maxWidth, childWidth);
                allFillParent = (allFillParent && childDesiredWidth == LayoutParamPolicies.MatchParent);

                if (childWeight > 0)
                {
                    // Widths of weighted Views are bogus if we end up remeasuring, so keep them separate.
                    weightedMaxWidth = Math.Max(weightedMaxWidth, matchWidthLocally ? marginWidth : childWidth);
                }
                else
                {
                    alternativeMaxWidth = Math.Max(alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth);
                }
            } // foreach


            float heightSize = totalLength;

            heightSize = Math.Max(heightSize, SuggestedMinimumHeight.AsDecimal());
            MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(heightSize + Padding.Top + Padding.Bottom), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);

            heightSize = heightSizeAndState.Size.AsDecimal();

            // 2nd phase:
            // We cycle through weighted children now (children with weight > 0).
            // The children are measured with exact size equal to their share of the available space based on their weights.
            // totalLength is updated to include weighted children measured sizes.
            float remainingExcess = heightSize - totalLength + usedExcessSpace - (Padding.Top + Padding.Bottom);

            if (remainingExcess != 0 && totalWeight > 0.0f)
            {
                float remainingWeight = totalWeight;
                maxWidth    = 0;
                totalLength = 0;

                int numberOfChildren = LayoutChildren.Count;
                for (int i = 0; i < numberOfChildren; ++i)
                {
                    LayoutItem childLayout = LayoutChildren[i];

                    float desiredChildWidth = childLayout.Owner.WidthSpecification;

                    float   childWeight = childLayout.Owner.Weight;
                    Extents childMargin = childLayout.Margin;

                    if (childWeight > 0)
                    {
                        MeasureWeightedChild(childLayout, remainingExcess, remainingWeight, childWeight,
                                             widthMeasureSpec, heightMeasureSpec, childState,
                                             Orientation.Vertical);
                    }

                    float length      = childLayout.MeasuredHeight.Size.AsDecimal() + childMargin.Top + childMargin.Bottom;
                    float cellPadding = i < numberOfChildren - 1 ? CellPadding.Height : 0;

                    if (isExactly)
                    {
                        totalLength += length;
                    }
                    else
                    {
                        float totalLength = this.totalLength;
                        totalLength = Math.Max(totalLength, totalLength + length + cellPadding);
                    }

                    bool  matchWidthLocally = (widthMode != MeasureSpecification.ModeType.Exactly) && (desiredChildWidth == LayoutParamPolicies.MatchParent);
                    float marginWidth       = childMargin.Start + childMargin.End;
                    float childWidth        = childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth;

                    maxWidth            = Math.Max(maxWidth, childWidth);
                    alternativeMaxWidth = Math.Max(alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth);
                    allFillParent       = (allFillParent && desiredChildWidth == LayoutParamPolicies.MatchParent);
                } // for loop
            }
            else
            {
                alternativeMaxWidth = Math.Max(alternativeMaxWidth, weightedMaxWidth);
            }

            if (!allFillParent && widthMode != MeasureSpecification.ModeType.Exactly)
            {
                maxWidth = alternativeMaxWidth;
            }

            maxWidth += (Owner.WidthSpecification == LayoutParamPolicies.WrapContent) ? (Padding.Start + Padding.End) : 0;
            maxWidth  = Math.Max(maxWidth, SuggestedMinimumWidth.AsRoundedValue());

            heightSizeAndState.State = childState.heightState;

            SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth + Padding.Top + Padding.Bottom), widthMeasureSpec, childState.widthState),
                                  heightSizeAndState);

            if (matchWidth)
            {
                ForceUniformWidth(heightMeasureSpec);
            }
        } // MeasureVertical
Exemplo n.º 10
0
        /// <inheritdoc/>
        /// <since_tizen> 9 </since_tizen>
        protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
        {
            for (int i = 0; i < LayoutChildren.Count; i++)
            {
                LayoutItem childLayout = LayoutChildren[i];
                if (childLayout != null)
                {
                    Geometry horizontalGeometry = GetHorizontalLayout(childLayout.Owner);
                    Geometry verticalGeometry   = GetVerticalLayout(childLayout.Owner);

                    // MeasureChildWithMargins() is called to assign child's MeasuredWidth/Height to calculate grand children's sizes correctly.
                    // Grand children's positions are calculated correctly only if their sizes are calculated correctly.
                    // MeasureChildWithMargins() should be called before childLayout.Layout() to use childLayout's MeasuredWidth/Height
                    // when the grand children's positions are calculated.
                    //
                    // FIXME: It would be better if MeasureChildWithMargins() are called in OnMeasure() to separate Measure and Layout calculations.
                    //        For now, not to call duplicate GetHorizontalLayout() and GetVerticalLayout() in both OnMeasure() and OnLayout(),
                    //        MeasureChildWithMargins() is called here.
                    MeasureChildWithMargins(childLayout,
                                            new MeasureSpecification(new LayoutLength(horizontalGeometry.Size), MeasureSpecification.ModeType.Exactly), new LayoutLength(0),
                                            new MeasureSpecification(new LayoutLength(verticalGeometry.Size), MeasureSpecification.ModeType.Exactly), new LayoutLength(0));

                    LayoutLength childLeft   = new LayoutLength(horizontalGeometry.Position + Padding.Start + childLayout.Margin.Start);
                    LayoutLength childRight  = new LayoutLength(horizontalGeometry.Position + horizontalGeometry.Size + Padding.Start - childLayout.Margin.End);
                    LayoutLength childTop    = new LayoutLength(verticalGeometry.Position + Padding.Top + childLayout.Margin.Top);
                    LayoutLength childBottom = new LayoutLength(verticalGeometry.Position + verticalGeometry.Size + Padding.Top - childLayout.Margin.Bottom);
                    childLayout.Layout(childLeft, childTop, childRight, childBottom);
                }
            }
            HorizontalRelativeCache.Clear();
            VerticalRelativeCache.Clear();
        }