From 1b75ecbe319aeba104e19180ea32da44f4ff8e8e Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Fri, 28 Apr 2017 17:41:58 +0100 Subject: [PATCH] Fix the USE_ASSIGNED_SIZE resize policy to not overwrite the actor's original policy OnRelayout is called during the relayout process, and if the actor has calculated the size of child actors it will add them to the relayout container with their desired size and set the ResizePolicy::USE_ASSIGNED_SIZE resize policy on them. However, by doing this, it overwrites the original resize policy of the actor, so the size calculation of the actor could be incorrect during any further relayout process. This patch fixes the above issue by setting an internal flag instead of overwriting the original resize policy in order to notify the size negotiation algorithm to assign the size of child actors as calculated during OnRelayout. Change-Id: Ib1b2e4cfc2a39cfd653e64291e86508351d15606 --- dali/internal/event/actors/actor-impl.cpp | 65 +++++++++++++++++++--- dali/internal/event/actors/actor-impl.h | 18 ++++++ .../size-negotiation/relayout-controller-impl.cpp | 3 + 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index ccbf532..53e0c75 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -101,6 +101,7 @@ struct Actor::RelayoutData for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i ) { resizePolicies[ i ] = ResizePolicy::DEFAULT; + useAssignedSize[ i ] = false; negotiatedDimensions[ i ] = 0.0f; dimensionNegotiated[ i ] = false; dimensionDirty[ i ] = false; @@ -112,6 +113,7 @@ struct Actor::RelayoutData } ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies + bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies @@ -1293,7 +1295,15 @@ void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimensio { if( dimension & ( 1 << i ) ) { - mRelayoutData->resizePolicies[ i ] = policy; + if ( policy == ResizePolicy::USE_ASSIGNED_SIZE ) + { + mRelayoutData->useAssignedSize[ i ] = true; + } + else + { + mRelayoutData->resizePolicies[ i ] = policy; + mRelayoutData->useAssignedSize[ i ] = false; + } } } @@ -1328,7 +1338,14 @@ ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const { if( ( dimension & ( 1 << i ) ) ) { - return mRelayoutData->resizePolicies[ i ]; + if( mRelayoutData->useAssignedSize[ i ] ) + { + return ResizePolicy::USE_ASSIGNED_SIZE; + } + else + { + return mRelayoutData->resizePolicies[ i ]; + } } } } @@ -4202,13 +4219,13 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont // 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. - if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE) + if( GetUseAssignedSize(Dimension::WIDTH ) ) { - SetLayoutNegotiated(false, Dimension::WIDTH); + SetLayoutNegotiated( false, Dimension::WIDTH ); } - if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE) + if( GetUseAssignedSize( Dimension::HEIGHT ) ) { - SetLayoutNegotiated(false, Dimension::HEIGHT); + SetLayoutNegotiated( false, Dimension::HEIGHT ); } // Do the negotiation @@ -4226,12 +4243,13 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont // Forces children that have already been laid out to be relayed out // if they have assigned size during relayout. - if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE) + if( child->GetUseAssignedSize(Dimension::WIDTH) ) { child->SetLayoutNegotiated(false, Dimension::WIDTH); child->SetLayoutDirty(true, Dimension::WIDTH); } - if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE) + + if( child->GetUseAssignedSize(Dimension::HEIGHT) ) { child->SetLayoutNegotiated(false, Dimension::HEIGHT); child->SetLayoutDirty(true, Dimension::HEIGHT); @@ -4245,6 +4263,37 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont } } +void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension ) +{ + if( mRelayoutData ) + { + for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + { + if( dimension & ( 1 << i ) ) + { + mRelayoutData->useAssignedSize[ i ] = use; + } + } + } +} + +bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const +{ + if ( mRelayoutData ) + { + // If more than one dimension is requested, just return the first one found + for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + { + if( dimension & ( 1 << i ) ) + { + return mRelayoutData->useAssignedSize[ i ]; + } + } + } + + return false; +} + void Actor::RelayoutRequest( Dimension::Type dimension ) { Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get(); diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 5e9b6ab..86a7654 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -868,6 +868,24 @@ public: void NegotiateSize( const Vector2& size, RelayoutContainer& container ); /** + * @brief Set whether size negotiation should use the assigned size of the actor + * during relayout for the given dimension(s) + * + * @param[in] use Whether the assigned size of the actor should be used + * @param[in] dimension The dimension(s) to set. Can be a bitfield of multiple dimensions + */ + void SetUseAssignedSize( bool use, Dimension::Type dimension = Dimension::ALL_DIMENSIONS ); + + /** + * @brief Returns whether size negotiation should use the assigned size of the actor + * during relayout for a single dimension + * + * @param[in] dimension The dimension to get + * @return Return whether the assigned size of the actor should be used. If more than one dimension is requested, just return the first one found + */ + bool GetUseAssignedSize( Dimension::Type dimension ) const; + + /** * @copydoc Dali::Actor::SetResizePolicy() */ void SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension = Dimension::ALL_DIMENSIONS ); diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp index eebc981..0b3ec2c 100644 --- a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp +++ b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp @@ -492,6 +492,9 @@ void RelayoutController::Relayout() // has to fill with all the actors it has not done any size negotiation for. actorImpl.NegotiateSize( size, *mRelayoutStack ); + + // Reset the flag so that size negotiation will respect the actor's original resize policy + actorImpl.SetUseAssignedSize( false ); } } -- 2.7.4