Update the preferred size after relayoutting 46/265646/3
authorHeeyong Song <heeyong.song@samsung.com>
Tue, 26 Oct 2021 05:19:58 +0000 (14:19 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 28 Oct 2021 07:13:48 +0000 (16:13 +0900)
It should be used in the next relayoutting

Change-Id: I3342de587942a9123ebb31cba4eac35c4e2b65ca

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-property-handler.cpp
dali/internal/event/actors/actor-relayouter.cpp
dali/internal/event/actors/actor-relayouter.h

index 66f2cbb..1d04226 100644 (file)
@@ -8065,6 +8065,139 @@ int utcDaliActorGetSizeAfterAnimation(void)
   END_TEST;
 }
 
+int utcDaliActorRelayoutAndAnimation(void)
+{
+  TestApplication application;
+  tet_infoline("Check the actor size when relayoutting and playing animation");
+
+  Vector3 parentSize(300.0f, 300.0f, 0.0f);
+  Vector3 actorSize(100.0f, 100.0f, 0.0f);
+
+  {
+    Actor parentA = Actor::New();
+    parentA.SetProperty(Actor::Property::SIZE, parentSize);
+    parentA.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(parentA);
+
+    Actor parentB = Actor::New();
+    parentB.SetProperty(Actor::Property::SIZE, parentSize);
+    parentB.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(parentB);
+
+    Actor actor = Actor::New();
+    actor.SetProperty(Actor::Property::SIZE, actorSize);
+    actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    parentA.Add(actor);
+
+    Vector3 size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION);
+
+    Vector3 targetValue(200.0f, 200.0f, 0.0f);
+
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateTo(Property(actor, Actor::Property::SIZE), targetValue);
+    animation.Play();
+
+    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
+
+    // Size and current size should be updated.
+    size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, targetValue, Math::MACHINE_EPSILON_0, TEST_LOCATION);
+
+    Vector3 currentSize = actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(currentSize, targetValue, Math::MACHINE_EPSILON_0, TEST_LOCATION);
+
+    // Trigger relayout
+    parentB.Add(actor);
+
+    application.SendNotification();
+    application.Render();
+
+    // Size and current size should be same.
+    size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, targetValue, 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);
+
+    actor.Unparent();
+    parentA.Unparent();
+    parentB.Unparent();
+  }
+
+  {
+    Actor parentA = Actor::New();
+    parentA.SetProperty(Actor::Property::SIZE, parentSize);
+    parentA.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(parentA);
+
+    Actor parentB = Actor::New();
+    parentB.SetProperty(Actor::Property::SIZE, parentSize);
+    parentB.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(parentB);
+
+    Actor actor = Actor::New();
+    actor.SetProperty(Actor::Property::SIZE, actorSize);
+    actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+    parentA.Add(actor);
+
+    Vector3 size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, actorSize, 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);
+
+    Vector3 currentSize = actor.GetCurrentProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(currentSize, actorSize, Math::MACHINE_EPSILON_0, TEST_LOCATION);
+
+    Vector3 targetValue(200.0f, 200.0f, 0.0f);
+
+    // Make an animation
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateTo(Property(actor, Actor::Property::SIZE), targetValue);
+    animation.Play();
+
+    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
+
+    // Size and current size should be updated.
+    size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, targetValue, 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);
+
+    // Trigger relayout
+    parentB.Add(actor);
+
+    application.SendNotification();
+    application.Render();
+
+    // Size and current size should be same.
+    size = actor.GetProperty(Actor::Property::SIZE).Get<Vector3>();
+    DALI_TEST_EQUALS(size, targetValue, 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);
+
+    actor.Unparent();
+    parentA.Unparent();
+    parentB.Unparent();
+  }
+
+  END_TEST;
+}
+
 int utcDaliActorPartialUpdate(void)
 {
   TestApplication application(
index 1057dea..6247000 100644 (file)
@@ -758,6 +758,18 @@ void Actor::SetSizeInternal(const Vector3& size)
   {
     mTargetSize = size;
 
+    // Update the preferred size after relayoutting
+    // It should be used in the next relayoutting
+    if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH && mRelayoutData)
+    {
+      mRelayoutData->preferredSize.width = mAnimatedSize.width;
+    }
+
+    if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT && mRelayoutData)
+    {
+      mRelayoutData->preferredSize.height = mAnimatedSize.height;
+    }
+
     // node is being used in a separate thread; queue a message to set the value & base value
     SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize);
 
