Merge "[Tizen] Store LayoutItem target size when set explictly" into tizen_5.0 accepted/tizen/5.0/unified/20181214.110734 submit/tizen_5.0/20181214.042026
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Fri, 14 Dec 2018 02:50:15 +0000 (02:50 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Fri, 14 Dec 2018 02:50:15 +0000 (02:50 +0000)
automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp
dali-toolkit/devel-api/layouting/layout-group-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.h
dali-toolkit/internal/layouting/layout-item-data-impl.cpp
dali-toolkit/internal/layouting/layout-item-data-impl.h
dali-toolkit/public-api/controls/control-impl.cpp

index 23cc93a..0ee5a23 100644 (file)
@@ -3341,6 +3341,117 @@ int UtcDaliLayouting_SetLayout(void)
   END_TEST;
 }
 
+int UtcDaliLayouting_SetSizeExplictFollowedByWrapContent(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_SetSizeExplictFollowedByWrapContent");
+
+  Stage stage = Stage::GetCurrent();
+
+  AbsoluteLayout absoluteLayout = AbsoluteLayout::New();
+  Control container = Control::New();
+  container.SetName( "Container" );
+  DevelControl::SetLayout( container, absoluteLayout );
+  container.SetAnchorPoint( Dali::AnchorPoint::CENTER );
+  container.SetParentOrigin( Dali::ParentOrigin::CENTER );
+
+  TextLabel textLabel = CreateTextLabel( "W" );
+  tet_infoline("SetSize explicitly then set WRAP_CONTENT");
+  textLabel.SetSize( 300.0f, 200.0f );
+  textLabel.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  textLabel.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  textLabel.SetName( "text-label" );
+  tet_infoline("Adding child to container");
+  container.Add( textLabel );
+
+  tet_infoline("Adding container stage");
+  stage.Add( container );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Not re-laid out
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 54.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  textLabel.SetProperty( TextLabel::Property::TEXT, "WWW" );
+
+  application.SendNotification();
+  application.Render();
+
+  // Add container to stage here
+  // Should call RequestLayout() to measure and layout
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Stage Size
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 162.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_SetSizeExplictFollowedByResizePolicyNaturalSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_SetSizeExplictFollowedByResizePolicyNaturalSize");
+
+  Stage stage = Stage::GetCurrent();
+
+  AbsoluteLayout absoluteLayout = AbsoluteLayout::New();
+  Control container = Control::New();
+  container.SetName( "Container" );
+  DevelControl::SetLayout( container, absoluteLayout );
+  container.SetAnchorPoint( Dali::AnchorPoint::CENTER );
+  container.SetParentOrigin( Dali::ParentOrigin::CENTER );
+
+  TextLabel textLabel = CreateTextLabel( "W" );
+  tet_infoline("SetSize explicitly then set ResizePolicy::NaturalSize");
+  textLabel.SetSize( 300.0f, 200.0f );
+  textLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+  textLabel.SetName( "text-label" );
+  tet_infoline("Adding child to container");
+  container.Add( textLabel );
+
+  tet_infoline("Adding container stage");
+  stage.Add( container );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Not re-laid out
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 54.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  textLabel.SetProperty( TextLabel::Property::TEXT, "WWW" );
+
+  application.SendNotification();
+  application.Render();
+
+  // Add container to stage here
+  // Should call RequestLayout() to measure and layout
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION ); // Stage Size
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 162.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliLayouting_StageAdd(void)
 {
   ToolkitTestApplication application;
@@ -3359,7 +3470,8 @@ int UtcDaliLayouting_StageAdd(void)
   child.SetAnchorPoint( Dali::AnchorPoint::TOP_LEFT );
   child.SetPosition( 0.0f, 0.0f );
   child.SetSize( 480.0f, 180.0f );
-  child.SetName( "Child Control" );
+  child.SetName( "ChildControl" );
+  tet_infoline("Adding child to container");
   container.Add( child );
 
   // Ensure layouting happens
@@ -3377,6 +3489,7 @@ int UtcDaliLayouting_StageAdd(void)
 
   // Add container to stage here
   // Should call RequestLayout() to measure and layout
+  tet_infoline("Adding container stage");
   stage.Add( container );
 
   application.SendNotification();
index 5ebb163..6147a80 100755 (executable)
@@ -350,7 +350,7 @@ void LayoutGroup::MeasureChild( LayoutItemPtr child,
   // Get last stored width and height specifications for the child
   auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
   auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild desiredWidth(%d) desiredHeight(%d)\n", desiredWidth, desiredHeight );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild child WIDTH_SPEC(%d) child HEIGHT SPEC(%d)\n", desiredWidth, desiredHeight );
 
   auto padding = GetPadding(); // Padding of this layout's owner, not of the child being measured.
 
@@ -374,13 +374,13 @@ void LayoutGroup::MeasureChildWithMargins( LayoutItemPtr child,
 
   auto padding = GetPadding(); // Padding of this layout's owner, not of the child being measured.
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins desiredWidth(%d)\n",  desiredWidth );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins child WIDTH_SPEC(%d)\n",  desiredWidth );
 
   MeasureSpec childWidthMeasureSpec = GetChildMeasureSpec( parentWidthMeasureSpec,
                                                            LayoutLength( padding.start + padding.end ) +
                                                            widthUsed, desiredWidth );
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins desiredHeight(%d)\n",  desiredHeight );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChildWithMargins child HEIGHT_SPEC(%d)\n",  desiredHeight );
 
   MeasureSpec childHeightMeasureSpec = GetChildMeasureSpec( parentHeightMeasureSpec,
                                                             LayoutLength( padding.top + padding.bottom )+
@@ -398,12 +398,14 @@ MeasureSpec LayoutGroup::GetChildMeasureSpec(
   auto specMode = measureSpec.GetMode();
   LayoutLength specSize = measureSpec.GetSize();
 
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::GetChildMeasureSpec childDimension(%f)\n", childDimension.AsInteger() );
+
   LayoutLength size = std::max( LayoutLength(0), specSize - padding ); // reduce available size by the owners padding
 
   LayoutLength resultSize = 0;
   MeasureSpec::Mode resultMode = MeasureSpec::Mode::UNSPECIFIED;
 
-  switch( specMode )
+  switch( specMode ) // Parents specMode
   {
     // Parent has imposed an exact size on us
     case MeasureSpec::Mode::EXACTLY:
@@ -632,14 +634,21 @@ void LayoutGroup::ChildAddedToOwnerImpl( Actor child )
       Vector3 size = child.GetTargetSize();
       // If the size of the control is set explicitly make sure that the control size
       // stays the same after the layout except it is over written with match parent specs.
-      if ( size.x != 0 )
+
+      auto childControl = Toolkit::Control::DownCast(childLayout->GetOwner());
+
+      bool setWidthExplictly = ( childControl.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ) > 0  );
+      if ( size.x != 0 || setWidthExplictly )
       {
-        childLayout->SetMinimumWidth( size.x );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner SetTargetWidth(%f)\n", size.x );
+        childLayout->SetTargetWidth( size.x );
       }
 
-      if ( size.y != 0 )
+      bool setHeightExplcitly = ( childControl.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ) > 0 );
+      if ( size.y != 0 || setHeightExplcitly )
       {
-        childLayout->SetMinimumHeight( size.y );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner SetTargetHeight(%f)\n", size.y);
+        childLayout->SetTargetHeight( size.y );
       }
       // Default layout data will be generated by Add().
     }
