#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
-Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
#endif
namespace Dali
return 0.0f; // Default
}
-void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
-{
- // Check if it needs to be negotiated
- if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
- {
- // Check that we havn't gotten into an infinite loop
- ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
- bool recursionFound = false;
- for( auto& element : recursionStack )
- {
- if( element == searchActor )
- {
- recursionFound = true;
- break;
- }
- }
-
- if( !recursionFound )
- {
- // Record the path that we have taken
- recursionStack.push_back( ActorDimensionPair( this, dimension ) );
-
- // Dimension dependency check
- for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
- {
- Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
-
- if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
- {
- NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
- }
- }
-
- // Parent dependency check
- Actor* parent = GetParent();
- if( parent && RelayoutDependentOnParent( dimension ) )
- {
- parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
- }
-
- // Children dependency check
- if( RelayoutDependentOnChildren( dimension ) )
- {
- for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
- {
- ActorPtr child = GetChildAt( i );
-
- // Only relayout child first if it is not dependent on this actor
- if( !child->RelayoutDependentOnParent( dimension ) )
- {
- child->NegotiateDimension( dimension, allocatedSize, recursionStack );
- }
- }
- }
-
- // For deriving classes
- OnCalculateRelayoutSize( dimension );
-
- // All dependencies checked, calculate the size and set negotiated flag
- const float newSize = Relayouter::ClampDimension( *this, CalculateSize( dimension, allocatedSize ), dimension );
-
- SetNegotiatedDimension( newSize, dimension );
- SetLayoutNegotiated( true, dimension );
-
- // For deriving classes
- OnLayoutNegotiated( newSize, dimension );
-
- // This actor has been successfully processed, pop it off the recursion stack
- recursionStack.pop_back();
- }
- else
- {
- // TODO: Break infinite loop
- SetLayoutNegotiated( true, dimension );
- }
- }
-}
-
-void Actor::NegotiateDimensions( const Vector2& allocatedSize )
-{
- // Negotiate all dimensions that require it
- ActorDimensionStack recursionStack;
-
- for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
- {
- const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
-
- // Negotiate
- NegotiateDimension( dimension, allocatedSize, recursionStack );
- }
-}
-
Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
{
return mRelayoutData->ApplySizeSetPolicy(*this, size);
void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
{
- // Force a size negotiation for actors that has assigned size during relayout
- // This is required as otherwise the flags that force a relayout will not
- // necessarilly be set. This will occur if the actor has already been laid out.
- // The dirty flags are then cleared. Then if the actor is added back into the
- // relayout container afterwards, the dirty flags would still be clear...
- // causing a relayout to be skipped. Here we force any actors added to the
- // container to be relayed out.
- DALI_LOG_TIMER_START( NegSizeTimer1 );
-
- if( GetUseAssignedSize(Dimension::WIDTH ) )
- {
- SetLayoutNegotiated( false, Dimension::WIDTH );
- }
- if( GetUseAssignedSize( Dimension::HEIGHT ) )
- {
- SetLayoutNegotiated( false, Dimension::HEIGHT );
- }
-
- // Do the negotiation
- NegotiateDimensions( allocatedSize );
-
- // Set the actor size
- SetNegotiatedSize( container );
-
- // Negotiate down to children
- for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
- {
- ActorPtr child = GetChildAt( i );
-
- // Forces children that have already been laid out to be relayed out
- // if they have assigned size during relayout.
- if( child->GetUseAssignedSize(Dimension::WIDTH) )
- {
- child->SetLayoutNegotiated(false, Dimension::WIDTH);
- child->SetLayoutDirty(true, Dimension::WIDTH);
- }
-
- if( child->GetUseAssignedSize(Dimension::HEIGHT) )
- {
- child->SetLayoutNegotiated(false, Dimension::HEIGHT);
- child->SetLayoutDirty(true, Dimension::HEIGHT);
- }
-
- // Only relayout if required
- if( child->RelayoutRequired() )
- {
- container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
- }
- }
- DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
+ Relayouter::NegotiateSize(*this, allocatedSize, container);
}
void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
void Actor::SetPreferredSize( const Vector2& size )
{
- EnsureRelayouter();
-
- // If valid width or height, then set the resize policy to FIXED
- // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
- // then change to FIXED as well
-
- if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
- {
- SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
- }
-
- if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
- {
- SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
- }
-
- mRelayoutData->preferredSize = size;
-
- mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
-
- RelayoutRequest();
+ EnsureRelayouter().SetPreferredSize(*this, size);
}
Vector2 Actor::GetPreferredSize() const
bool RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension );
/**
- * Negotiate sizes for a control in all dimensions
- *
- * @param[in] allocatedSize The size constraint that the control must respect
- */
- void NegotiateDimensions( const Vector2& allocatedSize );
-
- /**
- * Negotiate size for a specific dimension
- *
- * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
- * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
- * LayoutDimensionNegotiated flags being filled in on the actor.
- *
- * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
- * calculated and set as well as the LayoutDimensionNegotiated flags.
- *
- * @param[in] dimension The dimension to negotiate on
- * @param[in] allocatedSize The size constraint that the actor must respect
- */
- void NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack );
-
- /**
* @brief Calculate the size of a dimension
*
* @param[in] dimension The dimension to calculate the size for
#include <dali/public-api/math/vector3.h>
#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
+#endif
+} // unnamed namespace
+
namespace Dali
{
return false;
}
+void Actor::Relayouter::SetPreferredSize( Actor& actor, const Vector2& size )
+{
+ // If valid width or height, then set the resize policy to FIXED
+ // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
+ // then change to FIXED as well
+
+ if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
+ {
+ actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
+ }
+
+ if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
+ {
+ actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
+ }
+
+ actor.mRelayoutData->preferredSize = size;
+
+ actor.mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
+
+ actor.RelayoutRequest();
+}
+
float Actor::Relayouter::ClampDimension( const Internal::Actor& actor, float size, Dimension::Type dimension )
{
const float minSize = actor.GetMinimumSize( dimension );
return std::max( minSize, std::min( size, maxSize ) );
}
+void Actor::Relayouter::NegotiateDimension( Actor& actor, Dimension::Type dimension, const Vector2& allocatedSize, Actor::ActorDimensionStack& recursionStack )
+{
+ // Check if it needs to be negotiated
+ if( actor.IsLayoutDirty( dimension ) && !actor.IsLayoutNegotiated( dimension ) )
+ {
+ // Check that we havn't gotten into an infinite loop
+ Actor::ActorDimensionPair searchActor = Actor::ActorDimensionPair( &actor, dimension );
+ bool recursionFound = false;
+ for( auto& element : recursionStack )
+ {
+ if( element == searchActor )
+ {
+ recursionFound = true;
+ break;
+ }
+ }
+
+ if( !recursionFound )
+ {
+ // Record the path that we have taken
+ recursionStack.push_back( Actor::ActorDimensionPair( &actor, dimension ) );
+
+ // Dimension dependency check
+ for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+ {
+ Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
+
+ if( actor.RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
+ {
+ NegotiateDimension( actor, dimensionToCheck, allocatedSize, recursionStack );
+ }
+ }
+
+ // Parent dependency check
+ Actor* parent = actor.GetParent();
+ if( parent && actor.RelayoutDependentOnParent( dimension ) )
+ {
+ NegotiateDimension( *parent, dimension, allocatedSize, recursionStack );
+ }
+
+ // Children dependency check
+ if( actor.RelayoutDependentOnChildren( dimension ) )
+ {
+ for( uint32_t i = 0, count = actor.GetChildCount(); i < count; ++i )
+ {
+ ActorPtr child = actor.GetChildAt( i );
+
+ // Only relayout child first if it is not dependent on this actor
+ if( !child->RelayoutDependentOnParent( dimension ) )
+ {
+ NegotiateDimension( *child, dimension, allocatedSize, recursionStack );
+ }
+ }
+ }
+
+ // For deriving classes
+ actor.OnCalculateRelayoutSize( dimension );
+
+ // All dependencies checked, calculate the size and set negotiated flag
+ const float newSize = ClampDimension( actor, actor.CalculateSize( dimension, allocatedSize ), dimension );
+
+ actor.SetNegotiatedDimension( newSize, dimension );
+ actor.SetLayoutNegotiated( true, dimension );
+
+ // For deriving classes
+ actor.OnLayoutNegotiated( newSize, dimension );
+
+ // This actor has been successfully processed, pop it off the recursion stack
+ recursionStack.pop_back();
+ }
+ else
+ {
+ // TODO: Break infinite loop
+ actor.SetLayoutNegotiated( true, dimension );
+ }
+ }
+}
+
+void Actor::Relayouter::NegotiateDimensions(Actor& actor, const Vector2& allocatedSize)
+{
+ // Negotiate all dimensions that require it
+ ActorDimensionStack recursionStack;
+
+ for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+ {
+ const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
+
+ // Negotiate
+ NegotiateDimension(actor, dimension, allocatedSize, recursionStack);
+ }
+}
+
+void Actor::Relayouter::NegotiateSize(Actor& actor, const Vector2& allocatedSize, RelayoutContainer& container)
+{
+ // Force a size negotiation for actors that has assigned size during relayout
+ // This is required as otherwise the flags that force a relayout will not
+ // necessarilly be set. This will occur if the actor has already been laid out.
+ // The dirty flags are then cleared. Then if the actor is added back into the
+ // relayout container afterwards, the dirty flags would still be clear...
+ // causing a relayout to be skipped. Here we force any actors added to the
+ // container to be relayed out.
+ DALI_LOG_TIMER_START( NegSizeTimer1 );
+
+ if( actor.GetUseAssignedSize(Dimension::WIDTH ) )
+ {
+ actor.SetLayoutNegotiated( false, Dimension::WIDTH );
+ }
+ if( actor.GetUseAssignedSize( Dimension::HEIGHT ) )
+ {
+ actor.SetLayoutNegotiated( false, Dimension::HEIGHT );
+ }
+
+ // Do the negotiation
+ NegotiateDimensions(actor, allocatedSize);
+
+ // Set the actor size
+ actor.SetNegotiatedSize( container );
+
+ // Negotiate down to children
+ for( uint32_t i = 0, count = actor.GetChildCount(); i < count; ++i )
+ {
+ ActorPtr child = actor.GetChildAt( i );
+
+ // Forces children that have already been laid out to be relayed out
+ // if they have assigned size during relayout.
+ if( child->GetUseAssignedSize(Dimension::WIDTH) )
+ {
+ child->SetLayoutNegotiated(false, Dimension::WIDTH);
+ child->SetLayoutDirty(true, Dimension::WIDTH);
+ }
+
+ if( child->GetUseAssignedSize(Dimension::HEIGHT) )
+ {
+ child->SetLayoutNegotiated(false, Dimension::HEIGHT);
+ child->SetLayoutDirty(true, Dimension::HEIGHT);
+ }
+
+ // Only relayout if required
+ if( child->RelayoutRequired() )
+ {
+ container.Add( Dali::Actor( child.Get() ), actor.mTargetSize.GetVectorXY() );
+ }
+ }
+ DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
+}
+
} // namespace Internal
} // namespace Dali
/// @copydoc Actor::IsLayoutDirty
bool IsLayoutDirty( Dimension::Type dimension ) const;
+ /// @copydoc Actor::SetPreferredSize
+ /// @actor[in] actor The Actor whose preferred size we wish to set
+ void SetPreferredSize( Actor& actor, const Vector2& size );
+
/**
* @brief Clamp a dimension given the relayout constraints on given actor
*
*/
static float ClampDimension( const Internal::Actor& actor, float size, Dimension::Type dimension );
+ /**
+ * Negotiate size for a specific dimension
+ *
+ * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
+ * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
+ * LayoutDimensionNegotiated flags being filled in on the actor.
+ *
+ * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
+ * calculated and set as well as the LayoutDimensionNegotiated flags.
+ *
+ * @param[in] actor The actor whose dimension we are negotiating
+ * @param[in] dimension The dimension to negotiate on
+ * @param[in] allocatedSize The size constraint that the actor must respect
+ */
+ static void NegotiateDimension(Actor& actor, Dimension::Type dimension, const Vector2& allocatedSize, Actor::ActorDimensionStack& recursionStack);
+
+ /**
+ * Negotiate sizes for a control in all dimensions
+ *
+ * @param[in] actor The actor whose dimensions we are negotiating
+ * @param[in] allocatedSize The size constraint that the control must respect
+ */
+ static void NegotiateDimensions(Actor& actor, const Vector2& allocatedSize);
+
+ /**
+ * @brief Called by the RelayoutController to negotiate the size of an actor.
+ *
+ * The size allocated by the the algorithm is passed in which the
+ * actor must adhere to. A container is passed in as well which
+ * the actor should populate with actors it has not / or does not
+ * need to handle in its size negotiation.
+ *
+ * @param[in] actor The actor whose size we are negotiating
+ * @param[in] size The allocated size.
+ * @param[in,out] container The container that holds actors that are fed back into the
+ * RelayoutController algorithm.
+ */
+ static void NegotiateSize(Actor& actor, const Vector2& allocatedSize, RelayoutContainer& container);
+
public:
ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies