[Tizen] (Animation) Ensure AnimateBy updates the cached event-side properties 76/130276/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 19 May 2017 10:30:29 +0000 (11:30 +0100)
committerHeeyong Song <heeyong.song@samsung.com>
Sat, 20 May 2017 04:20:36 +0000 (13:20 +0900)
Change-Id: If7c50137a729f6072f39c8768a127326ca56d389

automated-tests/src/dali/utc-Dali-Animation.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-impl.h
dali/internal/event/common/object-impl.cpp
dali/internal/event/common/object-impl.h
dali/internal/event/common/property-metadata.cpp
dali/internal/event/common/property-metadata.h
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/event/render-tasks/render-task-impl.h

index 980c108..3789489 100644 (file)
@@ -2806,6 +2806,9 @@ int UtcDaliAnimationAnimateByBooleanP(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< bool >( index ), finalValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -3099,6 +3102,9 @@ int UtcDaliAnimationAnimateByFloatP(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< float >( index ), targetValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -3333,6 +3339,9 @@ int UtcDaliAnimationAnimateByIntegerP(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< int >( index ), targetValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -3567,6 +3576,9 @@ int UtcDaliAnimationAnimateByVector2P(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Vector2 >( index ), targetValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -3802,6 +3814,9 @@ int UtcDaliAnimationAnimateByVector3P(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( index ), targetValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -4038,6 +4053,9 @@ int UtcDaliAnimationAnimateByVector4P(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Vector4 >( index ), targetValue, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -4274,6 +4292,9 @@ int UtcDaliAnimationAnimateByActorPositionP(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), targetPosition, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -4489,6 +4510,9 @@ int UtcDaliAnimationAnimateByActorOrientationP1(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Quaternion >( Actor::Property::ORIENTATION ), Quaternion(relativeRotationRadians, Vector3::YAXIS), TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
@@ -4791,6 +4815,9 @@ int UtcDaliAnimationAnimateByActorScaleP(void)
   // Start the animation
   animation.Play();
 
+  // Target value should be retrievable straight away
+  DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::SCALE ), targetScale, TEST_LOCATION );
+
   bool signalReceived(false);
   AnimationFinishCheck finishCheck(signalReceived);
   animation.FinishedSignal().Connect(&application, finishCheck);
index 8df598e..c6a3efe 100644 (file)
@@ -416,6 +416,20 @@ void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, Devel
   }
 }
 
+/// Helper to adjust the current value of a variable from the given property-value
+/// Returns true if value adjusted, false otherwise
+template< typename PropertyType >
+inline bool AdjustValue( PropertyType& currentValue, const Property::Value& value )
+{
+  PropertyType relativeValue;
+  if( value.Get( relativeValue ) )
+  {
+    currentValue += relativeValue;
+    return true;
+  }
+  return false;
+}
+
 } // unnamed namespace
 
 ActorPtr Actor::New()
@@ -3242,145 +3256,299 @@ Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) c
   return value;
 }
 
