END_TEST;
}
+
+int UtcDaliLayouting_FlexLayout_NestedFlexboxWithSpec(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliLayouting_FlexLayout_NestedFlexboxWithSpec Test nested flex box with wrap content/match parent");
+
+ Stage stage = Stage::GetCurrent();
+
+ auto flexbox1 = Control::New();
+ auto flexLayout1 = FlexLayout::New();
+ DevelControl::SetLayout( flexbox1, flexLayout1 );
+ flexbox1.SetName( "Flexbox1");
+ flexbox1.SetParentOrigin( ParentOrigin::CENTER );
+ flexbox1.SetAnchorPoint( AnchorPoint::CENTER );
+
+ auto flexbox2 = Control::New();
+ auto flexLayout2 = FlexLayout::New();
+ DevelControl::SetLayout( flexbox2, flexLayout2 );
+ flexbox2.SetParentOrigin( ParentOrigin::CENTER );
+ flexbox2.SetAnchorPoint( AnchorPoint::CENTER );
+ flexbox2.SetName( "Flexbox2");
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+ std::vector< Control > controls;
+ controls.push_back( CreateLeafControl( 100, 100 ) );
+ flexbox2.Add( controls[0] );
+ flexbox1.Add( flexbox2 );
+ stage.Add( flexbox1 );
+
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Test flexbox2 is sized to wrap its content
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Test flexbox2 width is sized to match parent
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Test flexbox2 height is sized to match parent
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ flexbox2.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+ // Ensure layouting happens
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ // Test flexbox2 is sized to match its parent
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+ DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+ END_TEST;
+}
YGMeasureMode widthMode,
float innerHeight,
YGMeasureMode heightMode ) {
- // TODO: this function should try to get use of LayoutGroup::GetChildMeasureSpec
- // or LayoutGroup::MeasureChild somehow since it is fixed now
LayoutItem* childLayout = static_cast<LayoutItem*>(node->getContext());
auto childOwner = childLayout->GetOwner();
auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
-
- MeasureSpec::Mode measureWidthMode = MeasureSpec::Mode::AT_MOST;
- MeasureSpec::Mode measureHeightMode = MeasureSpec::Mode::AT_MOST;
- if( desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
- {
- if( innerWidth != YGUndefined)
- {
- desiredWidth = innerWidth;
- }
- measureWidthMode = MeasureSpec::Mode::EXACTLY;
- }
-
- if( desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT )
- {
- if( innerHeight != YGUndefined)
- {
- desiredHeight = innerHeight;
- }
- measureHeightMode = MeasureSpec::Mode::EXACTLY;
- }
-
- if( desiredWidth == Toolkit::ChildLayoutData::WRAP_CONTENT )
+ auto parentWidthMeasureSpec = MeasureSpec( 0 );
+ if ( innerWidth != YGUndefined )
{
- measureWidthMode = MeasureSpec::Mode::UNSPECIFIED;
+ parentWidthMeasureSpec = MeasureSpec( innerWidth, static_cast<MeasureSpec::Mode>(widthMode) );
}
-
- if( desiredHeight == Toolkit::ChildLayoutData::WRAP_CONTENT )
+ auto parentHeightMeasureSpec = MeasureSpec( 0 );
+ if ( innerHeight != YGUndefined )
{
- measureHeightMode = MeasureSpec::Mode::UNSPECIFIED;
+ parentHeightMeasureSpec = MeasureSpec( innerHeight, static_cast<MeasureSpec::Mode>(heightMode) );
}
+ auto childWidthMeasureSpec = LayoutGroup::GetChildMeasureSpec( parentWidthMeasureSpec, 0, desiredWidth);
+ auto childHeightMeasureSpec = LayoutGroup::GetChildMeasureSpec( parentHeightMeasureSpec, 0, desiredHeight);
- MeasureSpec widthMeasureSpec = MeasureSpec( desiredWidth, measureWidthMode );
- MeasureSpec heightMeasureSpec = MeasureSpec( desiredHeight, measureHeightMode );
- if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
- measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
+ // Force to fill parent if a child wants to match parent even if GetChildMeasureSpec sets otherwise
+ if( desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT && innerWidth != YGUndefined )
{
- // A measure just to get the size if the wrapped content
- childLayout->Measure( widthMeasureSpec, heightMeasureSpec );
- desiredWidth = childLayout->GetMeasuredWidth();
- desiredHeight = childLayout->GetMeasuredHeight();
- // Remove padding here since the second measure will add it back
- Extents padding = childLayout->GetPadding();
- desiredWidth = desiredWidth - padding.end - padding.start;
- desiredHeight = desiredHeight - padding.bottom - padding.top;
+ childWidthMeasureSpec = MeasureSpec( innerWidth, MeasureSpec::Mode::EXACTLY );
}
-
- // Safety check to avoid going out of boundary
- if( (innerWidth != YGUndefined && innerWidth != 0) && innerWidth < desiredWidth )
+ if( desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT && innerHeight != YGUndefined )
{
- desiredWidth = innerWidth;
+ childHeightMeasureSpec = MeasureSpec( innerHeight, MeasureSpec::Mode::EXACTLY );
}
- if( (innerHeight != YGUndefined && innerHeight != 0) && innerHeight < desiredHeight )
- {
- desiredHeight = innerHeight;
- }
-
- // Measure for Yoga
- MeasureSpec::Mode ygWidthMode = static_cast<MeasureSpec::Mode>(widthMode);
- if( measureWidthMode == MeasureSpec::Mode::EXACTLY )
- {
- ygWidthMode = MeasureSpec::Mode::EXACTLY;
- }
-
- MeasureSpec::Mode ygHeightMode = static_cast<MeasureSpec::Mode>(heightMode);
- if( measureHeightMode == MeasureSpec::Mode::EXACTLY )
- {
- ygHeightMode = MeasureSpec::Mode::EXACTLY;
- }
-
- MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, ygWidthMode );
- MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, ygHeightMode );
#if defined(DEBUG_ENABLED)
auto actor = Actor::DownCast(childOwner);
std::ostringstream oss;
{
oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " ";
}
- oss << "innerWidth:" << ((innerWidth == YGUndefined) ? "YGUndefined " : "") << innerWidth <<
- " innerHeight:" << ((innerHeight == YGUndefined) ? "YGUndefined " : "") << innerHeight <<
+ oss << "innerWidth:" << ( ( innerWidth == YGUndefined ) ? "YGUndefined " : "" ) << innerWidth <<
+ " innerHeight:" << ( ( innerHeight == YGUndefined ) ? "YGUndefined " : "" ) << innerHeight <<
" desiredWidth:" << desiredWidth << " desiredHeight:" << desiredHeight <<
- " widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec <<
- " ygWidthMeasureSpec:" << ygWidthMeasureSpec << " ygHeightMeasureSpec:" << ygHeightMeasureSpec << std::endl;
+ " childWidthMeasureSpec:" << childWidthMeasureSpec << " childHeightMeasureSpec:" << childHeightMeasureSpec << std::endl;
DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
#endif
- if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
- measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
- {
- if( ygWidthMeasureSpec == widthMeasureSpec && ygHeightMeasureSpec == heightMeasureSpec )
- {
- return YGSize{
- .width = childLayout->GetMeasuredWidth(),
- .height = childLayout->GetMeasuredHeight(),
- };
- }
- }
+ childLayout->Measure( childWidthMeasureSpec, childHeightMeasureSpec );
+
+ // Remove padding here since Yoga doesn't consider it as a part of the node size
+ Extents padding = childLayout->GetPadding();
+ auto measuredWidth = childLayout->GetMeasuredWidth() - padding.end - padding.start;
+ auto measuredHeight = childLayout->GetMeasuredHeight() - padding.bottom - padding.top;
- childLayout->Measure( ygWidthMeasureSpec, ygHeightMeasureSpec );
return YGSize{
- .width = childLayout->GetMeasuredWidth(),
- .height = childLayout->GetMeasuredHeight(),
+ .width = measuredWidth,
+ .height = measuredHeight,
};
}