Fix for SizeNegotiation.
[platform/core/uifw/dali-core.git] / dali / internal / event / size-negotiation / relayout-controller-impl.cpp
index 3deb9e1..9c2120a 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali/public-api/actors/layer.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/render-controller.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/object/object-registry.h>
 #include <dali/internal/event/actors/actor-impl.h>
@@ -67,9 +68,9 @@ void PrintChildren( Dali::Actor actor, int level )
 
   output << " - Pos: " << actor.GetCurrentPosition() << " Size: " << actor.GetTargetSize();
 
-  output << ", Dirty: (" << ( GetImplementation( actor ).IsLayoutDirty( WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutDirty( HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
-  output << ", Negotiated: (" << ( GetImplementation( actor ).IsLayoutNegotiated( WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutNegotiated( HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
-  output << ", Enabled: " << ( actor.IsRelayoutEnabled() ? "TRUE" : "FALSE" );
+  output << ", Dirty: (" << ( GetImplementation( actor ).IsLayoutDirty( Dimension::WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutDirty( Dimension::HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
+  output << ", Negotiated: (" << ( GetImplementation( actor ).IsLayoutNegotiated( Dimension::WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutNegotiated( Dimension::HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
+  output << ", Enabled: " << ( GetImplementation( actor ).IsRelayoutEnabled() ? "TRUE" : "FALSE" );
 
   output << ", (" << actor.GetObjectPtr() << ")" << std::endl;
 
@@ -111,13 +112,16 @@ RelayoutController* RelayoutController::Get()
   return &ThreadLocalStorage::Get().GetRelayoutController();
 }
 
-RelayoutController::RelayoutController()
-: mRelayoutInfoAllocator(),
+RelayoutController::RelayoutController( Integration::RenderController& controller )
+: mRenderController( controller ),
+  mRelayoutInfoAllocator(),
   mSlotDelegate( this ),
   mRelayoutStack( new MemoryPoolRelayoutContainer( mRelayoutInfoAllocator ) ),
   mRelayoutConnection( false ),
   mRelayoutFlag( false ),
-  mEnabled( false )
+  mEnabled( false ),
+  mPerformingRelayout( false ),
+  mProcessingCoreEvents( false )
 {
   // Make space for 32 controls to avoid having to copy construct a lot in the beginning
   mRelayoutStack->Reserve( 32 );
@@ -136,51 +140,61 @@ void RelayoutController::QueueActor( Dali::Actor& actor, RelayoutContainer& acto
   }
 }
 
-void RelayoutController::RequestRelayout( Dali::Actor& actor, Dimension dimension )
+void RelayoutController::RequestRelayout( Dali::Actor& actor, Dimension::Type dimension )
 {
   if( !mEnabled )
   {
     return;
   }
 
-  Dali::ActorContainer potentialRedundantSubRoots;
-  Dali::ActorContainer topOfSubTreeStack;
+  std::vector< Dali::Actor > potentialRedundantSubRoots;
+  std::vector< Dali::Actor > topOfSubTreeStack;
 
   topOfSubTreeStack.push_back( actor );
 
   // Propagate on all dimensions
-  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
   {
     if( dimension & ( 1 << i ) )
     {
       // Do the propagation
-      PropagateAll( actor, static_cast< Dimension >( 1 << i ), topOfSubTreeStack, potentialRedundantSubRoots );
+      PropagateAll( actor, static_cast< Dimension::Type >( 1 << i ), topOfSubTreeStack, potentialRedundantSubRoots );
     }
   }
 
-  // Request this actor as head of sub-tree if it is not dependent on a parent that is dirty
-  Dali::Actor subTreeActor = topOfSubTreeStack.back();
-  Dali::Actor parent = subTreeActor.GetParent();
-  if( !parent || !( GetImplementation( subTreeActor ).RelayoutDependentOnParent() && GetImplementation( parent ).RelayoutRequired() ) )
+  while( !topOfSubTreeStack.empty() )
   {
-    // Add sub tree root to relayout list
-    AddRequest( subTreeActor );
+    // Request this actor as head of sub-tree if it is not dependent on a parent that is dirty
+    Dali::Actor subTreeActor = topOfSubTreeStack.back();
+    topOfSubTreeStack.pop_back();
 
-    // Flag request for end of frame
-    Request();
-  }
-  else
-  {
-    potentialRedundantSubRoots.push_back( subTreeActor );
+    Dali::Actor parent = subTreeActor.GetParent();
+    if( !parent || !( GetImplementation( subTreeActor ).RelayoutDependentOnParent() && GetImplementation( parent ).RelayoutRequired() ) )
+    {
+      // Add sub tree root to relayout list
+      AddRequest( subTreeActor );
+
+      // Flag request for end of frame
+      Request();
+    }
+    else
+    {
+      potentialRedundantSubRoots.push_back( subTreeActor );
+    }
   }
 
   // Remove any redundant sub-tree heads
-  for( ActorContainer::iterator it = potentialRedundantSubRoots.begin(), itEnd = potentialRedundantSubRoots.end(); it != itEnd; ++it )
+  for( std::vector< Dali::Actor >::iterator it = potentialRedundantSubRoots.begin(), itEnd = potentialRedundantSubRoots.end(); it != itEnd; ++it )
   {
     Dali::Actor subRoot = *it;
 
     RemoveRequest( subRoot );
   }
+
+  if ( !mProcessingCoreEvents )
+  {
+    mRenderController.RequestProcessEventsOnIdle();
+  }
 }
 
 void RelayoutController::OnApplicationSceneCreated()
@@ -212,7 +226,7 @@ void RelayoutController::RequestRelayoutTree( Dali::Actor& actor )
   {
     // If parent is not in relayout we are at the top of a new sub-tree
     Dali::Actor parent = actor.GetParent();
-    if( !parent || !parent.IsRelayoutEnabled() )
+    if( !parent || !GetImplementation( parent ).IsRelayoutEnabled() )
     {
       AddRequest( actor );
     }
@@ -231,7 +245,7 @@ void RelayoutController::RequestRelayoutTree( Dali::Actor& actor )
   }
 }
 
-void RelayoutController::PropagateAll( Dali::Actor& actor, Dimension dimension, Dali::ActorContainer& topOfSubTreeStack, Dali::ActorContainer& potentialRedundantSubRoots )
+void RelayoutController::PropagateAll( Dali::Actor& actor, Dimension::Type dimension, std::vector< Dali::Actor >& topOfSubTreeStack, std::vector< Dali::Actor >& potentialRedundantSubRoots )
 {
   // Only set dirty flag if doing relayout and not already marked as dirty
   Actor& actorImpl = GetImplementation( actor );
@@ -243,9 +257,9 @@ void RelayoutController::PropagateAll( Dali::Actor& actor, Dimension dimension,
 
     // Check for dimension dependecy: width for height/height for width etc
     // Check each possible dimension and see if it is dependent on the input one
-    for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+    for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
     {
-      Dimension dimensionToCheck = static_cast< Dimension >( 1 << i );
+      Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
 
       if( actorImpl.RelayoutDependentOnDimension( dimension, dimensionToCheck ) &&
           !actorImpl.IsLayoutDirty( dimensionToCheck ) )
@@ -305,7 +319,7 @@ void RelayoutController::PropagateAll( Dali::Actor& actor, Dimension dimension,
 }
 
 
-void RelayoutController::PropagateFlags( Dali::Actor& actor, Dimension dimension )
+void RelayoutController::PropagateFlags( Dali::Actor& actor, Dimension::Type dimension )
 {
   // Only set dirty flag if doing relayout and not already marked as dirty
   Actor& actorImpl = GetImplementation( actor );
@@ -317,9 +331,9 @@ void RelayoutController::PropagateFlags( Dali::Actor& actor, Dimension dimension
 
     // Check for dimension dependecy: width for height/height for width etc
     // Check each possible dimension and see if it is dependent on the input one
-    for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+    for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
     {
-      Dimension dimensionToCheck = static_cast< Dimension >( 1 << i );
+      Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
 
       if( actorImpl.RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
       {
@@ -413,6 +427,8 @@ void RelayoutController::Relayout()
   // Only do something when requested
   if( mRelayoutFlag )
   {
+    mPerformingRelayout = true;
+
     // Clear the flag as we're now doing the relayout
     mRelayoutFlag = false;
 
@@ -469,6 +485,8 @@ void RelayoutController::Relayout()
 
       PRINT_HIERARCHY;
     }
+
+    mPerformingRelayout = false;
   }
   // should not disconnect the signal as that causes some control size negotiations to not work correctly
   // this algorithm needs more optimization as well
@@ -479,6 +497,16 @@ void RelayoutController::SetEnabled( bool enabled )
   mEnabled = enabled;
 }
 
+bool RelayoutController::IsPerformingRelayout() const
+{
+  return mPerformingRelayout;
+}
+
+void RelayoutController::SetProcessingCoreEvents( bool processingEvents )
+{
+  mProcessingCoreEvents = processingEvents;
+}
+
 void RelayoutController::FindAndZero( const RawActorList& list, const Dali::RefObject* object )
 {
   // Object has been destroyed so clear it from this list