Fix actor size issue 25/234825/3
authorHeeyong Song <heeyong.song@samsung.com>
Fri, 29 May 2020 02:05:28 +0000 (11:05 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 1 Jun 2020 04:34:26 +0000 (13:34 +0900)
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
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h

index d8fe2e6..c0ae406 100644 (file)
@@ -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;
 }
index bd1a01d..f5dfba6 100644 (file)
@@ -1154,6 +1154,8 @@ void Actor::SetWidth( float width )
     SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width );
   }
 
+  mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
+
   RelayoutRequest();
 }
 
@@ -1172,6 +1174,8 @@ void Actor::SetHeight( float height )
     SceneGraph::NodeTransformComponentMessage<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::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<Vector3>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::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();
 }
 
index 92e6ab8..bf58f23 100755 (executable)
@@ -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