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;
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
// Add container to stage here
// Should call RequestLayout() to measure and layout
+ tet_infoline("Adding container stage");
stage.Add( container );
application.SendNotification();
// 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.
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 )+
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:
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().
}
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)
{
{
// 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;
}
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 )
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
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 )
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;
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();
*/
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
mMinimumSize(),
mMeasuredWidth(0),
mMeasuredHeight(0),
+ mTargetWidth(0),
+ mTargetHeight(0),
mLeft( 0 ),
mRight( 0 ),
mTop( 0 ),
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;
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()