+ // Either expand children with weight to take up available space or
+ // shrink them if they extend beyond our current bounds. If we skipped
+ // measurement on any children, we need to measure them now.
+
+ // 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.
+ // mTotalLength is updated to include weighted children measured sizes.
+ LayoutLength remainingExcess = heightSize - mTotalLength + usedExcessSpace;
+ if( remainingExcess != 0 && totalWeight > 0.0f )
+ {
+ float remainingWeightSum = totalWeight;
+
+ mTotalLength = 0;
+
+ for( unsigned int i = 0; i < GetChildCount(); ++i )
+ {
+ auto childLayout = GetChildAt( i );
+ auto childOwner = childLayout->GetOwner();
+ LayoutLength desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+ LayoutLength desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+ float childWeight = childOwner.GetProperty<float>( Toolkit::LinearLayout::ChildProperty::WEIGHT );
+ Extents childMargin = childLayout->GetMargin();
+
+ LayoutLength childHeight = 0;
+ if( childWeight > 0 )
+ {
+ LayoutLength share = ( childWeight * remainingExcess ) / remainingWeightSum;
+ remainingExcess -= share;
+ remainingWeightSum -= childWeight;
+
+ // Always lay out weighted elements with intrinsic size regardless of the parent spec
+ // for consistency between specs.
+ if( desiredHeight == 0 )
+ {
+ // This child needs to be laid out from scratch using
+ // only its share of excess space.
+ childHeight = share;
+ }
+ else
+ {
+ // This child had some intrinsic width to which we
+ // need to add its share of excess space.
+ childHeight = childLayout->GetMeasuredHeight() + share;
+ }
+
+ const MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( widthMeasureSpec, padding.start + padding.end, desiredWidth );
+ const MeasureSpec childHeightMeasureSpec = MeasureSpec( childHeight, MeasureSpec::Mode::EXACTLY );
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+
+ // Child may now not fit in vertical dimension.
+ if( childLayout->GetMeasuredHeightAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL )
+ {
+ childState.heightState = MeasuredSize::State::MEASURED_SIZE_TOO_SMALL;
+ }
+ }
+
+ bool matchWidthLocally = false;
+ if( widthMode != MeasureSpec::Mode::EXACTLY && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
+ {
+ // Will have to re-measure at least this child when we know exact height.
+ matchWidth = true;
+ matchWidthLocally = true;
+ }
+
+ LayoutLength marginWidth = childMargin.start + childMargin.end;
+ LayoutLength childWidth = childLayout->GetMeasuredWidth() + marginWidth;
+ maxWidth = std::max( maxWidth, childWidth );
+ allFillParent = allFillParent && desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT;
+ alternativeMaxWidth = std::max( alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth );
+
+ childHeight = childLayout->GetMeasuredHeight();
+ LayoutLength length = childHeight + childMargin.top + childMargin.bottom;
+ LayoutLength cellPadding = i < GetChildCount() - 1 ? mCellPadding.height : 0;
+ LayoutLength totalLength = mTotalLength;
+ mTotalLength = std::max( totalLength, totalLength + length + cellPadding );
+ }
+
+ // Add in our padding
+ mTotalLength += padding.top + padding.bottom;
+ }
+ else
+ {
+ alternativeMaxWidth = std::max( alternativeMaxWidth, weightedMaxWidth );
+ }
+