Example #1
0
            protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
            {
                float maxWidth  = SuggestedMinimumWidth.AsDecimal();
                float maxHeight = SuggestedMinimumHeight.AsDecimal();

                MeasuredSize.StateType childWidthState  = MeasuredSize.StateType.MeasuredSizeOK;
                MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;

                var appBar  = (Owner as ContentPage)?.AppBar;
                var content = (Owner as ContentPage)?.Content;

                foreach (var childLayout in LayoutChildren)
                {
                    if (!childLayout.SetPositionByLayout)
                    {
                        continue;
                    }

                    if ((content != null) && (content == childLayout.Owner) && (content.HeightSpecification == LayoutParamPolicies.MatchParent))
                    {
                        var contentSizeH = heightMeasureSpec.Size.AsDecimal() - Padding.Top - Padding.Bottom - content.Margin.Top - content.Margin.Bottom - (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0);
                        MeasureSpecification contentHeightSpec = new MeasureSpecification(new LayoutLength(contentSizeH), MeasureSpecification.ModeType.Exactly);
                        MeasureChildWithoutPadding(childLayout, widthMeasureSpec, contentHeightSpec);
                    }
                    else
                    {
                        MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
                    }

                    float childRight  = childLayout.MeasuredWidth.Size.AsDecimal() + childLayout.Owner.PositionX;
                    float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childLayout.Owner.PositionY;

                    if (maxWidth < childRight)
                    {
                        maxWidth = childRight;
                    }

                    if (maxHeight < childBottom)
                    {
                        maxHeight = childBottom;
                    }

                    if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                    {
                        childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                    }
                    if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                    {
                        childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                    }
                }

                SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState),
                                      ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState));
            }
Example #2
0
        /// <summary>
        /// Measure the layout and its content to determine the measured width and the measured height.<br />
        /// </summary>
        /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
        /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
        /// <since_tizen> 6 </since_tizen>
        protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
        {
            // Ensure layout respects it's given minimum size
            float maxWidth  = SuggestedMinimumWidth.AsDecimal();
            float maxHeight = SuggestedMinimumHeight.AsDecimal();

            MeasuredSize.StateType childWidthState  = MeasuredSize.StateType.MeasuredSizeOK;
            MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;

            for (int i = 0; i < LayoutChildren.Count; i++)
            {
                LayoutItem childLayout = LayoutChildren[i];
                if (childLayout != null)
                {
                    // Get size of child with no padding, no margin. we won't support margin, padding for AbsolutLayout.
                    MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);

                    if (childLayout.Owner.ExcludeLayouting)
                    {
                        continue;
                    }

                    // Determine the width and height needed by the children using their given position and size.
                    // Children could overlap so find the right most child.
                    Position2D childPosition = childLayout.Owner.Position2D;
                    float      childRight    = childLayout.MeasuredWidth.Size.AsDecimal() + childPosition.X;
                    float      childBottom   = childLayout.MeasuredHeight.Size.AsDecimal() + childPosition.Y;

                    if (maxWidth < childRight)
                    {
                        maxWidth = childRight;
                    }

                    if (maxHeight < childBottom)
                    {
                        maxHeight = childBottom;
                    }

                    if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                    {
                        childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                    }
                    if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                    {
                        childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                    }
                }
            }

            SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState),
                                  ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState));
        }
Example #3
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 defiend!!!
                        // 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
Example #4
0
        private void MeasureHorizontal(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
        {
            var   widthMode       = widthMeasureSpec.Mode;
            var   heightMode      = heightMeasureSpec.Mode;
            bool  isWidthExactly  = (widthMode == MeasureSpecification.ModeType.Exactly);
            bool  isHeightExactly = (heightMode == MeasureSpecification.ModeType.Exactly);
            float maxHeight       = 0.0f;
            float totalWeight     = 0.0f;
            int   childrenCount   = IterateLayoutChildren().Count();

            // Child layout, which wants to match its width to its parent's remaining width, is either following 1 or 2.
            // 1. Child layout whose Owner.WidthSpecification is LayoutParamPolicies.MatchParent.
            // 2. Child layout whose Owner.WidthSpecification is 0 and Owner.Weight is greater than 0.
            // The number of child layout which wants to match its width to its parent's remaining width.
            int childrenMatchParentCount = 0;

            // Reset measure variable
            totalLength = 0.0f;

            HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
                                                                     MeasuredSize.StateType.MeasuredSizeOK);

            // 1ST PHASE:
            //
            // We measure all children whose width specification policy is WrapContent without weight.
            // After 1st phase, remaining width of parent is accumulated to calculate width of children
            // whose width specification policy is MatchParent.
            foreach (var childLayout in LayoutChildren)
            {
                if (!childLayout.SetPositionByLayout)
                {
                    continue;
                }
                int     childDesiredWidth  = childLayout.Owner.WidthSpecification;
                int     childDesiredHeight = childLayout.Owner.HeightSpecification;
                float   childWeight        = childLayout.Owner.Weight;
                Extents childMargin        = childLayout.Margin;
                float   childMarginWidth   = childMargin.Start + childMargin.End;
                float   childMarginHeight  = childMargin.Top + childMargin.Bottom;
                bool    useRemainingWidth  = (childDesiredWidth == 0) && (childWeight > 0);

                if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                {
                    totalWeight += childWeight;
                    childrenMatchParentCount++;
                }

                // MatchParent child layout's margin is not added to totalLength.
                // Consequently, MatchParent child layout's margin is added to remaining size,
                // so the margin is not shared with other MatchParent child layouts.
                // e.g.
                // LinearLayout has size 100.
                // Child layout1 is MatchParent and its margin is 20. (This margin is not ad
                // Child layout2 is MatchParent and its margin is 0.
                // Then, child layout1's size is 30 and child layout2's size is 50.
                if ((childDesiredWidth == LayoutParamPolicies.WrapContent) || ((childDesiredWidth >= 0) && (!useRemainingWidth)))
                {
                    MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));

                    float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal();

                    if (childMeasuredWidth < 0)
                    {
                        totalLength = Math.Max(totalLength, totalLength + childMarginWidth);
                    }
                    else
                    {
                        totalLength = Math.Max(totalLength, totalLength + childMeasuredWidth + childMarginWidth);
                    }
                }

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

                float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
                if (childMeasuredHeight < 0)
                {
                    maxHeight = Math.Max(maxHeight, childMarginHeight);
                }
                else
                {
                    maxHeight = Math.Max(maxHeight, childMeasuredHeight + childMarginHeight);
                }
            } // 1ST PHASE foreach

            totalLength = Math.Max(totalLength, totalLength + CellPadding.Width * (childrenCount - 1) + Padding.Start + Padding.End);
            float        widthSize         = Math.Max(totalLength, SuggestedMinimumWidth.AsDecimal());
            MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(widthSize), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);

            widthSize = widthSizeAndState.Size.AsDecimal();

            float remainingWidth    = widthSize - totalLength;
            float totalWeightLength = 0.0f;

            // Up to now, only WrapContent children's sizes are added to the totalLength.
            // Since the totalLength is used in OnLayout as the sum of all children's sizes,
            // the layout size is assigned to the totalLength if MatchParent child exists.
            if (childrenMatchParentCount > 0)
            {
                totalLength = widthSize;
            }

            // 2ND PHASE:
            //
            // We measure all children whose width specification policy is MatchParent without weight.
            // After 2nd phase, all children's widths are calculated without considering weight.
            // And the widths of all weighted children are accumulated to calculate weighted width.
            foreach (var childLayout in LayoutChildren)
            {
                if (!childLayout.SetPositionByLayout)
                {
                    continue;
                }
                int     childDesiredWidth  = childLayout.Owner.WidthSpecification;
                int     childDesiredHeight = childLayout.Owner.HeightSpecification;
                float   childWeight        = childLayout.Owner.Weight;
                Extents childMargin        = childLayout.Margin;
                float   childMarginHeight  = childMargin.Top + childMargin.Bottom;
                bool    useRemainingWidth  = (childDesiredWidth == 0) && (childWeight > 0);
                bool    needToMeasure      = false;

                if ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                {
                    if (isHeightExactly)
                    {
                        needToMeasure = true;
                    }
                    // RelativeLayout's MatchParent children should not fill to the RelativeLayout.
                    // Because the children's sizes and positions are calculated by RelativeLayout's APIs.
                    // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost.
                    //
                    // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent.
                    else if (Owner.HeightSpecification == LayoutParamPolicies.WrapContent)
                    {
                        if (childDesiredHeight == LayoutParamPolicies.MatchParent)
                        {
                            Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is MatchParent!");
                        }
                        else
                        {
                            Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is 0 with positive weight!");
                        }
                    }
                }

                if (remainingWidth > 0)
                {
                    if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                    {
                        if (isWidthExactly)
                        {
                            // In MeasureChildWithMargins(), it is assumed that widthMeasureSpec includes Padding.Start and Padding.End.
                            // Therefore, Padding.Start and Padding.End are added to widthMeasureSpec.Size before it is passed to MeasureChildWithMargins().
                            widthMeasureSpec.SetSize(new LayoutLength((int)(remainingWidth / childrenMatchParentCount) + Padding.Start + Padding.End));
                            needToMeasure = true;
                        }
                        // RelativeLayout's MatchParent children should not fill to the RelativeLayout.
                        // Because the children's sizes and positions are calculated by RelativeLayout's APIs.
                        // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost.
                        //
                        // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent.
                        else if (Owner.WidthSpecification == LayoutParamPolicies.WrapContent)
                        {
                            if (childDesiredWidth == LayoutParamPolicies.MatchParent)
                            {
                                Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is MatchParent!");
                            }
                            else
                            {
                                Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is 0 with positive weight!");
                            }
                        }
                    }
                }

                if (needToMeasure == true)
                {
                    MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));

                    float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
                    if (childMeasuredHeight < 0)
                    {
                        maxHeight = Math.Max(maxHeight, childMarginHeight);
                    }
                    else
                    {
                        maxHeight = Math.Max(maxHeight, childMeasuredHeight + childMarginHeight);
                    }
                }

                if ((childWeight > 0) && ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (childDesiredWidth == 0)))
                {
                    float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal();

                    if (childMeasuredWidth < 0)
                    {
                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMargin.Start + childMargin.End);
                    }
                    else
                    {
                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMeasuredWidth + childMargin.Start + childMargin.End);
                    }
                }
            } // 2ND PHASE foreach

            // 3RD PHASE:
            //
            // We measure all weighted children whose owner has weight greater than 0.
            // After 3rd phase, all weighted children has width which is proportional to their weights
            // in remaining width of parent.
            if (totalWeight > 0.0f)
            {
                foreach (LayoutItem childLayout in LayoutChildren)
                {
                    if (!childLayout.SetPositionByLayout)
                    {
                        continue;
                    }
                    int   childDesiredWidth = childLayout.Owner.WidthSpecification;
                    float childWeight       = childLayout.Owner.Weight;

                    if ((childWeight > 0) && ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (childDesiredWidth == 0)))
                    {
                        if (isWidthExactly)
                        {
                            MeasureWeightedChild(childLayout, totalWeightLength, totalWeight, childWeight,
                                                 widthMeasureSpec, heightMeasureSpec, childState,
                                                 Orientation.Horizontal);
                        }
                        // RelativeLayout's MatchParent children should not fill to the RelativeLayout.
                        // Because the children's sizes and positions are calculated by RelativeLayout's APIs.
                        // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost.
                        //
                        // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent.
                        else if (Owner.WidthSpecification == LayoutParamPolicies.WrapContent)
                        {
                            if (childDesiredWidth == LayoutParamPolicies.MatchParent)
                            {
                                Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is MatchParent!");
                            }
                            else
                            {
                                Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is 0 with positive weight!");
                            }
                        }
                    }
                } // 3RD PHASE foreach
            }

            maxHeight = Math.Max(maxHeight, maxHeight + (Padding.Top + Padding.Bottom));
            maxHeight = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue());

            widthSizeAndState.State = childState.widthState;

            SetMeasuredDimensions(widthSizeAndState,
                                  ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childState.heightState));
        } // MeasureHorizontal