@@ -2064,6 +2076,8 @@ void Actor::SetNegotiatedSize(RelayoutContainer& container)
     Dali::Actor handle(this);
     mOnRelayoutSignal.Emit(handle);
   }
+
+  mRelayoutData->relayoutRequested = false;
 }
 
 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
@@ -2091,6 +2105,11 @@ void Actor::RelayoutRequest(Dimension::Type dimension)
   {
     Dali::Actor self(this);
     relayoutController->RequestRelayout(self, dimension);
+
+    if(mRelayoutData)
+    {
+      mRelayoutData->relayoutRequested = true;
+    }
   }
 }
 
index 648b135..cce13c8 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/devel-api/actors/actor-devel.h>
 
 #include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/actors/actor-relayouter.h>
 #include <dali/internal/event/common/property-helper.h>
 #include <dali/internal/update/nodes/node-declarations.h>
 #include <dali/internal/update/nodes/node-messages.h>
@@ -801,6 +802,12 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize    = actor.mTargetSize;
             actor.mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.width  = actor.mAnimatedSize.width;
+              actor.mRelayoutData->preferredSize.height = actor.mAnimatedSize.height;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
@@ -814,6 +821,11 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize.width = actor.mTargetSize.width;
             actor.mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.width = actor.mAnimatedSize.width;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
@@ -827,6 +839,11 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize.height = actor.mTargetSize.height;
             actor.mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.height = actor.mAnimatedSize.height;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
@@ -957,6 +974,12 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize    = actor.mTargetSize;
             actor.mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.width  = actor.mAnimatedSize.width;
+              actor.mRelayoutData->preferredSize.height = actor.mAnimatedSize.height;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
@@ -970,6 +993,11 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize.width = actor.mTargetSize.width;
             actor.mUseAnimatedSize |= AnimatedSizeFlag::WIDTH;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.width = actor.mAnimatedSize.width;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
@@ -983,6 +1011,11 @@ void Actor::PropertyHandler::OnNotifyDefaultPropertyAnimation(Internal::Actor& a
             actor.mAnimatedSize.height = actor.mTargetSize.height;
             actor.mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT;
 
+            if(actor.mRelayoutData && !actor.mRelayoutData->relayoutRequested)
+            {
+              actor.mRelayoutData->preferredSize.height = actor.mAnimatedSize.height;
+            }
+
             // Notify deriving classes
             actor.OnSizeAnimation(animation, actor.mTargetSize);
           }
index 8cde6d5..4103c5c 100644 (file)
@@ -40,7 +40,8 @@ Actor::Relayouter::Relayouter()
   preferredSize(DEFAULT_PREFERRED_SIZE),
   sizeSetPolicy(DEFAULT_SIZE_SCALE_POLICY),
   relayoutEnabled(false),
-  insideRelayout(false)
+  insideRelayout(false),
+  relayoutRequested(false)
 {
   // Set size negotiation defaults
   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
index 69131bb..364e92c 100644 (file)
@@ -167,8 +167,9 @@ public:
 
   SizeScalePolicy::Type sizeSetPolicy : 3; ///< Policy to apply when setting size. Enough room for the enum
 
-  bool relayoutEnabled : 1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
-  bool insideRelayout : 1;  ///< Locking flag to prevent recursive relayouts on size set
+  bool relayoutEnabled : 1;   ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true)
+  bool insideRelayout : 1;    ///< Locking flag to prevent recursive relayouts on size set
+  bool relayoutRequested : 1; ///< Whether the relayout is requested.
 };
 
 } // namespace Internal