Support multiple transitions for a Control.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / transition / transition-base-impl.cpp
index 42fb10d..5ee926e 100644 (file)
@@ -36,8 +36,20 @@ namespace Internal
 {
 namespace
 {
+static constexpr float OPACITY_TRANSPARENT = 0.0f;
+
 const Dali::AlphaFunction DEFAULT_ALPHA_FUNCTION(Dali::AlphaFunction::DEFAULT);
 
+const Property::Map PROPERTY_MAP_INDEPENDENT_CONTROL{
+  {Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER},
+  {Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER},
+  {Dali::Actor::Property::POSITION_USES_ANCHOR_POINT, true},
+  {Dali::Actor::Property::INHERIT_POSITION, false},
+  {Dali::Actor::Property::INHERIT_ORIENTATION, false},
+  {Dali::Actor::Property::INHERIT_SCALE, false},
+  {Dali::Actor::Property::COLOR_MODE, Dali::ColorMode::USE_OWN_COLOR},
+};
+
 Property::Map GetOriginalProperties(Dali::Toolkit::Control control)
 {
   Property::Map propertyMap;
@@ -104,7 +116,9 @@ TransitionBase::TransitionBase()
 : mAlphaFunction(DEFAULT_ALPHA_FUNCTION),
   mTimePeriod(TimePeriod(0.0f)),
   mTransitionWithChild(false),
-  mMoveTargetChildren(false)
+  mMoveTargetChildren(false),
+  mIsAppearingTransition(true),
+  mIsPairTransition(false)
 {
 }
 
@@ -167,6 +181,20 @@ void TransitionBase::Play()
     return;
   }
 
+  // Set world transform and color to the target control to make it independent of the parent control and its transition.
+  // The properties will be returned at the TransitionFinished() method.
+  Matrix     targetWorldTransform = GetWorldTransform(mTarget);
+  Vector3    targetPosition, targetScale;
+  Quaternion targetOrientation;
+  targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale);
+  Vector4 targetColor = GetWorldColor(mTarget);
+
+  mTarget.SetProperties(PROPERTY_MAP_INDEPENDENT_CONTROL);
+  mTarget[Dali::Actor::Property::POSITION]    = targetPosition;
+  mTarget[Dali::Actor::Property::SCALE]       = targetScale;
+  mTarget[Dali::Actor::Property::ORIENTATION] = targetOrientation;
+  mTarget[Dali::Actor::Property::COLOR]       = targetColor;
+
   OnPlay();
 
   SetAnimation();
@@ -182,29 +210,34 @@ void TransitionBase::SetAnimation()
 
   for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
   {
-    Property::Value* initialValuePointer = mInitialPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
     Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
     if(finishValue)
     {
-      Property::Value initialValue = mStartPropertyMap.GetValue(i);
-      if(initialValuePointer)
+      // If this transition is appearing transition, this property keeps start value during delay.
+      // If multiple transitions are applied to this Control and others run before this transition,
+      // this property should keep start value until this transition starts.
+      if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
       {
-        initialValue = *initialValuePointer;
+        mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
       }
-      AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, initialValue, mStartPropertyMap.GetValue(i), *finishValue);
+      AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
     }
   }
 }
 
-void TransitionBase::AnimateBetween(Dali::Toolkit::Control target, Property::Index index, Property::Value initialValue, Property::Value sourceValue, Property::Value destinationValue)
+void TransitionBase::AnimateBetween(Dali::Toolkit::Control target, Property::Index index, Property::Value sourceValue, Property::Value destinationValue)
 {
   if(mAnimation)
   {
-    if(mTimePeriod.delaySeconds>0.0f)
+    // To make each property keep start value during delay time.
+    // When this transition is not Pair transition, it is not required.
+    // (For appearing transition, the mTarget control will not be shown during delay time,
+    //  For disapplearing transition, the property of mTarget control keeps current value during delay time)
+    if(IsPairTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
     {
       Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
-      initialKeyframes.Add(0.0f, initialValue);
-      initialKeyframes.Add(1.0f, initialValue);
+      initialKeyframes.Add(0.0f, sourceValue);
+      initialKeyframes.Add(1.0f, sourceValue);
       mAnimation.AnimateBetween(Property(target, index), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
     }
     Dali::KeyFrames keyframes = Dali::KeyFrames::New();
@@ -218,10 +251,11 @@ void TransitionBase::CopyTarget()
 {
   mCopiedActor = Dali::Actor::New();
   mTarget.GetParent().Add(mCopiedActor);
+
   mCopiedActor[Dali::DevelActor::Property::SIBLING_ORDER] = static_cast<int32_t>(mTarget[Dali::DevelActor::Property::SIBLING_ORDER]) + 1;
-  for(uint32_t i = 0; i < mTarget.GetChildCount(); ++i)
+  while(mTarget.GetChildCount() > 0)
   {
-    Dali::Actor child = mTarget.GetChildAt(i);
+    Dali::Actor child = mTarget.GetChildAt(0);
     Dali::DevelActor::SwitchParent(child, mCopiedActor);
   }
 
@@ -237,9 +271,9 @@ void TransitionBase::TransitionFinished()
   mTarget.SetProperties(mOriginalPropertyMap);
   if(mMoveTargetChildren)
   {
-    for(uint32_t i = 0; i < mCopiedActor.GetChildCount(); ++i)
+    while(mCopiedActor.GetChildCount() > 0)
     {
-      Dali::Actor child = mCopiedActor.GetChildAt(i);
+      Dali::Actor child = mCopiedActor.GetChildAt(0);
       Dali::DevelActor::SwitchParent(child, mTarget);
     }
     mCopiedActor.Unparent();