Example #5
0
            protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
            {
                Extents padding     = Padding;
                float   totalHeight = padding.Top + padding.Bottom;
                float   totalWidth  = padding.Start + padding.End;

                MeasuredSize.StateType childWidthState  = MeasuredSize.StateType.MeasuredSizeOK;
                MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;

                Direction      scrollingDirection = Direction.Vertical;
                ScrollableBase scrollableBase     = this.Owner as ScrollableBase;

                if (scrollableBase)
                {
                    scrollingDirection = scrollableBase.ScrollingDirection;
                }

                // measure child, should be a single scrolling child
                foreach (LayoutItem childLayout in LayoutChildren)
                {
                    if (childLayout != null)
                    {
                        // Get size of child
                        // Use an Unspecified MeasureSpecification mode so scrolling child is not restricted to it's parents size in Height (for vertical scrolling)
                        // or Width for horizontal scrolling
                        MeasureSpecification unrestrictedMeasureSpec = new MeasureSpecification(heightMeasureSpec.Size, MeasureSpecification.ModeType.Unspecified);

                        if (scrollingDirection == Direction.Vertical)
                        {
                            MeasureChild(childLayout, widthMeasureSpec, unrestrictedMeasureSpec);    // Height unrestricted by parent
                        }
                        else
                        {
                            MeasureChild(childLayout, unrestrictedMeasureSpec, heightMeasureSpec);    // Width unrestricted by parent
                        }

                        float childWidth  = childLayout.MeasuredWidth.Size.AsDecimal();
                        float childHeight = childLayout.MeasuredHeight.Size.AsDecimal();

                        // Determine the width and height needed by the children using their given position and size.
                        // Children could overlap so find the left most and right most child.
                        Position2D childPosition = childLayout.Owner.Position2D;
                        float      childLeft     = childPosition.X;
                        float      childTop      = childPosition.Y;

                        // Store current width and height needed to contain all children.
                        Extents childMargin = childLayout.Margin;
                        totalWidth  = childWidth + childMargin.Start + childMargin.End;
                        totalHeight = childHeight + childMargin.Top + childMargin.Bottom;

                        if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                        {
                            childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                        }
                        if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall)
                        {
                            childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                        }
                    }
                }


                MeasuredSize widthSizeAndState  = ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
                MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);

                totalWidth  = widthSizeAndState.Size.AsDecimal();
                totalHeight = heightSizeAndState.Size.AsDecimal();

                // Ensure layout respects it's given minimum size
                totalWidth  = Math.Max(totalWidth, SuggestedMinimumWidth.AsDecimal());
                totalHeight = Math.Max(totalHeight, SuggestedMinimumHeight.AsDecimal());

                widthSizeAndState.State  = childWidthState;
                heightSizeAndState.State = childHeightState;

                SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childWidthState),
                                      ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childHeightState));
            }