index 0b638de..67e0917 100644 (file)
@@ -353,7 +353,7 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS
   auto specMode = measureSpec.GetMode();
   auto specSize = measureSpec.GetSize();
 
-  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize MeasureSpec("<<measureSpec<< ") size:" << size << "\n" );
+  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize size:" << size <<  "MeasureSpec(" << measureSpec << ") \n" );
 
   switch (specMode)
   {
@@ -366,10 +366,9 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS
     {
       // Ensure the default size does not exceed the spec size unless the default size is 0.
       // Another container could provide a default size of 0.
-      LayoutLength tmp = specSize;
 
       // Do not set size to 0, use specSize in this case as could be a legacy container
-      if( size < tmp && size > LayoutLength( 0 ) )
+      if( ( size < specSize ) && ( size > LayoutLength( 0 ) )  )
       {
         result = size;
       }
@@ -394,8 +393,13 @@ void LayoutItem::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeas
   DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n");
 
   // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight
-  SetMeasuredDimensions( GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ),
-                         GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ) );
+  auto minimumWidth = GetSuggestedMinimumWidth();
+  auto minimumHeight = GetSuggestedMinimumHeight();
+  DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure minimumWidth(%f) minimumHeight(%f)\n",
+                 minimumWidth.AsInteger(), minimumHeight.AsInteger() );
+
+  SetMeasuredDimensions( GetDefaultSize( minimumWidth, widthMeasureSpec ),
+                         GetDefaultSize( minimumHeight, heightMeasureSpec ) );
 }
 
 void LayoutItem::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