-void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value )
+void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType )
 {
-  switch( index )
+  if( propertyChangeType == Object::PropertyChange::SET )
   {
-    case Dali::Actor::Property::SIZE:
+    switch( index )
     {
-      if( value.Get( mTargetSize ) )
+      case Dali::Actor::Property::SIZE:
       {
-        // Notify deriving classes
-        OnSizeAnimation( animation, mTargetSize );
+        if( value.Get( mTargetSize ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
       }
-      break;
-    }
 
-    case Dali::Actor::Property::SIZE_WIDTH:
-    {
-      if( value.Get( mTargetSize.width ) )
+      case Dali::Actor::Property::SIZE_WIDTH:
       {
-        // Notify deriving classes
-        OnSizeAnimation( animation, mTargetSize );
+        if( value.Get( mTargetSize.width ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
       }
-      break;
-    }
 
-    case Dali::Actor::Property::SIZE_HEIGHT:
-    {
-      if( value.Get( mTargetSize.height ) )
+      case Dali::Actor::Property::SIZE_HEIGHT:
       {
-        // Notify deriving classes
-        OnSizeAnimation( animation, mTargetSize );
+        if( value.Get( mTargetSize.height ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
       }
-      break;
-    }
 
-    case Dali::Actor::Property::SIZE_DEPTH:
-    {
-      if( value.Get( mTargetSize.depth ) )
+      case Dali::Actor::Property::SIZE_DEPTH:
       {
-        // Notify deriving classes
-        OnSizeAnimation( animation, mTargetSize );
+        if( value.Get( mTargetSize.depth ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
       }
-      break;
-    }
 
-    case Dali::Actor::Property::POSITION:
-    {
-      value.Get( mTargetPosition );
-      break;
-    }
+      case Dali::Actor::Property::POSITION:
+      {
+        value.Get( mTargetPosition );
+        break;
+      }
 
-    case Dali::Actor::Property::POSITION_X:
-    {
-      value.Get( mTargetPosition.x );
-      break;
-    }
+      case Dali::Actor::Property::POSITION_X:
+      {
+        value.Get( mTargetPosition.x );
+        break;
+      }
 
-    case Dali::Actor::Property::POSITION_Y:
-    {
-      value.Get( mTargetPosition.y );
-      break;
-    }
+      case Dali::Actor::Property::POSITION_Y:
+      {
+        value.Get( mTargetPosition.y );
+        break;
+      }
 
-    case Dali::Actor::Property::POSITION_Z:
-    {
-      value.Get( mTargetPosition.z );
-      break;
-    }
+      case Dali::Actor::Property::POSITION_Z:
+      {
+        value.Get( mTargetPosition.z );
+        break;
+      }
 
-    case Dali::Actor::Property::ORIENTATION:
-    {
-      value.Get( mTargetOrientation );
-      break;
-    }
+      case Dali::Actor::Property::ORIENTATION:
+      {
+        value.Get( mTargetOrientation );
+        break;
+      }
 
-    case Dali::Actor::Property::SCALE:
-    {
-      value.Get( mTargetScale );
-      break;
-    }
+      case Dali::Actor::Property::SCALE:
+      {
+        value.Get( mTargetScale );
+        break;
+      }
 
-    case Dali::Actor::Property::SCALE_X:
-    {
-      value.Get( mTargetScale.x );
-      break;
-    }
+      case Dali::Actor::Property::SCALE_X:
+      {
+        value.Get( mTargetScale.x );
+        break;
+      }
 
-    case Dali::Actor::Property::SCALE_Y:
-    {
-      value.Get( mTargetScale.y );
-      break;
-    }
+      case Dali::Actor::Property::SCALE_Y:
+      {
+        value.Get( mTargetScale.y );
+        break;
+      }
 
-    case Dali::Actor::Property::SCALE_Z:
-    {
-      value.Get( mTargetScale.z );
-      break;
-    }
+      case Dali::Actor::Property::SCALE_Z:
+      {
+        value.Get( mTargetScale.z );
+        break;
+      }
 
-    case Dali::Actor::Property::VISIBLE:
-    {
-      SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
-      break;
-    }
+      case Dali::Actor::Property::VISIBLE:
+      {
+        SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
+        break;
+      }
 
-    case Dali::Actor::Property::COLOR:
-    {
-      value.Get( mTargetColor );
-      break;
-    }
+      case Dali::Actor::Property::COLOR:
+      {
+        value.Get( mTargetColor );
+        break;
+      }
 
-    case Dali::Actor::Property::COLOR_RED:
-    {
-      value.Get( mTargetColor.r );
-      break;
-    }
+      case Dali::Actor::Property::COLOR_RED:
+      {
+        value.Get( mTargetColor.r );
+        break;
+      }
 
-    case Dali::Actor::Property::COLOR_GREEN:
-    {
-      value.Get( mTargetColor.g );
-      break;
-    }
+      case Dali::Actor::Property::COLOR_GREEN:
+      {
+        value.Get( mTargetColor.g );
+        break;
+      }
 
-    case Dali::Actor::Property::COLOR_BLUE:
-    {
-      value.Get( mTargetColor.b );
-      break;
-    }
+      case Dali::Actor::Property::COLOR_BLUE:
+      {
+        value.Get( mTargetColor.b );
+        break;
+      }
 
-    case Dali::Actor::Property::COLOR_ALPHA:
-    case Dali::DevelActor::Property::OPACITY:
-    {
-      value.Get( mTargetColor.a );
-      break;
-    }
+      case Dali::Actor::Property::COLOR_ALPHA:
+      case Dali::DevelActor::Property::OPACITY:
+      {
+        value.Get( mTargetColor.a );
+        break;
+      }
 
-    default:
+      default:
+      {
+        // Not an animatable property. Do nothing.
+        break;
+      }
+    }
+  }
+  else
+  {
+    switch( index )
     {
-      // Not an animatable property. Do nothing.
-      break;
+      case Dali::Actor::Property::SIZE:
+      {
+        if( AdjustValue< Vector3 >( mTargetSize, value ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::SIZE_WIDTH:
+      {
+        if( AdjustValue< float >( mTargetSize.width, value ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::SIZE_HEIGHT:
+      {
+        if( AdjustValue< float >( mTargetSize.height, value ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::SIZE_DEPTH:
+      {
+        if( AdjustValue< float >( mTargetSize.depth, value ) )
+        {
+          // Notify deriving classes
+          OnSizeAnimation( animation, mTargetSize );
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::POSITION:
+      {
+        AdjustValue< Vector3 >( mTargetPosition, value );
+        break;
+      }
+
+      case Dali::Actor::Property::POSITION_X:
+      {
+        AdjustValue< float >( mTargetPosition.x, value );
+        break;
+      }
+
+      case Dali::Actor::Property::POSITION_Y:
+      {
+        AdjustValue< float >( mTargetPosition.y, value );
+        break;
+      }
+
+      case Dali::Actor::Property::POSITION_Z:
+      {
+        AdjustValue< float >( mTargetPosition.z, value );
+        break;
+      }
+
+      case Dali::Actor::Property::ORIENTATION:
+      {
+        Quaternion relativeValue;
+        if( value.Get( relativeValue ) )
+        {
+          mTargetOrientation *= relativeValue;
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::SCALE:
+      {
+        AdjustValue< Vector3 >( mTargetScale, value );
+        break;
+      }
+
+      case Dali::Actor::Property::SCALE_X:
+      {
+        AdjustValue< float >( mTargetScale.x, value );
+        break;
+      }
+
+      case Dali::Actor::Property::SCALE_Y:
+      {
+        AdjustValue< float >( mTargetScale.y, value );
+        break;
+      }
+
+      case Dali::Actor::Property::SCALE_Z:
+      {
+        AdjustValue< float >( mTargetScale.z, value );
+        break;
+      }
+
+      case Dali::Actor::Property::VISIBLE:
+      {
+        bool relativeValue = false;
+        if( value.Get( relativeValue ) )
+        {
+          bool visible = mVisible || relativeValue;
+          SetVisibleInternal( visible, SendMessage::FALSE );
+        }
+        break;
+      }
+
+      case Dali::Actor::Property::COLOR:
+      {
+        AdjustValue< Vector4 >( mTargetColor, value );
+        break;
+      }
+
+      case Dali::Actor::Property::COLOR_RED:
+      {
+        AdjustValue< float >( mTargetColor.r, value );
+        break;
+      }
+
+      case Dali::Actor::Property::COLOR_GREEN:
+      {
+        AdjustValue< float >( mTargetColor.g, value );
+        break;
+      }
+
+      case Dali::Actor::Property::COLOR_BLUE:
+      {
+        AdjustValue< float >( mTargetColor.b, value );
+        break;
+      }
+
+      case Dali::Actor::Property::COLOR_ALPHA:
+      case Dali::DevelActor::Property::OPACITY:
+      {
+        AdjustValue< float >( mTargetColor.a, value );
+        break;
+      }
+
+      default:
+      {
+        // Not an animatable property. Do nothing.
+        break;
+      }
     }
   }
 }
index 59e23d0..51906d5 100644 (file)
@@ -1656,7 +1656,7 @@ public:
   /**
    * @copydoc Dali::Internal::Object::OnNotifyDefaultPropertyAnimation()
    */
-  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value );
+  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType );
 
   /**
    * @copydoc Dali::Internal::Object::GetPropertyOwner()
index 2191e2a..2b0bf2e 100644 (file)
@@ -281,7 +281,7 @@ void Animation::Play()
       Object* object = connector->GetObject();
       if( object )
       {
-        object->NotifyPropertyAnimation( *this, connector->GetPropertyIndex(), iter->targetValue );
+        object->NotifyPropertyAnimation( *this, connector->GetPropertyIndex(), iter->targetValue, iter->propertyChangeType );
       }
     }
   }
@@ -370,6 +370,14 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
 
   ExtendDuration( period );
 
+  // Store data to later notify the object that its property is being animated
+  ConnectorTargetValues connectorPair;
+  connectorPair.targetValue = relativeValue;
+  connectorPair.connectorIndex = mConnectors.Count();
+  connectorPair.timePeriod = period;
+  connectorPair.propertyChangeType = Object::PropertyChange::ADJUST_VALUE_BY;
+  mConnectorTargetValues.push_back( connectorPair );
+
   switch ( targetType )
   {
     case Property::BOOLEAN:
@@ -502,6 +510,7 @@ void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIn
   connectorPair.targetValue = destinationValue;
   connectorPair.connectorIndex = mConnectors.Count();
   connectorPair.timePeriod = period;
+  connectorPair.propertyChangeType = Object::PropertyChange::SET;
   mConnectorTargetValues.push_back( connectorPair );
 
   switch ( destinationType )
index 92dff74..6a3d6c2 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/internal/event/animation/animator-connector-base.h>
 #include <dali/internal/event/animation/key-frames-impl.h>
 #include <dali/internal/event/animation/path-impl.h>
+#include <dali/internal/event/common/object-impl.h>
 
 namespace Dali
 {
@@ -445,13 +446,15 @@ private:
     ConnectorTargetValues()
     : targetValue(),
       timePeriod( 0.0f ),
-      connectorIndex( 0 )
+      connectorIndex( 0 ),
+      propertyChangeType( Object::PropertyChange::SET )
     {
     }
 
     Property::Value targetValue;
     TimePeriod timePeriod;
     unsigned int connectorIndex;
+    Object::PropertyChange::Type propertyChangeType;
   };
 
 private:
index 344e72c..0e7b77e 100644 (file)
@@ -924,19 +924,32 @@ void Object::RemovePropertyNotifications()
   }
 }
 
-void Object::NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value )
+void Object::NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType )
 {
   if ( index < DEFAULT_PROPERTY_MAX_COUNT )
   {
-    OnNotifyDefaultPropertyAnimation( animation, index, value );
+    OnNotifyDefaultPropertyAnimation( animation, index, value, propertyChangeType );
   }
   else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
     AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
     if( animatableProperty )
     {
-      // update the cached property value
-      animatableProperty->SetPropertyValue( value );
+      switch( propertyChangeType )
+      {
+        case PropertyChange::SET:
+        {
+          // update the cached property value
+          animatableProperty->SetPropertyValue( value );
+          break;
+        }
+        case PropertyChange::ADJUST_VALUE_BY:
+        {
+          // adjust the cached property value
+          animatableProperty->AdjustPropertyValueBy( value );
+          break;
+        }
+      }
     }
   }
   else
@@ -944,8 +957,21 @@ void Object::NotifyPropertyAnimation( Animation& animation, Property::Index inde
     CustomPropertyMetadata* custom = FindCustomProperty( index );
     if( custom && custom->IsAnimatable() )
     {
-      // update the cached property value
-      custom->SetPropertyValue( value );
+      switch( propertyChangeType )
+      {
+        case PropertyChange::SET:
+        {
+          // update the cached property value
+          custom->SetPropertyValue( value );
+          break;
+        }
+        case PropertyChange::ADJUST_VALUE_BY:
+        {
+          // adjust the cached property value
+          custom->AdjustPropertyValueBy( value );
+          break;
+        }
+      }
     }
   }
 }
index 035e7ee..f38f03b 100644 (file)
@@ -81,6 +81,18 @@ class Object : public Dali::BaseObject
 {
 public:
 
+  /**
+   * Used by NotifyPropertyAnimation to differentiate between an AnimateTo and AnimateBy call.
+   */
+  struct PropertyChange
+  {
+    enum Type
+    {
+      SET,      ///< Animating to the given value.
+      ADJUST_VALUE_BY  ///< Animating by the given value.
+    };
+  };
+
   typedef Dali::Handle::Capability Capability;
 
   class Observer
@@ -245,8 +257,9 @@ public:
    * @param[in] animation The animation animating the property.
    * @param[in] index The index of the property.
    * @param[in] value The value of the property after the animation.
+   * @param[in] propertyChangeType Whether the property value given should be set or changed by.
    */
-  void NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value );
+  void NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType );
 
   /******************************** Uniform Mappings ********************************/
 
@@ -492,8 +505,9 @@ private: // Default property extensions for derived classes
    * @param[in] animation The animation animating the property.
    * @param[in] index The index of the property.
    * @param[in] value The value of the property after the animation.
+   * @param[in] propertyChangeType Whether the property value given should be set or changed by.
    */
-  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value )
+  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType )
   { }
 
   /**
index abbe62e..d233e7e 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali/internal/event/common/property-metadata.h>
 
 // INTERNAL INCLUDES
+#include <dali/public-api/math/quaternion.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
@@ -30,6 +31,23 @@ namespace Dali
 namespace Internal
 {
 
+namespace
+{
+
+/// Helper to adjust the property value by an amount specified in another property-value
+template < typename PropertyType >
+inline void AdjustProperty( Property::Value& currentPropertyValue, const Property::Value& relativePropertyValue )
+{
+  PropertyType currentValue;
+  PropertyType relativeValue;
+  if( currentPropertyValue.Get( currentValue ) && relativePropertyValue.Get( relativeValue ) )
+  {
+    currentPropertyValue = currentValue + relativeValue;
+  }
+}
+
+} // unnamed namespace
+
 void PropertyMetadata::SetPropertyValue( const Property::Value& propertyValue )
 {
   switch ( GetType() )
@@ -235,6 +253,146 @@ Property::Value PropertyMetadata::GetPropertyValue() const
   return propertyValue;
 }
 
+void PropertyMetadata::AdjustPropertyValueBy( const Property::Value& relativePropertyValue )
+{
+  switch ( GetType() )
+  {
+    case Property::NONE:
+    case Property::RECTANGLE:
+    case Property::STRING:
+    case Property::ARRAY:
+    case Property::MAP:
+    case Property::MATRIX:
+    case Property::MATRIX3:
+    {
+      // Not animated
+      break;
+    }
+
+    case Property::BOOLEAN:
+    {
+      bool currentValue = false;
+      bool relativeValue = false;
+      if( value.Get( currentValue ) && relativePropertyValue.Get( relativeValue ) )
+      {
+        value = currentValue || relativeValue;
+      }
+      break;
+    }
+
+    case Property::INTEGER:
+    {
+      AdjustProperty< int >( value, relativePropertyValue );
+      break;
+    }
+
+    case Property::FLOAT:
+    {
+      AdjustProperty< float >( value, relativePropertyValue );
+      break;
+    }
+
+    case Property::ROTATION:
+    {
+      Quaternion currentValue;
+      Quaternion relativeValue;
+      if( value.Get( currentValue ) && relativePropertyValue.Get( relativeValue ) )
+      {
+        value = currentValue * relativeValue;
+      }
+      break;
+    }
+
+    case Property::VECTOR2:
+    {
+      if( componentIndex == Property::INVALID_COMPONENT_INDEX )
+      {
+        AdjustProperty< Vector2 >( value, relativePropertyValue );
+      }
+      else
+      {
+        Vector2 vector2Value;
+        value.Get( vector2Value );
+
+        if( componentIndex == 0 )
+        {
+          vector2Value.x += relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 1 )
+        {
+          vector2Value.y += relativePropertyValue.Get< float >();
+        }
+
+        value = vector2Value;
+      }
+
+      break;
+    }
+
+    case Property::VECTOR3:
+    {
+      if( componentIndex == Property::INVALID_COMPONENT_INDEX )
+      {
+        AdjustProperty< Vector3 >( value, relativePropertyValue );
+      }
+      else
+      {
+        Vector3 vector3Value;
+        value.Get( vector3Value );
+
+        if( componentIndex == 0 )
+        {
+          vector3Value.x += relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 1 )
+        {
+          vector3Value.y += relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 2 )
+        {
+          vector3Value.z += relativePropertyValue.Get< float >();
+        }
+
+        value = vector3Value;
+      }
+      break;
+    }
+
+    case Property::VECTOR4:
+    {
+      if( componentIndex == Property::INVALID_COMPONENT_INDEX )
+      {
+        AdjustProperty< Vector4 >( value, relativePropertyValue );
+      }
+      else
+      {
+        Vector4 vector4Value;
+        value.Get( vector4Value );
+
+        if( componentIndex == 0 )
+        {
+          vector4Value.x = relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 1 )
+        {
+          vector4Value.y = relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 2 )
+        {
+          vector4Value.z = relativePropertyValue.Get< float >();
+        }
+        else if( componentIndex == 3 )
+        {
+          vector4Value.w = relativePropertyValue.Get< float >();
+        }
+
+        value = vector4Value;
+      }
+      break;
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali
index a06f262..b845eaa 100644 (file)
@@ -116,6 +116,12 @@ public:
    */
   Property::Value GetPropertyValue() const;
 
+  /**
+   * Modifies the stored value by the relativeValue.
+   * @param[in] relativeValue The value to change by.
+   */
+  void AdjustPropertyValueBy( const Property::Value& relativeValue );
+
 protected:
 
   /**
index a97069b..556d994 100644 (file)
@@ -69,6 +69,17 @@ TypeRegistration mType( typeid( Dali::RenderTask ), typeid( Dali::BaseHandle ),
 
 SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &RenderTask::DoConnectSignal );
 
+/// Helper to adjust the current value of a variable from the given property-value
+template< typename PropertyType >
+inline void AdjustValue( PropertyType& currentValue, const Property::Value& value )
+{
+  PropertyType relativeValue;
+  if( value.Get( relativeValue ) )
+  {
+    currentValue += relativeValue;
+  }
+}
+
 } // Unnamed namespace
 
 RenderTask* RenderTask::New( bool isSystemLevel )
@@ -689,30 +700,60 @@ Property::Value RenderTask::GetDefaultPropertyCurrentValue( Property::Index inde
   return value;
 }
 
-void RenderTask::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value )
+void RenderTask::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType )
 {
-  switch ( index )
+  if( propertyChangeType == Object::PropertyChange::SET )
   {
-    case Dali::RenderTask::Property::VIEWPORT_POSITION:
-    {
-      value.Get( mViewportPosition );
-      break;
-    }
-    case Dali::RenderTask::Property::VIEWPORT_SIZE:
-    {
-      value.Get( mViewportSize );
-      break;
-    }
-    case Dali::RenderTask::Property::CLEAR_COLOR:
+    switch ( index )
     {
-      value.Get( mClearColor );
-      break;
+      case Dali::RenderTask::Property::VIEWPORT_POSITION:
+      {
+        value.Get( mViewportPosition );
+        break;
+      }
+      case Dali::RenderTask::Property::VIEWPORT_SIZE:
+      {
+        value.Get( mViewportSize );
+        break;
+      }
+      case Dali::RenderTask::Property::CLEAR_COLOR:
+      {
+        value.Get( mClearColor );
+        break;
+      }
+      case Dali::RenderTask::Property::REQUIRES_SYNC:
+      default:
+      {
+        // Nothing to do as not animatable
+        break;
+      }
     }
-    case Dali::RenderTask::Property::REQUIRES_SYNC:
-    default:
+  }
+  else
+  {
+    switch ( index )
     {
-      // Nothing to do as not animatable
-      break;
+      case Dali::RenderTask::Property::VIEWPORT_POSITION:
+      {
+        AdjustValue< Vector2 >( mViewportPosition, value );
+        break;
+      }
+      case Dali::RenderTask::Property::VIEWPORT_SIZE:
+      {
+        AdjustValue< Vector2 >( mViewportSize, value );
+        break;
+      }
+      case Dali::RenderTask::Property::CLEAR_COLOR:
+      {
+        AdjustValue< Vector4 >( mClearColor, value );
+        break;
+      }
+      case Dali::RenderTask::Property::REQUIRES_SYNC:
+      default:
+      {
+        // Nothing to do as not animatable
+        break;
+      }
     }
   }
 }
index 90d5cc3..13728ed 100644 (file)
@@ -325,7 +325,7 @@ public: // Implementation of Object
   /**
    * @copydoc Dali::Internal::Object::OnNotifyDefaultPropertyAnimation()
    */
-  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value );
+  virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, PropertyChange::Type propertyChangeType );
 
   /**
    * @copydoc Dali::Internal::Object::GetSceneObject()