Example #6
0
        protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
        {
            float totalHeight = 0.0f;
            float totalWidth  = 0.0f;

            HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK,
                                                                     MeasuredSize.StateType.MeasuredSizeOK);

            float minPositionX = 0.0f;
            float minPositionY = 0.0f;
            float maxPositionX = 0.0f;
            float maxPositionY = 0.0f;

            // measure children
            foreach (LayoutItem childLayout in _children)
            {
                if (childLayout != null)
                {
                    // Get size of child
                    MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
                    float childWidth  = childLayout.MeasuredWidth.Size.AsDecimal();
                    float childHeight = childLayout.MeasuredHeight.Size.AsDecimal();

                    // Determine the width and height needed by the children using their given position and size.
                    // Children could overlap so find the left most and right most child.
                    Position2D childPosition = childLayout.Owner.Position2D;
                    float      childLeft     = childPosition.X;
                    float      childTop      = childPosition.Y;

                    minPositionX = Math.Min(minPositionX, childLeft);
                    maxPositionX = Math.Max(maxPositionX, childLeft + childWidth);
                    // Children could overlap so find the highest and lowest child.
                    minPositionY = Math.Min(minPositionY, childTop);
                    maxPositionY = Math.Max(maxPositionY, childTop + childHeight);

                    // Store current width and height needed to contain all children.
                    totalWidth  = maxPositionX - minPositionX;
                    totalHeight = maxPositionY - minPositionY;

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


            MeasuredSize widthSizeAndState  = ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
            MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);

            totalWidth  = widthSizeAndState.Size.AsDecimal();
            totalHeight = heightSizeAndState.Size.AsDecimal();

            // Ensure layout respects it's given minimum size
            totalWidth  = Math.Max(totalWidth, SuggestedMinimumWidth.AsDecimal());
            totalHeight = Math.Max(totalHeight, SuggestedMinimumHeight.AsDecimal());

            widthSizeAndState.State  = childState.widthState;
            heightSizeAndState.State = childState.heightState;

            SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childState.widthState),
                                  ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childState.heightState));
        }
