Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animation-impl.cpp
index 972c00f..7a04d21 100644 (file)
@@ -34,8 +34,6 @@
 #include <dali/internal/event/effects/shader-effect-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 
-using namespace std;
-
 using Dali::Internal::SceneGraph::UpdateManager;
 using Dali::Internal::SceneGraph::AnimatorBase;
 using Dali::Internal::SceneGraph::Shader;
@@ -65,35 +63,29 @@ TypeAction action1( mType, Dali::Animation::ACTION_PLAY, &Animation::DoAction );
 TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
 TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
 
+const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
+const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
+const Dali::Animation::Interpolation DEFAULT_INTERPOLATION( Dali::Animation::Linear );
+
 } // anon namespace
 
 
 AnimationPtr Animation::New(float durationSeconds)
 {
-  return New(durationSeconds, Dali::Animation::Bake, Dali::Animation::Bake, Dali::AlphaFunctions::Linear);
-}
-
-AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction)
-{
-  return New(durationSeconds, endAction, destroyAction, Dali::AlphaFunctions::Linear);
-}
-
-AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction alpha)
-{
   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
   UpdateManager& updateManager = tls.GetUpdateManager();
 
   AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
 
-  AnimationPtr progress = new Animation( updateManager, playlist, durationSeconds, endAction, destroyAction, alpha );
+  AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
 
   // Second-phase construction
-  progress->Initialize();
+  animation->Initialize();
 
-  return progress;
+  return animation;
 }
 
-Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction defaultAlpha )
+Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
 : mUpdateManager( updateManager ),
   mPlaylist( playlist ),
   mAnimation( NULL ),
@@ -103,8 +95,9 @@ Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist,
   mDurationSeconds( durationSeconds ),
   mSpeedFactor(1.0f),
   mIsLooping( false ),
+  mPlayRange( Vector2(0.0f,1.0f)),
   mEndAction( endAction ),
-  mDestroyAction( destroyAction ),
+  mDisconnectAction( disconnectAction ),
   mDefaultAlpha( defaultAlpha )
 {
 }
@@ -138,7 +131,7 @@ void Animation::CreateSceneObject()
   DALI_ASSERT_DEBUG( mAnimation == NULL );
 
   // Create a new animation, temporarily owned
-  SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mIsLooping, mEndAction, mDestroyAction );
+  SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
 
   // Keep a const pointer to the animation.
   mAnimation = animation;
@@ -202,19 +195,19 @@ Dali::Animation::EndAction Animation::GetEndAction() const
   return mEndAction;
 }
 
-void Animation::SetDestroyAction(EndAction action)
+void Animation::SetDisconnectAction(EndAction action)
 {
   // Cache for public getters
-  mDestroyAction = action;
+  mDisconnectAction = action;
 
   // mAnimation is being used in a separate thread; queue a message to set the value
-  SetDestroyActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
+  SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
 }
 
-Dali::Animation::EndAction Animation::GetDestroyAction() const
+Dali::Animation::EndAction Animation::GetDisconnectAction() const
 {
   // This is not animatable; the cached value is up-to-date.
-  return mDestroyAction;
+  return mDisconnectAction;
 }
 
 void Animation::Play()
@@ -228,7 +221,7 @@ void Animation::Play()
 
 void Animation::PlayFrom( float progress )
 {
-  if( progress >= 0.0f && progress <= 1.0f )
+  if( progress >= mPlayRange.x && progress <= mPlayRange.y )
   {
     // Update the current playlist
     mPlaylist.OnPlay( *this );
@@ -512,21 +505,41 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
 
 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
 {
-  AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
+  AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, DEFAULT_INTERPOLATION );
+}
+
+void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
+{
+  AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, interpolation );
 }
 
 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
 {
-  AnimateBetween(target, keyFrames, mDefaultAlpha, period);
+  AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
+}
+
+void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
+{
+  AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
 }
 
 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
 {
-  AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
+  AnimateBetween(target, keyFrames, alpha, mDurationSeconds, DEFAULT_INTERPOLATION);
+}
+
+void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
+{
+  AnimateBetween(target, keyFrames, alpha, mDurationSeconds, interpolation);
 }
 
 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
 {
+  AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
+}
+
+void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
+{
   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
 
   ExtendDuration( period );
@@ -555,7 +568,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
                                                            target.propertyIndex,
                                                            target.componentIndex,
-                                                           KeyFrameNumberFunctor(kfCopy),
+                                                           KeyFrameNumberFunctor(kfCopy,interpolation),
                                                            alpha,
                                                            period ) );
       break;
@@ -569,7 +582,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
                                                          target.propertyIndex,
                                                          target.componentIndex,
-                                                         KeyFrameIntegerFunctor(kfCopy),
+                                                         KeyFrameIntegerFunctor(kfCopy,interpolation),
                                                          alpha,
                                                          period ) );
       break;
@@ -583,7 +596,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector2Functor(kfCopy),
+                                                             KeyFrameVector2Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -597,7 +610,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector3Functor(kfCopy),
+                                                             KeyFrameVector3Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -611,7 +624,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector4Functor(kfCopy),
+                                                             KeyFrameVector4Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -636,124 +649,6 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
   }
 }
 
-void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func )
-{
-  Animate( target, targetType, func, mDefaultAlpha, mDurationSeconds );
-}
-
-void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha )
-{
-  Animate( target, targetType, func, alpha, mDurationSeconds );
-}
-
-void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, TimePeriod period )
-{
-  Animate( target, targetType, func, mDefaultAlpha, period );
-}
-
-void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha, TimePeriod period )
-{
-  Property::Type type = target.object.GetPropertyType(target.propertyIndex);
-  if(target.componentIndex != Property::INVALID_COMPONENT_INDEX)
-  {
-    if( type == Property::VECTOR2
-        || type == Property::VECTOR3
-        || type == Property::VECTOR4 )
-    {
-      type = Property::FLOAT;
-    }
-  }
-  DALI_ASSERT_ALWAYS( type == targetType && "Animation function must match target property type" );
-
-  ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
-
-  ExtendDuration( period );
-
-  switch ( targetType )
-  {
-    case Property::BOOLEAN:
-    {
-      AddAnimatorConnector( AnimatorConnector<bool>::New(proxy,
-                                                         target.propertyIndex,
-                                                         target.componentIndex,
-                                                         AnyCast< AnimatorFunctionBool >( func ),
-                                                         alpha,
-                                                         period) );
-      break;
-    }
-
-    case Property::FLOAT:
-    {
-      AddAnimatorConnector( AnimatorConnector<float>::New(proxy,
-                                                          target.propertyIndex,
-                                                          target.componentIndex,
-                                                          AnyCast< AnimatorFunctionFloat >( func ),
-                                                          alpha,
-                                                          period) );
-      break;
-    }
-
-    case Property::INTEGER:
-    {
-      AddAnimatorConnector( AnimatorConnector<int>::New(proxy,
-                                                        target.propertyIndex,
-                                                        target.componentIndex,
-                                                        AnyCast< AnimatorFunctionInteger >( func ),
-                                                        alpha,
-                                                        period) );
-      break;
-    }
-
-    case Property::VECTOR2:
-    {
-      AddAnimatorConnector( AnimatorConnector<Vector2>::New(proxy,
-                                                            target.propertyIndex,
-                                                            target.componentIndex,
-                                                            AnyCast< AnimatorFunctionVector2 >( func ),
-                                                            alpha,
-                                                            period) );
-      break;
-    }
-
-    case Property::VECTOR3:
-    {
-      AddAnimatorConnector( AnimatorConnector<Vector3>::New(proxy,
-                                                            target.propertyIndex,
-                                                            target.componentIndex,
-                                                            AnyCast< AnimatorFunctionVector3 >( func ),
-                                                            alpha,
-                                                            period) );
-      break;
-    }
-
-    case Property::VECTOR4:
-    {
-      AddAnimatorConnector( AnimatorConnector<Vector4>::New(proxy,
-                                                            target.propertyIndex,
-                                                            target.componentIndex,
-                                                            AnyCast< AnimatorFunctionVector4 >( func ),
-                                                            alpha,
-                                                            period) );
-      break;
-    }
-
-    case Property::ROTATION:
-    {
-      AddAnimatorConnector( AnimatorConnector<Quaternion>::New(proxy,
-                                                               target.propertyIndex,
-                                                               target.componentIndex,
-                                                               AnyCast< AnimatorFunctionQuaternion >( func ),
-                                                               alpha,
-                                                               period) );
-      break;
-    }
-
-    default:
-      DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds" ); // should never come here
-      break;
-  }
-}
-
 bool Animation::HasFinished()
 {
   bool hasFinished(false);
@@ -824,6 +719,48 @@ void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
   mConnectors.PushBack( connector );
 }
 
+void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
+{
+  Animate( actor, path, forward, mDefaultAlpha, TimePeriod(0.0f,GetDuration()) );
+}
+
+void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
+{
+  Animate( actor, path, forward, alpha, TimePeriod(0.0f,GetDuration()) );
+}
+
+void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
+{
+  Animate( actor, path, forward, mDefaultAlpha, period );
+}
+
+void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
+{
+  ExtendDuration( period );
+
+  PathPtr pathCopy = Path::Clone(path);
+
+  //Position animation
+  AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
+                                                         Dali::Actor::POSITION,
+                                                         Property::INVALID_COMPONENT_INDEX,
+                                                         PathPositionFunctor( pathCopy ),
+                                                         alpha,
+                                                         period ) );
+
+  //If forward is zero, PathRotationFunctor will always return the unit quaternion
+  if( forward != Vector3::ZERO )
+  {
+    //Rotation animation
+    AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
+                                                              Dali::Actor::ROTATION,
+                                                              Property::INVALID_COMPONENT_INDEX,
+                                                              PathRotationFunctor( pathCopy, forward ),
+                                                              alpha,
+                                                              period ) );
+  }
+}
+
 void Animation::MoveBy(Actor& actor, float x, float y, float z)
 {
   MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
@@ -868,18 +805,6 @@ void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alph
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
 
-void Animation::Move(Actor& actor, AnimatorFunctionVector3 func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
-{
-  ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
-
-  AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
-                                                         Dali::Actor::POSITION,
-                                                         Property::INVALID_COMPONENT_INDEX,
-                                                         func,
-                                                         alpha,
-                                                         TimePeriod(delaySeconds, durationSeconds) ) );
-}
-
 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
 {
   RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
@@ -954,18 +879,6 @@ void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction
                                                             TimePeriod(delaySeconds, durationSeconds) ) );
 }
 
-void Animation::Rotate(Actor& actor, AnimatorFunctionQuaternion func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
-{
-  ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
-
-  AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
-                                                            Dali::Actor::ROTATION,
-                                                            Property::INVALID_COMPONENT_INDEX,
-                                                            func,
-                                                            alpha,
-                                                            TimePeriod(delaySeconds, durationSeconds) ) );
-}
-
 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
 {
   ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
@@ -1134,7 +1047,7 @@ void Animation::Resize(Actor& actor, float width, float height, AlphaFunction al
 
 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
 {
-  Vector3 targetSize( width, height, min(width, height) );
+  Vector3 targetSize( width, height, std::min(width, height) );
 
   ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
 
@@ -1206,23 +1119,23 @@ bool Animation::DoAction(BaseObject* object, const std::string& actionName, cons
   return done;
 }
 
-float Animation::GetCurrentProgress()
+void Animation::SetCurrentProgress(float progress)
 {
-  if( mAnimation )
+  if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
   {
-    return mAnimation->GetCurrentProgress();
+    // mAnimation is being used in a separate thread; queue a message to set the current progress
+    SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
   }
-
-  return 0.0f;
 }
 
-void Animation::SetCurrentProgress(float progress)
+float Animation::GetCurrentProgress()
 {
-  if( mAnimation && progress >= 0.0f && progress <= 1.0f )
+  if( mAnimation )
   {
-    // mAnimation is being used in a separate thread; queue a message to set the current progress
-    SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
+    return mAnimation->GetCurrentProgress();
   }
+
+  return 0.0f;
 }
 
 void Animation::ExtendDuration( const TimePeriod& timePeriod )
@@ -1249,6 +1162,30 @@ float Animation::GetSpeedFactor() const
   return mSpeedFactor;
 }
 
+void Animation::SetPlayRange( const Vector2& range)
+{
+  //Make sure the range specified is between 0.0 and 1.0
+  if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
+  {
+    Vector2 orderedRange( range );
+    //If the range is not in order swap values
+    if( range.x > range.y )
+    {
+      orderedRange = Vector2(range.y, range.x);
+    }
+
+    // Cache for public getters
+    mPlayRange = orderedRange;
+
+    // mAnimation is being used in a separate thread; queue a message to set play range
+    SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
+  }
+}
+
+Vector2 Animation::GetPlayRange() const
+{
+  return mPlayRange;
+}
 
 
 } // namespace Internal