@@ -519,8 +523,21 @@ LayoutLength LayoutItem::GetSuggestedMinimumWidth() const
   auto owner = GetOwner();
   auto actor = Actor::DownCast(owner);
   auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
+  LayoutLength layoutMinimumWidth = GetMinimumWidth();
+
+  // Set minimum size takes precedence over natural size.
+  LayoutLength result = std::max( layoutMinimumWidth, LayoutLength( naturalSize.width ) );
+
+  if( actor.GetChildCount() == 0 ) // If not a container
+  {
+    LayoutLength targetWidth = GetTargetWidth();
+    DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumWidth targetWidth(%f)\n", targetWidth.AsInteger() );
+    result = (result > 0 && (targetWidth < 1 ) ) ? result : targetWidth;  // Use size set if no mininum width and control has no natural size.
+  }
 
-  return std::max( mImpl->mMinimumSize.GetWidth(), LayoutLength( naturalSize.width ) );
+  DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumWidth control(%s) naturalWidth(%f) minimumSize.width(%f) targetWidth(%f) result(%f)\n",
+        actor.GetName().c_str(), LayoutLength( naturalSize.width ).AsInteger(), layoutMinimumWidth.AsInteger(), actor.GetTargetSize().width, result.AsInteger() );
+  return result;
 }
 
 LayoutLength LayoutItem::GetSuggestedMinimumHeight() const
@@ -528,8 +545,20 @@ LayoutLength LayoutItem::GetSuggestedMinimumHeight() const
   auto owner = GetOwner();
   auto actor = Actor::DownCast(owner);
   auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
+  LayoutLength layoutMinimumHeight = GetMinimumHeight();
 
-  return std::max( mImpl->mMinimumSize.GetHeight(), LayoutLength( naturalSize.height ) );
+  // Set minimum size takes precedence over natural size.
+  LayoutLength result = std::max( layoutMinimumHeight, LayoutLength( naturalSize.height ) );
+
+  if( actor.GetChildCount() == 0 ) // If not a container
+  {
+    LayoutLength targetHeight = GetTargetHeight();
+    result = (result > 0 && (targetHeight < 1 ) )?result : targetHeight; // Use size set if no mininum width and control has no natural size.
+  }
+
+  DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::GetSuggestedMinimumHeight control(%s) naturalHeight(%f) minimumHeight(%f) targetHeight(%f) result(%f)\n",
+          actor.GetName().c_str(), naturalSize.height, layoutMinimumHeight.AsInteger(), actor.GetTargetSize().height, result.AsInteger() );
+  return result;
 }
 
 MeasuredSize LayoutItem::ResolveSizeAndState( LayoutLength size, MeasureSpec measureSpec, MeasuredSize::State childMeasuredState )
@@ -584,6 +613,9 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig
     mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_FORCE_SET_FRAME );
   }
 
+  DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame %s changed size(%s)\n",
+        Actor::DownCast( GetOwner() ).GetName().c_str(), (changed)?"yes":"no" );
+
   LayoutLength oldWidth = mImpl->mRight - mImpl->mLeft;
   LayoutLength oldHeight = mImpl->mBottom - mImpl->mTop;
   LayoutLength newWidth = right - left;
@@ -660,6 +692,26 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig
   return changed;
 }
 
+LayoutLength LayoutItem::GetTargetWidth() const
+{
+  return mImpl->mTargetWidth;
+}
+
+LayoutLength LayoutItem::GetTargetHeight() const
+{
+  return mImpl->mTargetHeight;
+}
+
+void LayoutItem::SetTargetWidth( LayoutLength width )
+{
+  mImpl->mTargetWidth = width;
+}
+
+void LayoutItem::SetTargetHeight( LayoutLength height )
+{
+  mImpl->mTargetHeight = height;
+}
+
 void LayoutItem::OnLayoutAnimationFinished( Animation& animation )
 {
   auto owner = GetOwner();
index 47d65cc..9089eaf 100755 (executable)
@@ -359,6 +359,40 @@ public:
    */
   Extents GetMargin() const;
 
+  /**
+   * @brief Sets the target width of the layout item.
+   *
+   * The item may not actually be drawn as this size but the value is stored
+   * so if space allows it may take up this size at some point.
+   *
+   * @param[in] width The target width the layout will try to be, in pixels
+   */
+  void SetTargetWidth( LayoutLength width );
+
+  /**
+   * @brief Sets the target height of the layout item.
+   *
+   * The item may not actually be drawn as this size but the value is stored
+   * so if space allows it may take up this size at some point.
+   *
+   * @param[in] height The target width the layout will try to be, in pixels
+   */
+  void SetTargetHeight( LayoutLength height );
+
+  /**
+   * @brief Gets the target width of this layout item.
+   *
+   * @return height The target width set on this layout item
+   */
+  LayoutLength GetTargetWidth() const;
+
+  /**
+   * @brief Gets the target height of the layout item.
+   *
+   * @return height The target width set on this layout item
+   */
+  LayoutLength GetTargetHeight() const;
+
 protected:
   /**
    * @brief Allow directly deriving classes to remove layout children when unparented
index c97a8df..c254124 100644 (file)
@@ -37,6 +37,8 @@ LayoutItem::Impl::Impl()
   mMinimumSize(),
   mMeasuredWidth(0),
   mMeasuredHeight(0),
+  mTargetWidth(0),
+  mTargetHeight(0),
   mLeft( 0 ),
   mRight( 0 ),
   mTop( 0 ),
index 0b415ad..cff1577 100644 (file)
@@ -45,6 +45,9 @@ public:
   MeasuredSize mMeasuredWidth;
   MeasuredSize mMeasuredHeight;
 
+  LayoutLength mTargetWidth;  ///< Original fixed width that was set
+  LayoutLength mTargetHeight; ///< Original fixed height that was set
+
   LayoutLength mLeft;
   LayoutLength mRight;
   LayoutLength mTop;
index 1804809..a0788b0 100755 (executable)
@@ -707,6 +707,24 @@ void Control::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
 void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
 {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "Control::OnSetResizePolicy for %s %d\n", Self().GetName().c_str(), policy );
+
+    if( mImpl->GetLayout() )
+    {
+      const ResizePolicy::Type resizePolicy = Self().GetResizePolicy( dimension );
+
+      if( ResizePolicy::FIXED != resizePolicy && ( Self().GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ) < 0 ) && ( dimension == Dimension::WIDTH || dimension == Dimension::ALL_DIMENSIONS ) )
+      {
+        DALI_LOG_INFO( gLogFilter, Debug::General, "Control::OnSetResizePolicy Reseting MinimumWidth\n" );
+        mImpl->GetLayout()->SetMinimumWidth( 0 );
+      }
+
+      if( ResizePolicy::FIXED != resizePolicy && ( Self().GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ) < 0 ) &&  ( dimension == Dimension::HEIGHT || dimension == Dimension::ALL_DIMENSIONS ) )
+      {
+        DALI_LOG_INFO( gLogFilter, Debug::General, "Control::OnSetResizePolicy Reseting MinimumHeight\n" );
+        mImpl->GetLayout()->SetMinimumHeight( 0 );
+      }
+    }
 }
 
 Vector3 Control::GetNaturalSize()