Merge "DALi Version 1.3.30" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 29 Jun 2018 13:17:18 +0000 (13:17 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Fri, 29 Jun 2018 13:17:19 +0000 (13:17 +0000)
automated-tests/src/dali-toolkit/utc-Dali-FlexLayout.cpp
dali-toolkit/internal/layouting/flex-layout-impl.cpp

index 8317361..b839043 100644 (file)
@@ -716,3 +716,93 @@ int UtcDaliLayouting_FlexLayout08(void)
 
   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;
+}
index 648a7f6..bf5d084 100644 (file)
@@ -286,84 +286,33 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node,
                               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;
@@ -372,30 +321,23 @@ YGSize FlexLayout::OnChildMeasure( YGNodeRef node,
   {
     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,
   };
 }