From 8e2fde0306de39b285e405952d61907fc625a56c Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Fri, 29 May 2020 11:05:28 +0900 Subject: [PATCH] Fix actor size issue SetSize() was ignored if Actor::SetSize() and the size animation was used at the same time because the mRelayoutData->preferredSize was updated in OnNotifyDefaultPropertyAnimation(). Do not change mRelayoutData->preferredSize in OnNotifyDefaultPropertyAnimation() and keep the animated size value as a separate value while the animation is playing. Change-Id: I2de604e9e10c22e970dbc5902826cd67eb306f54 --- automated-tests/src/dali/utc-Dali-Actor.cpp | 64 +++++++++++++++---- dali/internal/event/actors/actor-impl.cpp | 99 ++++++++++++++++------------- dali/internal/event/actors/actor-impl.h | 13 ++++ 3 files changed, 117 insertions(+), 59 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index d8fe2e6..c0ae406 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -7267,36 +7267,52 @@ int utcDaliEnsureRenderWhenMakingLastActorInvisible(void) int utcDaliActorGetSizeAfterAnimation(void) { TestApplication application; - tet_infoline( "Check the actor size when an animation is finished" ); + tet_infoline( "Check the actor size before / after an animation is finished" ); - Vector3 vector( 100.0f, 100.0f, 0.0f ); + Vector3 actorSize( 100.0f, 100.0f, 0.0f ); Actor actor = Actor::New(); - actor.SetSize( vector.x, vector.y ); + actor.SetSize( actorSize ); actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); Stage::GetCurrent().Add( actor ); + // Size should be updated without rendering. + Vector3 size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + application.SendNotification(); application.Render(); - Vector3 size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); - DALI_TEST_EQUALS( size, vector, Math::MACHINE_EPSILON_0, TEST_LOCATION ); - DALI_TEST_EQUALS( vector.width, actor.GetProperty< float >( Actor::Property::SIZE_WIDTH ), TEST_LOCATION ); - DALI_TEST_EQUALS( vector.height, actor.GetProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); - DALI_TEST_EQUALS( vector.depth, actor.GetProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); + // Size and current size should be updated. + size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.width, actor.GetProperty< float >( Actor::Property::SIZE_WIDTH ), TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.height, actor.GetProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.depth, actor.GetProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); Vector3 currentSize = actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(); - DALI_TEST_EQUALS( currentSize, vector, Math::MACHINE_EPSILON_0, TEST_LOCATION ); - DALI_TEST_EQUALS( vector.width, actor.GetCurrentProperty< float >( Actor::Property::SIZE_WIDTH ), TEST_LOCATION ); - DALI_TEST_EQUALS( vector.height, actor.GetCurrentProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); - DALI_TEST_EQUALS( vector.depth, actor.GetCurrentProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); + DALI_TEST_EQUALS( currentSize, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.width, actor.GetCurrentProperty< float >( Actor::Property::SIZE_WIDTH ), TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.height, actor.GetCurrentProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); + DALI_TEST_EQUALS( actorSize.depth, actor.GetCurrentProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); + + // Set size again + actorSize = Vector3( 200.0f, 200.0f, 0.0f ); + actor.SetSize( actorSize ); - Vector3 targetValue( 10.0f, 20.0f, 30.0f ); + size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + + Vector3 targetValue( 10.0f, 20.0f, 0.0f ); Animation animation = Animation::New( 1.0f ); animation.AnimateTo( Property( actor, Actor::Property::SIZE ), targetValue ); animation.Play(); + // Size should be updated without rendering. + size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, targetValue, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + application.SendNotification(); application.Render( 1100 ); // After the animation @@ -7354,7 +7370,7 @@ int utcDaliActorGetSizeAfterAnimation(void) DALI_TEST_EQUALS( targetValue.height, actor.GetCurrentProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); DALI_TEST_EQUALS( targetValue.depth, actor.GetCurrentProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); - Vector3 offset( 10.0f, 20.0f, 30.0f ); + Vector3 offset( 10.0f, 20.0f, 0.0f ); animation.Clear(); animation.AnimateBy( Property( actor, Actor::Property::SIZE ), offset ); @@ -7423,5 +7439,25 @@ int utcDaliActorGetSizeAfterAnimation(void) DALI_TEST_EQUALS( targetValue.height, actor.GetCurrentProperty< float >( Actor::Property::SIZE_HEIGHT ), TEST_LOCATION ); DALI_TEST_EQUALS( targetValue.depth, actor.GetCurrentProperty< float >( Actor::Property::SIZE_DEPTH ), TEST_LOCATION ); + // Set size again + actorSize = Vector3( 300.0f, 300.0f, 0.0f ); + + actor.SetSize( actorSize ); + + size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + + currentSize = actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( currentSize, targetValue, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + + size = actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + + currentSize = actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(); + DALI_TEST_EQUALS( currentSize, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + END_TEST; } diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index bd1a01d..f5dfba6 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -1154,6 +1154,8 @@ void Actor::SetWidth( float width ) SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeX, width ); } + mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH; + RelayoutRequest(); } @@ -1172,6 +1174,8 @@ void Actor::SetHeight( float height ) SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeY, height ); } + mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT; + RelayoutRequest(); } @@ -1179,6 +1183,8 @@ void Actor::SetDepth( float depth ) { mTargetSize.depth = depth; + mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH; + // node is being used in a separate thread; queue a message to set the value & base value SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeZ, depth ); } @@ -1187,14 +1193,35 @@ Vector3 Actor::GetTargetSize() const { Vector3 size = mTargetSize; - // Should return preferred size if size is fixed as set by SetSize - if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) + if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH ) + { + // Should return animated size if size is animated + size.width = mAnimatedSize.width; + } + else + { + // Should return preferred size if size is fixed as set by SetSize + if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) + { + size.width = GetPreferredSize().width; + } + } + + if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT ) { - size.width = GetPreferredSize().width; + size.height = mAnimatedSize.height; + } + else + { + if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) + { + size.height = GetPreferredSize().height; + } } - if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) + + if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH ) { - size.height = GetPreferredSize().height; + size.depth = mAnimatedSize.depth; } return size; @@ -2031,9 +2058,11 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node ) mTargetSize( Vector3::ZERO ), mTargetPosition( Vector3::ZERO ), mTargetScale( Vector3::ONE ), + mAnimatedSize( Vector3::ZERO ), mName(), mSortedDepth( 0u ), mDepth( 0u ), + mUseAnimatedSize( AnimatedSizeFlag::CLEAR ), mIsRoot( ROOT_LAYER == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), @@ -2930,18 +2959,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( value.Get( mTargetSize ) ) { - if( mRelayoutData ) - { - if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.width = mTargetSize.width; - } - - if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.height = mTargetSize.height; - } - } + mAnimatedSize = mTargetSize; + mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -2953,10 +2972,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( value.Get( mTargetSize.width ) ) { - if( mRelayoutData && GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.width = mTargetSize.width; - } + mAnimatedSize.width = mTargetSize.width; + mUseAnimatedSize |= AnimatedSizeFlag::WIDTH; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -2968,10 +2985,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( value.Get( mTargetSize.height ) ) { - if( mRelayoutData && GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.height = mTargetSize.height; - } + mAnimatedSize.height = mTargetSize.height; + mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -2983,6 +2998,9 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( value.Get( mTargetSize.depth ) ) { + mAnimatedSize.depth = mTargetSize.depth; + mUseAnimatedSize |= AnimatedSizeFlag::DEPTH; + // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); } @@ -3097,18 +3115,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( AdjustValue< Vector3 >( mTargetSize, value ) ) { - if( mRelayoutData ) - { - if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.width = mTargetSize.width; - } - - if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.height = mTargetSize.height; - } - } + mAnimatedSize = mTargetSize; + mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -3120,10 +3128,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( AdjustValue< float >( mTargetSize.width, value ) ) { - if( mRelayoutData && GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.width = mTargetSize.width; - } + mAnimatedSize.width = mTargetSize.width; + mUseAnimatedSize |= AnimatedSizeFlag::WIDTH; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -3135,10 +3141,8 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( AdjustValue< float >( mTargetSize.height, value ) ) { - if( mRelayoutData && GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.height = mTargetSize.height; - } + mAnimatedSize.height = mTargetSize.height; + mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT; // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); @@ -3150,6 +3154,9 @@ void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::In { if( AdjustValue< float >( mTargetSize.depth, value ) ) { + mAnimatedSize.depth = mTargetSize.depth; + mUseAnimatedSize |= AnimatedSizeFlag::DEPTH; + // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); } @@ -4709,6 +4716,8 @@ void Actor::SetPreferredSize( const Vector2& size ) mRelayoutData->preferredSize = size; + mUseAnimatedSize = AnimatedSizeFlag::CLEAR; + RelayoutRequest(); } diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 92e6ab8..bf58f23 100755 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -1740,6 +1740,17 @@ private: }; }; + struct AnimatedSizeFlag + { + enum Type + { + CLEAR = 0, + WIDTH = 1, + HEIGHT = 2, + DEPTH = 4 + }; + }; + // Remove default constructor and copy constructor Actor() = delete; Actor( const Actor& ) = delete; @@ -1970,10 +1981,12 @@ protected: Vector3 mTargetSize; ///< Event-side storage for size (not a pointer as most actors will have a size) Vector3 mTargetPosition; ///< Event-side storage for position (not a pointer as most actors will have a position) Vector3 mTargetScale; ///< Event-side storage for scale + Vector3 mAnimatedSize; ///< Event-side storage for size animation std::string mName; ///< Name of the actor uint32_t mSortedDepth; ///< The sorted depth index. A combination of tree traversal and sibling order. int16_t mDepth; ///< The depth in the hierarchy of the actor. Only 32,767 levels of depth are supported + uint16_t mUseAnimatedSize; ///< Whether the size is animated. const bool mIsRoot : 1; ///< Flag to identify the root actor const bool mIsLayer : 1; ///< Flag to identify that this is a layer -- 2.7.4