From 56a9f0862566dfb88e0f0266c211ca9766e9bf49 Mon Sep 17 00:00:00 2001 From: Agnelo Vaz Date: Mon, 20 Aug 2018 17:28:20 +0100 Subject: [PATCH] Controls are LayoutGroups instead of LayoutItems LayoutGroup measures and layouts it's children. Children are currently positioned by their AnchorPoint and Position. Children are not positioned in relation to each other so may overlap. Change-Id: I786736a13f5f0b00c15fec461b5a20883da9f346 --- .../src/dali-toolkit/utc-Dali-Layouting.cpp | 251 +++++++++++++++++++++ .../devel-api/layouting/layout-group-impl.cpp | 158 ++++++++++++- .../devel-api/layouting/layout-group-impl.h | 17 ++ dali-toolkit/devel-api/layouting/layout-group.cpp | 6 + dali-toolkit/devel-api/layouting/layout-group.h | 7 + .../devel-api/layouting/layout-item-impl.cpp | 22 +- .../internal/layouting/absolute-layout-impl.cpp | 3 +- .../internal/layouting/layout-controller-impl.cpp | 4 +- 8 files changed, 458 insertions(+), 10 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp index 29e3726..8fabd35 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp @@ -35,6 +35,9 @@ using namespace Dali; using namespace Toolkit; +namespace +{ + void TestLayoutItemOrder( std::vector< Control >& controls, LayoutGroup& layoutGroup ) { for( auto&& iter : controls ) @@ -44,6 +47,19 @@ void TestLayoutItemOrder( std::vector< Control >& controls, LayoutGroup& layoutG } } +// Turns the given control into a Root layout control and adds it to the stage. +void SetupRootLayoutControl( Control& rootControl ) +{ + rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "RootAbsoluteLayout" ); + Stage stage = Stage::GetCurrent(); + stage.Add( rootControl ); +} + +} // unnamed namespace + void utc_dali_toolkit_layouting_startup(void) { test_return_value = TET_UNDEF; @@ -623,6 +639,7 @@ int UtcDaliLayouting_HboxLayout08(void) Control control1 = CreateLeafControl( 40, 40 ); rootControl.Add( control1 ); + auto hbox = Control::New(); auto hboxLayout = LinearLayout::New(); hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); @@ -641,7 +658,9 @@ int UtcDaliLayouting_HboxLayout08(void) DALI_TEST_EQUALS( hboxLayout.IsLayoutAnimated(), false, TEST_LOCATION ); DALI_TEST_EQUALS( DevelControl::GetLayout( control2 ).IsLayoutAnimated(), false, TEST_LOCATION ); + tet_infoline(" Set hBoxLayout to animate"); hboxLayout.SetAnimateLayout( true ); + tet_infoline(" Set absoluteLayout not to animate"); absoluteLayout.SetAnimateLayout( false ); DALI_TEST_EQUALS( absoluteLayout.IsLayoutAnimated(), false, TEST_LOCATION ); @@ -2028,3 +2047,235 @@ int UtcDaliLayouting_SetLayoutOrder02(void) END_TEST; } + +int UtcDaliLayouting_LayoutGroup01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayouting_LayoutGroup01 - Test adding a control to a layout then adding a TextLabel to that control"); + + Control rootControl; + SetupRootLayoutControl( rootControl ); + + // Create a parent layout + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 600 ); + hbox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + hbox.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // LinearLayout will eventually do this internally. + + tet_infoline("Add a control without SetLayout being called"); + + auto control = Control::New(); + control.SetName("Control1"); + hbox.Add( control ); + control.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + control.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + + tet_infoline("Add a Textlabel to the control"); + auto textLabel = TextLabel::New("Test text"); + textLabel.SetName("TextLabel"); + control.Add( textLabel ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Test text is it's natural size"); + DALI_TEST_EQUALS( textLabel.GetProperty( Actor::Property::SIZE ), Vector3( 230.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Test control is width of it's parent and height of it's child"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 600.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_LayoutGroup02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayouting_LayoutGroup02 - Test control is the size of it's largest child"); + + Control rootControl; + SetupRootLayoutControl( rootControl ); + + // Create a parent layout + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 600 ); + hbox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + hbox.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // LinearLayout will eventually do this internally. + + tet_infoline("Add a control without SetLayout being called"); + + auto control = Control::New(); + control.SetName("Control1"); + hbox.Add( control ); + control.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + control.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + + tet_infoline("Add a Textlabel to the control"); + auto textLabel = TextLabel::New("Test text"); + textLabel.SetName("TextLabel"); + control.Add( textLabel ); + + tet_infoline("Add another Textlabel to the control"); + auto largeTextLabel = TextLabel::New("Test large text"); + largeTextLabel.SetName("TextLabel-Large"); + control.Add( largeTextLabel ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Test text is it's natural size"); + DALI_TEST_EQUALS( textLabel.GetProperty( Actor::Property::SIZE ), Vector3( 230.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Test text is centered in the control, the control is the size of the largest child"); + DALI_TEST_EQUALS( textLabel.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Test large text is it's natural size"); + DALI_TEST_EQUALS( largeTextLabel.GetProperty( Actor::Property::SIZE ), Vector3( 382.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Test text is aligned to start as is the size of the control"); + DALI_TEST_EQUALS( largeTextLabel.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + tet_infoline("Test control is width of it's parent and height of it's largest child"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 382.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_LayoutGroup03(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayouting_LayoutGroup03 - Test control witha LayoutGroup as a leaf"); + + Control rootControl; + SetupRootLayoutControl( rootControl ); + + // Create a parent layout + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 600 ); + hbox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + hbox.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // LinearLayout will eventually do this internally. + + tet_infoline("Add a control without SetLayout being called"); + + auto control = Control::New(); + control.SetName("Control1"); + hbox.Add( control ); + control.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + control.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 100 ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Test control is width of it's parent and exact given height"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 600.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_LayoutGroupWithPadding01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayouting_LayoutGroupWithPadding01 - Test adding a control to a layout that has padding"); + + Control rootControl; + SetupRootLayoutControl( rootControl ); + + // Create a parent layout + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 600 ); + hbox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + hbox.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // LinearLayout will eventually do this internally. + + tet_infoline("Add a control without SetLayout being called"); + + auto control = Control::New(); + control.SetName("Control1"); + hbox.Add( control ); + control.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + control.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + + const Extents CONTROL_PADDING = Extents(5, 10, 20, 2 ); + tet_printf( "Adding Padding to control"); + control.SetProperty( Toolkit::Control::Property::PADDING, CONTROL_PADDING ); + + tet_infoline("Add a Textlabel to the control"); + auto textLabel = TextLabel::New("Test text"); + textLabel.SetName("TextLabel"); + control.Add( textLabel ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Test text is it's natural size"); + DALI_TEST_EQUALS( textLabel.GetProperty( Actor::Property::SIZE ), Vector3( 230.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Test control is size of it's child and control it's own padding"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 245.0f, 86.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliLayouting_LayoutGroupWithChildMargin01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliLayouting_LayoutGroupWithChildMargin01 - Test adding a control with padding to a layout that has padding"); + + Control rootControl; + SetupRootLayoutControl( rootControl ); + + // Create a parent layout + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + rootControl.Add( hbox ); + DevelControl::SetLayout( hbox, hboxLayout ); + hbox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 600 ); + hbox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + hbox.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // LinearLayout will eventually do this internally. + + tet_infoline("Add a control without SetLayout being called"); + + auto control = Control::New(); + control.SetName("Control1"); + hbox.Add( control ); + control.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + control.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT ); + + const Extents CONTROL_PADDING = Extents(5, 10, 20, 2 ); + tet_printf( "Adding Padding to control"); + control.SetProperty( Toolkit::Control::Property::PADDING, CONTROL_PADDING ); + + tet_infoline("Add a Textlabel to the control"); + auto textLabel = TextLabel::New("Test text"); + const Extents CHILD_MARGIN = Extents( 10, 0, 5, 0 ); + textLabel.SetProperty( Toolkit::Control::Property::MARGIN, CHILD_MARGIN ); + textLabel.SetName("TextLabel"); + control.Add( textLabel ); + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + tet_infoline("Test text is it's natural size"); + DALI_TEST_EQUALS( textLabel.GetProperty( Actor::Property::SIZE ), Vector3( 230.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + tet_infoline("Test control is width of it's parent and height of it's child"); + DALI_TEST_EQUALS( control.GetProperty( Actor::Property::SIZE ), Vector3( 255.0f, 91.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp index 69d268d..9f54f56 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp @@ -48,6 +48,12 @@ LayoutGroup::LayoutGroup() { } +LayoutGroupPtr LayoutGroup::New( Handle& owner ) +{ + LayoutGroupPtr layoutPtr = new LayoutGroup(); + return layoutPtr; +} + LayoutGroup::~LayoutGroup() { // An object with a unique_ptr to an opaque structure must define it's destructor in the translation unit @@ -333,7 +339,8 @@ void LayoutGroup::MeasureChild( LayoutItemPtr child, #if defined( DEBUG_ENABLED ) if ( control ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild natural size(%f, %f)\n", control.GetNaturalSize().width, control.GetNaturalSize().height ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::MeasureChild(%s) natural size(%f, %f)\n", + control.GetName().c_str(), control.GetNaturalSize().width, control.GetNaturalSize().height ); } #endif @@ -568,7 +575,10 @@ void LayoutGroup::ChildAddedToOwner( Actor child ) LayoutItemPtr childLayout; Toolkit::Control control = Toolkit::Control::DownCast( child ); - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control(%s)\n", control?control.GetName().c_str():"Invalid" ); +#if defined(DEBUG_ENABLED) + auto parent = Toolkit::Control::DownCast( GetOwner() ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control(%s) owner(%s)\n", control?control.GetName().c_str():"Invalid", parent?parent.GetName().c_str():"Invalid" ); +#endif if( control ) // Can only support adding Controls, not Actors to layout { @@ -579,7 +589,7 @@ void LayoutGroup::ChildAddedToOwner( Actor child ) if( ! childLayout ) { // If the child doesn't already have a layout, then create a LayoutItem for it. - childLayout = LayoutItem::New( control ); + childLayout = LayoutGroup::New( control ); childLayout->SetAnimateLayout( IsLayoutAnimated() ); // @todo this essentially forces animation inheritance. Bad? #if defined(DEBUG_ENABLED) auto desiredSize = control.GetNaturalSize(); @@ -688,7 +698,7 @@ void LayoutGroup::OnAnimationStateChanged( bool animateLayout ) for( auto&& child : mImpl->mChildren ) { LayoutGroupPtr parentGroup( dynamic_cast< LayoutGroup* >( child.child.Get() ) ); - if( !parentGroup ) + if( parentGroup && ( 0 == parentGroup->GetChildCount() ) ) // A leaf LayoutGroup will have no children. { // Change state only in case of leaf children child.child->SetAnimateLayout( animateLayout ); @@ -696,6 +706,146 @@ void LayoutGroup::OnAnimationStateChanged( bool animateLayout ) } } +void LayoutGroup::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) +{ + DALI_LOG_STREAM( gLogFilter, Debug::Verbose, + "LayoutGroup::OnMeasure Actor Id:" << Actor::DownCast(GetOwner()).GetId() << + " Owner:" << Actor::DownCast(GetOwner()).GetName() << + " MeasureSpecs( width:"< 0 ) + { + for( unsigned int i=0; iGetOwner(); + + // Get size of child + MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec ); + auto childWidth = childLayout->GetMeasuredWidth(); + auto childHeight = childLayout->GetMeasuredHeight(); + auto childMargin = childLayout->GetMargin(); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure child width[%d] height(%d)\n", childWidth.mValue, childHeight.mValue ); + + layoutWidth = std::max( layoutWidth, childWidth + childMargin.start + childMargin.end ); + layoutHeight = std::max( layoutHeight, childHeight + childMargin.top + childMargin.bottom ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure calculated child width[%d] calculated height(%d)\n", layoutWidth.mValue, layoutHeight.mValue ); + } + } + + Extents padding = GetPadding(); + layoutWidth += padding.start + padding.end; + layoutHeight += padding.top + padding.bottom; + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Getting default size as a leaf\n" ); + // LayoutGroup does not contain any children so must be a leaf + layoutWidth = GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ); + layoutHeight = GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ); + } + + // Can't exceed specified width + if( widthMode == MeasureSpec::Mode::EXACTLY ) + { + exactWidth = true; + } + else if ( widthMode == MeasureSpec::Mode::AT_MOST ) + { + layoutWidth = std::min( layoutWidth, widthSpecSize ); + } + + // Can't exceed specified height + if( heightMode == MeasureSpec::Mode::EXACTLY ) + { + exactHeight = true; + } + else if ( heightMode == MeasureSpec::Mode::AT_MOST ) + { + layoutHeight = std::min( layoutHeight, heightSpecSize ); + } + + layoutWidth = std::max( layoutWidth, GetSuggestedMinimumWidth() ); + layoutHeight = std::max( layoutHeight, GetSuggestedMinimumHeight() ); + + if( exactWidth ) + { + layoutWidth = widthSpecSize; + } + + if( exactHeight ) + { + layoutHeight = heightSpecSize; + } + + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Measured size(%d,%d) for : %s \n", layoutWidth.mValue, layoutHeight.mValue, Actor::DownCast(GetOwner()).GetName().c_str() ); + SetMeasuredDimensions( MeasuredSize( layoutWidth ), MeasuredSize( layoutHeight ) ); +} + +void LayoutGroup::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnLayout\n"); + + auto count = GetChildCount(); + + for( unsigned int childIndex = 0; childIndex < count; childIndex++) + { + LayoutItemPtr childLayout = GetChildAt( childIndex ); + if( childLayout != nullptr ) + { + + auto childOwner = childLayout->GetOwner(); + auto childWidth = childLayout->GetMeasuredWidth(); + auto childHeight = childLayout->GetMeasuredHeight(); + auto childMargin = childLayout->GetMargin(); + auto control = Toolkit::Control::DownCast( childOwner ); + Extents padding = GetPadding(); + + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnLayout child width[%d] height(%d)\n", childWidth.mValue, childHeight.mValue ); + + auto childPosition = control.GetProperty< Vector3 >( Actor::Property::POSITION ); + auto anchorPoint = control.GetProperty< Vector3 >( Actor::Property::ANCHOR_POINT ); + + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnLayout child[%s] position(%f,%f)\n", control.GetName().c_str(), childPosition.x, childPosition.y ); + + // Margin and Padding only supported when child anchor point is TOP_LEFT. + int paddingAndMarginOffsetX = ( AnchorPoint::TOP_LEFT == anchorPoint ) ? ( padding.top + childMargin.top ) : 0; + int paddingAndMarginOffsetY = ( AnchorPoint::TOP_LEFT == anchorPoint ) ? ( padding.start + childMargin.start ) : 0; + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnLayout paddingMargin offset(%d,%d)\n", paddingAndMarginOffsetX, paddingAndMarginOffsetY ); + + LayoutLength childLeft = childPosition.x + paddingAndMarginOffsetX; + LayoutLength childTop = childPosition.y + paddingAndMarginOffsetY; + + childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight ); + } + } +} + + } // namespace Internal } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.h b/dali-toolkit/devel-api/layouting/layout-group-impl.h index 3039125..ee73c88 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.h @@ -65,6 +65,14 @@ public: */ LayoutGroup(); + /** + * @brief Construct + * + * @param[in] owner The owner (container view / child view / visual ) of this layout + * @return a new LayoutGroup object + */ + static LayoutGroupPtr New( Handle& owner ); + protected: /** * Virtual destructor may only be called by Unreference() @@ -248,6 +256,15 @@ protected: LayoutLength widthUsed, MeasureSpec parentHeightMeasureSpec, LayoutLength heightUsed ); + /** + * @copydoc LayoutItem::OnMeasure + */ + virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override; + + /** + * @copydoc LayoutItem::OnLayout + */ + virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) override; private: /** diff --git a/dali-toolkit/devel-api/layouting/layout-group.cpp b/dali-toolkit/devel-api/layouting/layout-group.cpp index b13da31..50ed913 100644 --- a/dali-toolkit/devel-api/layouting/layout-group.cpp +++ b/dali-toolkit/devel-api/layouting/layout-group.cpp @@ -27,6 +27,12 @@ LayoutGroup::LayoutGroup() { } +LayoutGroup LayoutGroup::New( Handle& handle ) +{ + Internal::LayoutGroupPtr layout = Internal::LayoutGroup::New( handle ); + return LayoutGroup( layout.Get() ); +} + LayoutGroup LayoutGroup::DownCast( BaseHandle handle ) { return LayoutGroup( dynamic_cast< Dali::Toolkit::Internal::LayoutGroup* >( handle.GetObjectPtr() ) ); diff --git a/dali-toolkit/devel-api/layouting/layout-group.h b/dali-toolkit/devel-api/layouting/layout-group.h index 1d9ad5d..9d0e684 100644 --- a/dali-toolkit/devel-api/layouting/layout-group.h +++ b/dali-toolkit/devel-api/layouting/layout-group.h @@ -80,6 +80,13 @@ public: ~LayoutGroup() = default; /** + * @brief Create an initialized LayoutGroup + * + * @param[in] handle A handle to the object that this layout for, e.g. a Control or a Visual::Base + */ + static LayoutGroup New( Handle& handle ); + + /** * @brief Copy constructor */ LayoutGroup(const LayoutGroup& copy) = default; diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index a0350e3..ecf86b3 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -95,6 +95,16 @@ void LayoutItem::Unparent() void LayoutItem::SetAnimateLayout( bool animateLayout ) { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetAnimateLayout animateLayout(%s)\n", (animateLayout)?"true":"false" ); + + auto owner = GetOwner(); + auto actor = Actor::DownCast(owner); + + if( actor ) + { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetAnimateLayout animateLayout(%s) owner(%s)\n", (animateLayout)?"true":"false", actor.GetName().c_str() ); + } + mImpl->mAnimated = animateLayout; OnAnimationStateChanged( animateLayout ); @@ -170,7 +180,7 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur // flag not set, setMeasuredDimension() was not invoked, we raise an exception to warn the developer DALI_ASSERT_ALWAYS( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET ) && - "Layout's OnMeasure() did not set the measured dimension by calling setMeasuredDimension()" ); + "Layout's OnMeasure() mension()" ); mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_LAYOUT_REQUIRED ); } @@ -180,6 +190,8 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur void LayoutItem::Layout( LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) { + DALI_LOG_TRACE_METHOD( gLayoutFilter ); + if( mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT ) ) { OnMeasure( mImpl->mOldWidthMeasureSpec, mImpl->mOldHeightMeasureSpec ); @@ -227,7 +239,7 @@ Extents LayoutItem::GetPadding() const { Extents padding = control.GetProperty( Toolkit::Control::Property::PADDING ); - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutBase::Padding for %s : (%d,%d,%d,%d) \n", + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::Padding for %s : (%d,%d,%d,%d) \n", control.GetName().c_str(), padding.start, padding.end, padding.top, padding.bottom ); @@ -289,6 +301,8 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS void LayoutItem::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec) { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n"); + SetMeasuredDimensions( GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ), GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ) ); } @@ -332,7 +346,7 @@ void LayoutItem::SetLayoutRequested() void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight ) { - DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutBase::SetMeasuredDimensions width(%d) height(%d) \n", + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(%d) height(%d) \n", MeasureSpec::IntType( measuredWidth.GetSize() ), MeasureSpec::IntType( measuredHeight.GetSize() ) ); @@ -450,6 +464,8 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig auto actor = Actor::DownCast(owner); if( actor ) { + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame owner(%s) (%d, %d, %d, %d)\n", actor.GetName().c_str(), + left.mValue, top.mValue, right.mValue, bottom.mValue ); if( mImpl->mAnimated ) { auto animation = Animation::New( 0.5f ); diff --git a/dali-toolkit/internal/layouting/absolute-layout-impl.cpp b/dali-toolkit/internal/layouting/absolute-layout-impl.cpp index 3f499ef..14fed57 100644 --- a/dali-toolkit/internal/layouting/absolute-layout-impl.cpp +++ b/dali-toolkit/internal/layouting/absolute-layout-impl.cpp @@ -106,7 +106,7 @@ void AbsoluteLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec height // Store current width and height needed to contain all children. totalWidth = maxPosition.x - minPosition.x; totalHeight = maxPosition.y - minPosition.y; - DALI_LOG_INFO( gLogFilter, Debug::Concise, "AbsoluteLayout::OnMeasure child width(%f) height(%f) \n", (float)totalWidth, (float)totalHeight ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AbsoluteLayout::OnMeasure child width(%f) height(%f) \n", (float)totalWidth, (float)totalHeight ); if( childLayout->GetMeasuredWidthAndState().GetState() == MeasuredSize::State::MEASURED_SIZE_TOO_SMALL ) { @@ -141,6 +141,7 @@ void AbsoluteLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top // Absolute layout positions it's children at their Actor positions. // Children could overlap or spill outside the parent, as is the nature of absolute positions. auto count = GetChildCount(); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "AbsoluteLayout::OnLayout child count(%d)\n", count ); for( unsigned int i = 0; i < count; i++) { diff --git a/dali-toolkit/internal/layouting/layout-controller-impl.cpp b/dali-toolkit/internal/layouting/layout-controller-impl.cpp index 1f12c3f..0e8d925 100644 --- a/dali-toolkit/internal/layouting/layout-controller-impl.cpp +++ b/dali-toolkit/internal/layouting/layout-controller-impl.cpp @@ -110,7 +110,7 @@ void LayoutController::MeasureHierarchy( Actor root, MeasureSpec widthSpec, Meas Toolkit::Control control = Toolkit::Control::DownCast( root ); if( control ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::Measuring leaf\n" ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::Measuring control\n" ); Internal::Control& controlImpl = GetImplementation( control ); Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl ); @@ -138,7 +138,7 @@ void LayoutController::PerformLayout( Actor root, int left, int top, int right, Toolkit::Control control = Toolkit::Control::DownCast( root ); if( control ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on leaf\n" ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayout on control[%s]\n", control.GetName().c_str() ); Internal::Control& controlImpl = GetImplementation( control ); Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl ); LayoutItemPtr layout = controlDataImpl.GetLayout(); -- 2.7.4