From: Adeel Kazmi Date: Fri, 27 Jul 2018 15:51:55 +0000 (+0000) Subject: Merge "Change layout item list order according to the actor's child list" into devel... X-Git-Tag: dali_1.3.35~4 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=d8ec629f3d3ce51d49eeb2068c38909ca21cf4a3;hp=3639aa62c56600070cb1a03aef89e76847f75b50 Merge "Change layout item list order according to the actor's child list" into devel/master --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp index cd82d5e..76f9cf4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include <../custom-layout.h> @@ -34,6 +35,15 @@ using namespace Dali; using namespace Toolkit; +void TestLayoutItemOrder( std::vector< Control >& controls, LayoutGroup& layoutGroup ) +{ + for( auto&& iter : controls ) + { + unsigned int siblingOrder = static_cast< unsigned int>( iter.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) ); + DALI_TEST_EQUALS( layoutGroup.GetChildAt( siblingOrder ), DevelControl::GetLayout( iter ), TEST_LOCATION ); + } +} + void utc_dali_toolkit_layouting_startup(void) { test_return_value = TET_UNDEF; @@ -1692,6 +1702,9 @@ int UtcDaliLayouting_LayoutChildren01(void) DALI_TEST_EQUALS( hboxLayout.GetOwner(), empty, TEST_LOCATION ); DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION ); + // For coverage + hboxImpl.SetLayoutRequested(); + END_TEST; } @@ -1798,10 +1811,10 @@ int UtcDaliLayouting_LayoutChildren04(void) END_TEST; } -int UtcDaliLayouting_SetLayoutOrder(void) +int UtcDaliLayouting_SetLayoutOrder01(void) { ToolkitTestApplication application; - tet_infoline(" UtcDaliLayouting_SetLayoutOrder - Call SetLayout after adding the control to the root layout"); + tet_infoline(" UtcDaliLayouting_SetLayoutOrder01 - Call SetLayout after adding the control to the root layout"); Stage stage = Stage::GetCurrent(); @@ -1838,3 +1851,91 @@ int UtcDaliLayouting_SetLayoutOrder(void) END_TEST; } + +int UtcDaliLayouting_SetLayoutOrder02(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliLayouting_SetLayoutOrder02 - Test the layout item order and the control order"); + + Stage stage = Stage::GetCurrent(); + + auto rootControl = Control::New(); + auto absoluteLayout = AbsoluteLayout::New(); + DevelControl::SetLayout( rootControl, absoluteLayout ); + rootControl.SetName( "AbsoluteLayout" ); + stage.Add( rootControl ); + + auto hbox = Control::New(); + auto hboxLayout = LinearLayout::New(); + hbox.SetName( "HBox"); + + rootControl.Add( hbox ); + + DevelControl::SetLayout( hbox, hboxLayout ); + + // Add child controls + std::vector< Control > controls; + controls.push_back( CreateLeafControl( 100, 100 ) ); // 0 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 1 + controls.push_back( CreateLeafControl( 100, 100 ) ); // 2 + + for( auto&& iter : controls ) + { + hbox.Add( iter ); + } + + // Ensure layouting happens + application.SendNotification(); + application.Render(); + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("RaiseToTop"); + + controls[0].RaiseToTop(); // 1 2 0 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("LowerToBottom"); + + controls[2].LowerToBottom(); // 2 1 0 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("Remove / Add"); + + hbox.Remove( controls[2] ); // 1 0 + hbox.Add( controls[2] ); // 1 0 2 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("SetLayout"); + + auto vboxLayout = LinearLayout::New(); + DevelControl::SetLayout( controls[0], vboxLayout ); + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("Raise"); + + controls[0].Raise(); // 1 2 0 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("Lower"); + + controls[2].Lower(); // 2 1 0 + + TestLayoutItemOrder( controls, hboxLayout ); + + tet_infoline("SetLayout again"); + + auto vboxLayout1 = LinearLayout::New(); + DevelControl::SetLayout( controls[2], vboxLayout1 ); + + TestLayoutItemOrder( controls, hboxLayout ); + + DevelControl::SetLayout( controls[2], vboxLayout ); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp index f3856de..69d268d 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.cpp @@ -122,6 +122,104 @@ void LayoutGroup::Remove( LayoutItem& child ) RequestLayout(); } +Toolkit::LayoutGroup::LayoutId LayoutGroup::Insert( LayoutItem& target, LayoutItem& child ) +{ + LayoutParent* oldParent = child.GetParent(); + if( oldParent ) + { + LayoutGroupPtr parentGroup( dynamic_cast< LayoutGroup* >( oldParent ) ); + if( parentGroup ) + { + parentGroup->Remove( child ); + } + } + + // Find target position + std::vector< Impl::ChildLayout >::iterator position; + for( auto iter = mImpl->mChildren.begin(); iter != mImpl->mChildren.end(); ++iter ) + { + if( iter->child.Get() == &target ) + { + position = iter; + break; + } + } + + Impl::ChildLayout childLayout; + childLayout.layoutId = mImpl->mNextLayoutId++; + childLayout.child = &child; + mImpl->mChildren.insert( position, childLayout ); + + child.SetParent( this ); + + auto owner = child.GetOwner(); + + // Inform deriving classes that this child has been added + OnChildAdd( *childLayout.child.Get() ); + + // Now listen to future changes to the child properties. + DevelHandle::PropertySetSignal(owner).Connect( this, &LayoutGroup::OnSetChildProperties ); + + RequestLayout(); + + return childLayout.layoutId; +} + +Toolkit::LayoutGroup::LayoutId LayoutGroup::Move( LayoutItem& target, LayoutItem& child ) +{ + // Remove child from the previous position + for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; ++iter ) + { + if( iter->child.Get() == &child ) + { + mImpl->mChildren.erase( iter ); + break; + } + } + + // Find target position + std::vector< Impl::ChildLayout >::iterator position; + for( auto iter = mImpl->mChildren.begin(); iter != mImpl->mChildren.end(); ++iter ) + { + if( iter->child.Get() == &target ) + { + position = iter; + break; + } + } + + Impl::ChildLayout childLayout; + childLayout.layoutId = mImpl->mNextLayoutId++; + childLayout.child = &child; + mImpl->mChildren.insert( position, childLayout ); + + RequestLayout(); + + return childLayout.layoutId; +} + +Toolkit::LayoutGroup::LayoutId LayoutGroup::MoveBack( LayoutItem& child ) +{ + // Remove child from the previous position + for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; ++iter ) + { + if( iter->child.Get() == &child ) + { + mImpl->mChildren.erase( iter ); + break; + } + } + + Impl::ChildLayout childLayout; + childLayout.layoutId = mImpl->mNextLayoutId++; + childLayout.child = &child; + mImpl->mChildren.emplace_back( childLayout ); + + RequestLayout(); + + return childLayout.layoutId; +} + void LayoutGroup::RemoveAll() { for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; ) @@ -418,7 +516,30 @@ void LayoutGroup::OnInitialize() if( parentLayout ) { Internal::LayoutGroup& parentLayoutImpl = GetImplementation( parentLayout ); - parentLayoutImpl.Add( *this ); + + unsigned int count = parent.GetChildCount(); + unsigned int index = static_cast< unsigned int >( control.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) ); + + // Find insertion position + while( ++index < count ) + { + auto sibling = Toolkit::Control::DownCast( parent.GetChildAt( index ) ); + if( sibling ) + { + auto siblingLayout = DevelControl::GetLayout( sibling ); + if( siblingLayout ) + { + Internal::LayoutItem& siblingLayoutImpl = GetImplementation( siblingLayout ); + parentLayoutImpl.Insert( siblingLayoutImpl, *this ); + break; + } + } + } + + if( index >= count ) + { + parentLayoutImpl.Add( *this ); + } } } } @@ -509,13 +630,39 @@ void LayoutGroup::ChildRemovedFromOwner( Actor child ) } } -void LayoutGroup::ChildOrderChanged() +void LayoutGroup::ChildOrderChanged( Actor child ) { - RequestLayout(); - // Force Children to be relaid out: - for( auto&& child : mImpl->mChildren ) + Toolkit::Control childControl = Toolkit::Control::DownCast( child ); + if( childControl ) { - child.child->SetLayoutRequested(); + Internal::Control& childControlImpl = GetImplementation( childControl ); + Internal::Control::Impl& childControlDataImpl = Internal::Control::Impl::Get( childControlImpl ); + + auto childLayout = childControlDataImpl.GetLayout(); + if( childLayout ) + { + Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() ); + unsigned int count = control.GetChildCount(); + unsigned int index = static_cast< unsigned int >( childControl.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) ); + + // Find insertion position + while( ++index < count ) + { + auto sibling = Toolkit::Control::DownCast( control.GetChildAt( index ) ); + if( sibling ) + { + auto siblingLayout = DevelControl::GetLayout( sibling ); + if( siblingLayout ) + { + Internal::LayoutItem& siblingLayoutImpl = GetImplementation( siblingLayout ); + Move( siblingLayoutImpl, *childLayout ); + return; + } + } + } + + MoveBack( *childLayout ); + } } } diff --git a/dali-toolkit/devel-api/layouting/layout-group-impl.h b/dali-toolkit/devel-api/layouting/layout-group-impl.h index 36e0312..3039125 100644 --- a/dali-toolkit/devel-api/layouting/layout-group-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-group-impl.h @@ -96,6 +96,26 @@ public: void Remove( LayoutItem& child ) override; /** + * @brief Insert a child to the parent + * @param[in] target The target item + * @param[in] child The item to insert to this layout parent + */ + Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& child ) override; + + /** + * @brief Move a child to another position + * @param[in] target The target item + * @param[in] child The item to move + */ + Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& child ) override; + + /** + * @brief Move a child to back + * @param[in] child The item to move + */ + Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& child ) override; + + /** * @brief Remove all layout children. * * @note This will not unparent owner's children @@ -264,7 +284,7 @@ private: /** * Callback when child order is changed */ - void ChildOrderChanged(); + void ChildOrderChanged( Actor child ); /** * Callback when an owner property is set. Triggers a relayout if it's a child property diff --git a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp index 4c1e6b9..a0350e3 100644 --- a/dali-toolkit/devel-api/layouting/layout-item-impl.cpp +++ b/dali-toolkit/devel-api/layouting/layout-item-impl.cpp @@ -327,7 +327,7 @@ bool LayoutItem::IsLayoutRequested() const void LayoutItem::SetLayoutRequested() { - return mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); + mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT ); } void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight ) diff --git a/dali-toolkit/devel-api/layouting/layout-parent-impl.h b/dali-toolkit/devel-api/layouting/layout-parent-impl.h index 677a8ff..7c9414f 100644 --- a/dali-toolkit/devel-api/layouting/layout-parent-impl.h +++ b/dali-toolkit/devel-api/layouting/layout-parent-impl.h @@ -52,6 +52,26 @@ public: */ virtual void Remove( LayoutItem& item ) = 0; + /** + * @brief Insert a child to the parent + * @param[in] target The target item + * @param[in] item The item to insert to this layout parent + */ + virtual Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& item ) = 0; + + /** + * @brief Move a child to another position + * @param[in] target The target item + * @param[in] item The item to move + */ + virtual Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& item ) = 0; + + /** + * @brief Move a child to back + * @param[in] item The item to move + */ + virtual Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& item ) = 0; + protected: virtual ~LayoutParent() {