Example #7
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;

            // Reset total length
            _totalLength = 0.0f;
            LayoutLength usedExcessSpace = new LayoutLength(0);

            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 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.

            foreach (LayoutItem childLayout in _children)
            {
                LayoutLength childDesiredWidth  = new LayoutLength(childLayout.Owner.WidthSpecification);
                LayoutLength childDesiredHeight = new LayoutLength(childLayout.Owner.HeightSpecification);
                float        childWeight        = childLayout.Owner.Weight;
                Extents      childMargin        = childLayout.Margin;
                totalWeight += childWeight;

                bool useExcessSpace = (childDesiredWidth.AsRoundedValue() == 0) && (childWeight > 0);
                if (isExactly && useExcessSpace)
                {
                    _totalLength += childMargin.Start + childMargin.End;
                }
                else
                {
                    if (useExcessSpace)
                    {
                        // The widthMode is either UNSPECIFIED or AT_MOST, and
                        // this child is only laid out using excess space. Measure
                        // using WRAP_CONTENT so that we can find out the view's
                        // optimal width.
                        MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(widthMeasureSpec, new LayoutLength(childLayout.Padding.Start + childLayout.Padding.End),
                                                                                                  new LayoutLength(LayoutParamPolicies.WrapContent));
                        MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(heightMeasureSpec, new LayoutLength(childLayout.Padding.Top + childLayout.Padding.Bottom),
                                                                                                   childDesiredHeight);
                        childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
                        usedExcessSpace += childLayout.MeasuredWidth.Size;
                    }
                    else
                    {
                        MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
                    }
                    LayoutLength childWidth = childLayout.MeasuredWidth.Size;

                    LayoutLength length = childWidth + childMargin.Start + childMargin.End;
                    if (isExactly)
                    {
                        _totalLength += length.AsDecimal();
                    }
                    else
                    {
                        _totalLength = Math.Max(_totalLength, _totalLength + length.AsDecimal() + CellPadding.Width);
                    }
                }

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

                LayoutLength marginHeight = new LayoutLength(childMargin.Top + childMargin.Bottom);
                LayoutLength childHeight  = childLayout.MeasuredHeight.Size + marginHeight;

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

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

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

            Extents padding = Padding;

            _totalLength += padding.Start + padding.End;
            LayoutLength widthSize = new LayoutLength(_totalLength);

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

            widthSize = widthSizeAndState.Size;

            if (!allFillParent && heightMode != MeasureSpecification.ModeType.Exactly)
            {
                maxHeight = alternativeMaxHeight;
            }
            maxHeight += padding.Top + padding.Bottom;
            maxHeight  = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue());

            widthSizeAndState.State = childState.widthState;

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

            if (matchHeight)
            {
                ForceUniformHeight(_children.Count, widthMeasureSpec);
            }
        } // MeasureHorizontally