Merge "Outline effect has been fixed to be not front cropped." into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 17 Nov 2017 18:45:17 +0000 (18:45 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Fri, 17 Nov 2017 18:45:17 +0000 (18:45 +0000)
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h [new file with mode: 0755]
dali-toolkit/devel-api/visuals/visual-properties-devel.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp [new file with mode: 0755]
dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h [new file with mode: 0755]
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp

index 54a69bb..a247f7d 100644 (file)
@@ -68,7 +68,9 @@ void TestApplication::Initialize()
                                         mGlSyncAbstraction,
                                         mGestureManager,
                                         mDataRetentionPolicy,
-                                        false );
+                                        Integration::RenderToFrameBuffer::FALSE,
+                                        Integration::DepthBufferAvailable::TRUE,
+                                        Integration::StencilBufferAvailable::TRUE );
 
   mCore->ContextCreated();
   mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
index 121d5f4..af56d92 100644 (file)
@@ -24,6 +24,8 @@
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/transition-data.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
 
@@ -280,6 +282,15 @@ int UtcDaliVisualSize(void)
   gradientVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION );
 
+  // animated gradient visual
+  Vector2 animated_gradient_visual_size(10.f, 10.f);
+  propertyMap.Clear();
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
+  Visual::Base animatedGradientVisual = factory.CreateVisual( propertyMap );
+  animatedGradientVisual.GetNaturalSize(naturalSize);
+  animatedGradientVisual.SetTransformAndSize(DefaultTransform(), controlSize );
+  DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION );
+
   // svg visual
   Visual::Base svgVisual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions() );
   svgVisual.SetTransformAndSize(DefaultTransform(), controlSize );
@@ -1102,6 +1113,490 @@ int UtcDaliVisualGetPropertyMap10(void)
   END_TEST;
 }
 
+int UtcDaliVisualGetPropertyMap11(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetPropertyMap11: AnimatedGradientVisual" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+
+  Vector2 start(-0.5f, 0.5f);
+  Vector2 end  (0.5f, -0.0f);
+  Vector4 start_color(1.0f, 0.7f, 0.5f, 1.0f);
+  Vector4 end_color  (0.7f, 0.5f, 1.0f, 1.0f);
+  Vector2 rotate_center(0.0f, 0.4f);
+  float rotate_amount = 1.57f;
+  float offset = 100.f;
+
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  DevelAnimatedGradientVisual::GradientType::RADIAL);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE,  DevelAnimatedGradientVisual::UnitType::USER_SPACE);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  DevelAnimatedGradientVisual::SpreadType::CLAMP);
+
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION,  start);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION,  end);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR,  start_color);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR,  end_color);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  rotate_center);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  rotate_amount);
+  propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET,  offset);
+
+  Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK( animatedGradientVisual );
+
+  Property::Map resultMap;
+  animatedGradientVisual.CreatePropertyMap( resultMap );
+
+  // check the property values from the returned map from visual
+  Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_GRADIENT );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::GradientType::RADIAL );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE,  Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::UnitType::USER_SPACE );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::SpreadType::CLAMP );
+
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_POSITION,  Property::VECTOR2 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector2>(), start , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_POSITION,  Property::VECTOR2 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector2>(), end , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_COLOR,  Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector4>(), start_color , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_COLOR,  Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector4>(), end_color , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  Property::VECTOR2 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector2>(), rotate_center , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), rotate_amount , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  value = resultMap.Find( DevelAnimatedGradientVisual::Property::OFFSET,  Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), offset , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliVisualGetPropertyMap12(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetPropertyMap12: AnimatedGradientVisual with animation param" );
+
+  // Case 1 : Set values by index
+  {
+    tet_printf( " - Set Values by Index\n" );
+    // NOTE : PropertyMap doesn't optimized even delay < -loop_count * (duration + repeat_delay) so this animation will not run
+    // _delay = -10.0f is this case. It will progress (10.0f / 1.5f) amount. and 10.0f / 1.5f > 5.
+    for(float _delay = -10.0f; _delay <= 5.0f; _delay += 5.0f)
+    {
+      tet_printf( "test with delay [%f]\n", _delay );
+      VisualFactory factory = VisualFactory::Get();
+      DALI_TEST_CHECK( factory );
+
+      Property::Map propertyMap;
+      Property::Map animationMap;
+      propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+
+      float duration = 1.1f;
+      float delay = _delay;
+      float repeat_delay = 0.4f;
+
+      int direction = DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD;
+      int loop_count = 5;
+      int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR;
+      int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT;
+
+      auto buildAnimatedMap = [&animationMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Value &start, const Property::Value &target)->Property::Map&
+      {
+        animationMap.Clear();
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::START, start);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, direction);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, motion);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, easing);
+
+        return animationMap;
+      };
+
+      Vector2 start1(-0.5f, 0.5f);
+      Vector2 end1  (0.5f, -0.5f);
+      Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f);
+      Vector4 end_color1  (0.7f, 0.5f, 1.0f, 1.0f);
+      Vector2 rotate_center1(0.0f, 0.4f);
+      float rotate_amount1 = 0.0f;
+      float offset1 = 0.f;
+
+      Vector2 start2(-0.5f, -0.5f);
+      Vector2 end2  (0.5f, 0.5f);
+      Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f);
+      Vector4 end_color2  (0.3f, 1.0f, 0.1f, 0.0f);
+      Vector2 rotate_center2(0.0f, -0.4f);
+      float rotate_amount2 = 6.2832f;
+      float offset2 = 2.f;
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  DevelAnimatedGradientVisual::GradientType::LINEAR);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE,  DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  DevelAnimatedGradientVisual::SpreadType::REPEAT);
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1        , start2        ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION,   buildAnimatedMap(end1          , end2          ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR,    buildAnimatedMap(start_color1  , start_color2  ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR,      buildAnimatedMap(end_color1    , end_color2    ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  buildAnimatedMap(rotate_center1, rotate_center2));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  buildAnimatedMap(rotate_amount1, rotate_amount2));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET,         buildAnimatedMap(offset1       , offset2       ));
+
+      Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap);
+      DALI_TEST_CHECK( animatedGradientVisual );
+
+      Property::Map resultMap;
+      animatedGradientVisual.CreatePropertyMap( resultMap );
+
+      // check the property values from the returned map from visual
+      Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_GRADIENT );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::GradientType::LINEAR );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::SpreadType::REPEAT );
+
+      auto checkAnimatedMap = [&value, &resultMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Index &index, const Property::Value &start, const Property::Value &target, int line_num)->void
+      {
+        tet_printf("Check value at %d\n", line_num);
+        value = resultMap.Find( index, Property::MAP );
+        DALI_TEST_CHECK( value );
+        DALI_TEST_CHECK( value->GetType() == Property::MAP );
+        Property::Map *temp_map = value->GetMap();
+        DALI_TEST_CHECK( temp_map );
+
+        auto checkMapValue = [&temp_map](const Property::Index index)->Property::Value
+        {
+          Property::Value *res = temp_map->Find( index );
+          DALI_TEST_CHECK( res );
+          return *res;
+        };
+
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::START)       , start, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET)      , target, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION)   , Property::Value( direction ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION)    , Property::Value( duration ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY)       , Property::Value( delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT)      , Property::Value( loop_count ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY), Property::Value( repeat_delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE) , Property::Value( motion ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE) , Property::Value( easing ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+      };
+
+      // check the animation map data is good
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_POSITION, start1        , start2        , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_POSITION  , end1          , end2          , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_COLOR   , start_color1  , start_color2  , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_COLOR     , end_color1    , end_color2    , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_CENTER , rotate_center1, rotate_center2, __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , rotate_amount1, rotate_amount2, __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::OFFSET        , offset1       , offset2       , __LINE__);
+    }
+  }
+
+  // Case 2 : Set values by string
+  {
+    tet_printf( " - Set Values by String\n" );
+    // NOTE : PropertyMap doesn't optimized even delay < -loop_count * (duration + repeat_delay) so this animation will not run
+    // _delay = -10.0f is this case. It will progress (10.0f / 1.5f) amount. and 10.0f / 1.5f > 5.
+    for(float _delay = -10.0f; _delay <= 5.0f; _delay += 5.0f)
+    {
+      tet_printf( "test with delay [%f]\n", _delay );
+      VisualFactory factory = VisualFactory::Get();
+      DALI_TEST_CHECK( factory );
+
+      Property::Map propertyMap;
+      Property::Map animationMap;
+      propertyMap.Insert("visualType", "ANIMATED_GRADIENT");
+
+      float duration = 1.1f;
+      float delay = _delay;
+      float repeat_delay = 0.4f;
+
+      int direction = DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD;
+      int loop_count = 5;
+      int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR;
+      int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT;
+
+      auto buildAnimatedMap = [&animationMap, &duration, &delay, &loop_count, &repeat_delay](const Property::Value &start, const Property::Value &target)->Property::Map&
+      {
+        animationMap.Clear();
+        animationMap.Insert("startValue"   , start);
+        animationMap.Insert("targetValue"  , target);
+        animationMap.Insert("directionType", "BACKWARD");
+        animationMap.Insert("duration"     , duration);
+        animationMap.Insert("delay"        , delay);
+        animationMap.Insert("repeat"       , loop_count);
+        animationMap.Insert("repeatDelay"  , repeat_delay);
+        animationMap.Insert("motionType"   , "MIRROR");
+        animationMap.Insert("easingType"   , "IN_OUT");
+
+        return animationMap;
+      };
+
+      Vector2 start1(-0.5f, 0.5f);
+      Vector2 end1  (0.5f, -0.5f);
+      Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f);
+      Vector4 end_color1  (0.7f, 0.5f, 1.0f, 1.0f);
+      Vector2 rotate_center1(0.0f, 0.4f);
+      float rotate_amount1 = 0.0f;
+      float offset1 = 0.f;
+
+      Vector2 start2(-0.5f, -0.5f);
+      Vector2 end2  (0.5f, 0.5f);
+      Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f);
+      Vector4 end_color2  (0.3f, 1.0f, 0.1f, 0.0f);
+      Vector2 rotate_center2(0.0f, -0.4f);
+      float rotate_amount2 = 6.2832f;
+      float offset2 = 2.f;
+
+      // For test mix the type string/index key and string/index value works well.
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  "RADIAL");
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE,  DevelAnimatedGradientVisual::UnitType::USER_SPACE);
+      propertyMap.Insert("spreadType"  , DevelAnimatedGradientVisual::SpreadType::REFLECT);
+
+      propertyMap.Insert("startPosition", buildAnimatedMap(start1        , start2        ));
+      propertyMap.Insert("endPosition"  , buildAnimatedMap(end1          , end2          ));
+      propertyMap.Insert("startColor"   , buildAnimatedMap(start_color1  , start_color2  ));
+      propertyMap.Insert("endColor"     , buildAnimatedMap(end_color1    , end_color2    ));
+      propertyMap.Insert("rotateCenter" , buildAnimatedMap(rotate_center1, rotate_center2));
+      propertyMap.Insert("rotateAmount" , buildAnimatedMap(rotate_amount1, rotate_amount2));
+      propertyMap.Insert("offset"       , buildAnimatedMap(offset1       , offset2       ));
+
+      Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap);
+      DALI_TEST_CHECK( animatedGradientVisual );
+
+      Property::Map resultMap;
+      animatedGradientVisual.CreatePropertyMap( resultMap );
+
+      // check the property values from the returned map from visual
+      // Note : resultMap from CreatePropertyMap only contain indexKey
+      Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_GRADIENT );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::GradientType::RADIAL );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::UnitType::USER_SPACE );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::SpreadType::REFLECT );
+
+      auto checkAnimatedMap = [&value, &resultMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Index &index, const Property::Value &start, const Property::Value &target, int line_num)->void
+      {
+        tet_printf("Check value at %d\n", line_num);
+        value = resultMap.Find( index, Property::MAP );
+        DALI_TEST_CHECK( value );
+        DALI_TEST_CHECK( value->GetType() == Property::MAP );
+        Property::Map *temp_map = value->GetMap();
+        DALI_TEST_CHECK( temp_map );
+
+        auto checkMapValue = [&temp_map](const Property::Index index)->Property::Value
+        {
+          Property::Value *res = temp_map->Find( index );
+          DALI_TEST_CHECK( res );
+          return *res;
+        };
+
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::START)       , start, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET)      , target, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION)   , Property::Value( direction ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION)    , Property::Value( duration ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY)       , Property::Value( delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT)      , Property::Value( loop_count ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY), Property::Value( repeat_delay ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE) , Property::Value( motion ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        DALI_TEST_EQUALS( checkMapValue(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE) , Property::Value( easing ), Math::MACHINE_EPSILON_100, TEST_LOCATION );
+      };
+
+      // check the animation map data is good
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_POSITION, start1        , start2        , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_POSITION  , end1          , end2          , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::START_COLOR   , start_color1  , start_color2  , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::END_COLOR     , end_color1    , end_color2    , __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_CENTER , rotate_center1, rotate_center2, __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , rotate_amount1, rotate_amount2, __LINE__);
+      checkAnimatedMap(DevelAnimatedGradientVisual::Property::OFFSET        , offset1       , offset2       , __LINE__);
+    }
+  }
+
+  END_TEST;
+}
+int UtcDaliVisualGetPropertyMap13(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetPropertyMap13: AnimatedGradientVisual when repeat = 0" );
+
+  for(int _direction = 0; _direction <= 1; ++_direction)
+  {
+    for(float _delay = -10.0f; _delay <= 10.0f; _delay += 10.0f)
+    {
+      tet_printf( ((_direction == 0) ? "Forward test with delay [%f]\n" : "Backward test with delay [%f]\n") , _delay );
+      VisualFactory factory = VisualFactory::Get();
+      DALI_TEST_CHECK( factory );
+
+      Property::Map propertyMap;
+      Property::Map animationMap;
+      propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+
+      float duration = 1.0f;
+      float delay = _delay;
+      float repeat_delay = 0.5f;
+
+      int direction = _direction;
+      int loop_count = 0; // When loop_count is 0, Animation will not be created.
+      int motion = DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP;
+      int easing = DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN;
+
+      auto buildAnimatedMap = [&animationMap, &direction, &duration, &delay, &loop_count, &repeat_delay, &motion, &easing](const Property::Value &start, const Property::Value &target)->Property::Map&
+      {
+        animationMap.Clear();
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::START, start);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target);
+        if(direction == 0)animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD);
+        else animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, direction);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, motion);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, easing);
+
+        return animationMap;
+      };
+
+      Vector2 start1(-0.5f, 0.5f);
+      Vector2 end1  (0.5f, -0.5f);
+      Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f);
+      Vector4 end_color1  (0.7f, 0.5f, 1.0f, 1.0f);
+      Vector2 rotate_center1(1.0f, 0.4f);
+      float rotate_amount1 = 2.0f;
+      float offset1 = 1.f;
+
+      Vector2 start2(-0.5f, -0.5f);
+      Vector2 end2  (0.5f, 0.5f);
+      Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f);
+      Vector4 end_color2  (0.3f, 1.0f, 0.1f, 0.0f);
+      Vector2 rotate_center2(1.0f, -0.4f);
+      float rotate_amount2 = 1.0f;
+      float offset2 = 3.f;
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  DevelAnimatedGradientVisual::GradientType::LINEAR);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE,  DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  DevelAnimatedGradientVisual::SpreadType::REFLECT);
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1        , start2        ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION,   buildAnimatedMap(end1          , end2          ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR,    buildAnimatedMap(start_color1  , start_color2  ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR,      buildAnimatedMap(end_color1    , end_color2    ));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  buildAnimatedMap(rotate_center1, rotate_center2));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  buildAnimatedMap(rotate_amount1, rotate_amount2));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET,         buildAnimatedMap(offset1       , offset2       ));
+
+      Visual::Base animatedGradientVisual = factory.CreateVisual(propertyMap);
+      DALI_TEST_CHECK( animatedGradientVisual );
+
+      Property::Map resultMap;
+      animatedGradientVisual.CreatePropertyMap( resultMap );
+
+      // check the property values from the returned map from visual
+      Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelVisual::ANIMATED_GRADIENT );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::GRADIENT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::GradientType::LINEAR );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::UNIT_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::SPREAD_TYPE,  Property::INTEGER );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_CHECK( value->Get<int>() == DevelAnimatedGradientVisual::SpreadType::REFLECT );
+
+      // If loop_count = 0, Animation doesn't created.
+      // Optimized resultMap only have one value, which is target value
+      // Note: target value will be changed by direction option.
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_POSITION,  Property::VECTOR2 );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<Vector2>(), direction ? start1 : start2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_POSITION,  Property::VECTOR2 );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<Vector2>(), direction ? end1 : end2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::START_COLOR,  Property::VECTOR4 );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<Vector4>(), direction ? start_color1 : start_color2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::END_COLOR,  Property::VECTOR4 );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<Vector4>(), direction ? end_color1 : end_color2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  Property::VECTOR2 );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<Vector2>(), direction ? rotate_center1 : rotate_center2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  Property::FLOAT );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<float>(), direction ? rotate_amount1 : rotate_amount2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+      value = resultMap.Find( DevelAnimatedGradientVisual::Property::OFFSET,  Property::FLOAT );
+      DALI_TEST_CHECK( value );
+      DALI_TEST_EQUALS( value->Get<float>(), direction ? offset1 : offset2 , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+    }
+  }
+
+  END_TEST;
+}
+
 int UtcDaliVisualAnimateBorderVisual01(void)
 {
   ToolkitTestApplication application;
@@ -1356,6 +1851,614 @@ int UtcDaliVisualAnimatePrimitiveVisual(void)
   END_TEST;
 }
 
+int UtcDaliVisualAnimatedGradientVisual01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedGradientVisual with default" );
+
+  {
+    VisualFactory factory = VisualFactory::Get();
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+    Visual::Base visual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+    actor.SetSize(2000, 2000);
+    actor.SetParentOrigin(ParentOrigin::CENTER);
+    actor.SetColor(Color::BLACK);
+    Stage::GetCurrent().Add(actor);
+
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    for(int step_iter = 0; step_iter < 3; step_iter++)
+    {
+      application.SendNotification();
+      application.Render(0);
+      application.Render(750u); // step i/4
+      application.SendNotification();
+
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<Vector2>( "start_point"  , Vector2( -0.5f, 0.0f ) ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<Vector2>( "end_point"    , Vector2( 0.5f, 0.0f ) ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<Vector4>( "start_color"  , Vector4( 143.0f, 170.0f, 220.0f, 255.0f ) / 255.0f ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<Vector4>( "end_color"    , Vector4( 255.0f, 163.0f, 163.0f, 255.0f ) / 255.0f ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<Vector2>( "rotate_center", Vector2( 0.0f, 0.0f ) ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<float>( "rotate_angle"   , 0.0f ), true, TEST_LOCATION );
+      DALI_TEST_EQUALS( application.GetGlAbstraction().CheckUniformValue<float>( "gradient_offset", 0.5f * step_iter + 0.5f ), true, TEST_LOCATION );
+    }
+
+    //Not check here. cause gradient_offset value can be 2.0f or 0.0f
+    application.Render(750u); // go to end
+    application.SendNotification();
+
+    application.Render(10u); // finish
+    application.SendNotification();
+
+    actor.Unparent();
+    application.SendNotification();
+    application.Render(0u);
+    application.SendNotification();
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualAnimatedGradientVisual02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedGradientVisual with full-option" );
+
+  {
+    float _delay[4] = {0.0f, -1.35f, 0.15f, -0.4f}; // fract(_delay) must NOT be 1/4, 2/4, 3/4. cause we don't know progress is 1.0f or 0.0f
+    int _direction[2] = {0, 1};
+    int _loop_count[3] = {-1, 0, 1};
+    int _motion[2] = {0, 1};
+    int _easing[4] = {0, 1, 2, 3};
+
+    int test_case_max = 4 * 2 * 3 * 2 * 4;
+    int test_case = 0;
+    int test_case_d = 7; // 7 is the number of animated properties.
+
+    float _duration = 0.4f;
+    float _repeat_delay = _duration * 0.25f; // < _duration. cause real_duration = _duration - _repeat_delay;
+    float noise_maker = 0.0f;
+    // total testing time = ceil((4*2*3*2*4) / 7) * (_duration(=0.4) * 2 + 0.01) = 22.68 seconds
+    for( test_case = 0; test_case < test_case_max + test_case_d; test_case += test_case_d )
+    {
+      tet_printf( "test [%d ~ %d / %d]\n" , test_case, test_case + test_case_d - 1, test_case_max);
+
+      VisualFactory factory = VisualFactory::Get();
+      Property::Map propertyMap;
+      Property::Map animationMap;
+      propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+
+      int gradient_type = DevelAnimatedGradientVisual::GradientType::LINEAR;
+      int unit_type = DevelAnimatedGradientVisual::UnitType::USER_SPACE;
+      int spread_type = DevelAnimatedGradientVisual::SpreadType::REPEAT;
+
+      auto buildAnimatedMap = [&animationMap, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const Property::Value &start, const Property::Value &target, int tc_offset)->Property::Map&
+      {
+        int tc = (test_case + tc_offset);
+        int idx_easing = tc % 4; tc /= 4;
+        int idx_motion = tc % 2; tc /= 2;
+        int idx_loop_count = tc % 3; tc /= 3;
+        int idx_direction = tc % 2; tc /= 2;
+        int idx_delay = tc % 4; tc /= 4;
+
+        float duration = _duration - _repeat_delay;
+        float repeat_delay = _repeat_delay;
+        float delay = _delay[idx_delay] * _duration;
+        int direction = _direction[idx_direction];
+        int loop_count = _loop_count[idx_loop_count];
+        int motion = _motion[idx_motion];
+        int easing = _easing[idx_easing];
+
+        animationMap.Clear();
+        animationMap.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::START, start );
+        animationMap.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target );
+        if( direction == 0 )
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD);
+        }
+        else
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD);
+        }
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, loop_count);
+        animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay);
+        if( motion == 0 )
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP);
+        }
+        else
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR);
+        }
+        if( easing == 0 )
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR);
+        }
+        else if( easing == 1 )
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN);
+        }
+        else if( easing == 2 )
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT);
+        }
+        else
+        {
+          animationMap.Insert(DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT);
+        }
+
+        return animationMap;
+      };
+
+      // Give different values for debuging
+      noise_maker += 1.0f;
+      Vector2 start1(-0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f);
+      Vector2 end1  (0.5f + noise_maker * 0.1f, -0.5f + noise_maker * 0.1f);
+      Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f);
+      Vector4 end_color1  (0.7f, 0.5f, 1.0f, 1.0f);
+      Vector2 rotate_center1(0.0f + noise_maker * 0.1f, 0.4f + noise_maker * 0.1f);
+      float rotate_amount1 = 0.0f + noise_maker * 0.1f;
+      float offset1 = 0.f + noise_maker * 0.1f;
+
+      Vector2 start2(0.2f + noise_maker * 0.1f, -0.7f + noise_maker * 0.1f);
+      Vector2 end2  (0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f);
+      Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f);
+      Vector4 end_color2  (0.3f, 1.0f, 0.1f, 0.0f);
+      Vector2 rotate_center2(0.0f + noise_maker * 0.1f, -0.4f + noise_maker * 0.1f);
+      float rotate_amount2 = 7.0f + noise_maker * 0.1f;
+      float offset2 = 2.f + noise_maker * 0.1f;
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, gradient_type);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::UNIT_TYPE,     unit_type);
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::SPREAD_TYPE,   spread_type);
+
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_POSITION, buildAnimatedMap(start1        , start2        ,0));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_POSITION,   buildAnimatedMap(end1          , end2          ,1));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::START_COLOR,    buildAnimatedMap(start_color1  , start_color2  ,2));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::END_COLOR,      buildAnimatedMap(end_color1    , end_color2    ,3));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_CENTER,  buildAnimatedMap(rotate_center1, rotate_center2,4));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT,  buildAnimatedMap(rotate_amount1, rotate_amount2,5));
+      propertyMap.Insert(DevelAnimatedGradientVisual::Property::OFFSET,         buildAnimatedMap(offset1       , offset2       ,6));
+
+      Visual::Base visual = factory.CreateVisual( propertyMap );
+
+      DummyControl actor = DummyControl::New( true );
+      Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>( actor.GetImplementation() );
+      dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+      actor.SetSize( 2000, 2000 );
+      actor.SetParentOrigin(ParentOrigin::CENTER);
+      actor.SetColor(Color::BLACK);
+      Stage::GetCurrent().Add(actor);
+
+      application.SendNotification();
+      application.Render( 0 );
+      application.SendNotification();
+
+      DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+      application.SendNotification();
+
+      //Compare between CPU calculated value and Shader Visual calculated value
+      auto testProperty = [&application, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const char* name, const Property::Value& start, const Property::Value& target, int tc_offset, int value_type, float progress)->void
+      {
+        int tc = (test_case + tc_offset);
+        int idx_easing = tc % 4; tc /= 4;
+        int idx_motion = tc % 2; tc /= 2;
+        int idx_loop_count = tc % 3; tc /= 3;
+        int idx_direction = tc % 2; tc /= 2;
+        int idx_delay = tc % 4; tc /= 4;
+
+        float duration = _duration - _repeat_delay;
+        float repeat_delay = _repeat_delay;
+        float delay = _delay[idx_delay] * _duration;
+        int direction = _direction[idx_direction];
+        int loop_count = _loop_count[idx_loop_count];
+        int motion = _motion[idx_motion];
+        int easing = _easing[idx_easing];
+
+        progress -= delay / _duration;
+
+        Property::Value s = start;
+        Property::Value t = target;
+        if( direction == 1 )
+        {
+          s = target;
+          t = start;
+        }
+        float x; ///< Animator progress value
+        if( loop_count == 0 )
+        {
+          x = 1.0f;
+        }
+        else if( loop_count > 0 && progress + 0.01f > loop_count )
+        {
+          x = ( motion == 0 ) ? 1.0f : 0.0f;
+        }
+        else
+        {
+          if( progress < 0.0f )
+          {
+            progress = 0.0f;
+          }
+          progress = fmodf( progress, 1.0f );
+          progress = Dali::Clamp( (progress * (duration + repeat_delay) - repeat_delay) / duration, 0.0f, 1.0f );
+
+          x = progress;
+          if( motion == 1 )
+          {
+            x = progress * 2.0f;
+            if( x > 1.0f )
+            {
+              x = 2.0f - x;
+            }
+          }
+
+          if( easing == 1 ) // EASE_IN
+          {
+            x = x*x;
+          }
+          else if( easing == 2 ) // EASE_OUT
+          {
+            x = 2.0f*x - x*x;
+          }
+          else if( easing == 3 ) // EASE_IN_OUT
+          {
+            x = x * x * (3.0f - 2.0f * x);
+          }
+        }
+        if( value_type == 0 ) // result type is Float
+        {
+          float res;
+          float cur;
+          res = s.Get<float>() * (1.0f - x) + t.Get<float>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<float>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else if( value_type == 1 ) // result type is Vector2
+        {
+          Vector2 res;
+          Vector2 cur;
+          res = s.Get<Vector2>() * (1.0f - x) + t.Get<Vector2>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector2>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else if( value_type == 2 ) // result type is Vector3
+        {
+          Vector3 res;
+          Vector3 cur;
+          res = s.Get<Vector3>() * (1.0f - x) + t.Get<Vector3>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector3>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else // result type is Vector4
+        {
+          Vector4 res;
+          Vector4 cur;
+          res = s.Get<Vector4>() * (1.0f - x) + t.Get<Vector4>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector4>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+      };
+
+      float step = 0.0f;
+      for( int iter = 0; iter < 2; iter++ ) // test 2*duration seconds
+      {
+        for( int step_iter = 0; step_iter < 3; step_iter++ )
+        {
+          application.SendNotification();
+          application.Render( _duration * 250.f );  // step i/4
+          application.SendNotification();
+          step += 0.25f;
+
+          testProperty( "start_point"    , Property::Value( start1 )        , Property::Value( start2 )        , 0, 1, step );
+          testProperty( "end_point"      , Property::Value( end1 )          , Property::Value( end2 )          , 1, 1, step );
+          testProperty( "start_color"    , Property::Value( start_color1 )  , Property::Value( start_color2 )  , 2, 3, step );
+          testProperty( "end_color"      , Property::Value( end_color1 )    , Property::Value( end_color2 )    , 3, 3, step );
+          testProperty( "rotate_center"  , Property::Value( rotate_center1 ), Property::Value( rotate_center2 ), 4, 1, step );
+          testProperty( "rotate_angle"   , Property::Value( rotate_amount1 ), Property::Value( rotate_amount2 ), 5, 0, step );
+          testProperty( "gradient_offset", Property::Value( offset1 )       , Property::Value( offset2 )       , 6, 0, step );
+        }
+        application.SendNotification();
+        application.Render(_duration * 250.f);  // step 4/4 will not test
+        application.SendNotification();
+        step += 0.25f;
+      }
+
+      application.SendNotification();
+      actor.Unparent();
+      application.SendNotification();
+      application.Render(10.f);  // tempral time
+      application.SendNotification();
+    }
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualAnimatedGradientVisual03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedGradientVisual with full-option use string key" );
+
+  {
+    float _delay[4] = {0.0f, -1.35f, 0.15f, -0.4f}; // fract(_delay) must NOT be 1/4, 2/4, 3/4. cause we don't know progress is 1.0f or 0.0f
+    int _direction[2] = {0, 1};
+    int _loop_count[3] = {-1, 0, 1};
+    int _motion[2] = {0, 1};
+    int _easing[4] = {0, 1, 2, 3};
+
+    int test_case_max = 4 * 2 * 3 * 2 * 4;
+    int test_case = 0;
+    int test_case_d = 7; // 7 is the number of animated properties.
+
+    float _duration = 0.4f;
+    float _repeat_delay = _duration * 0.25f; // < _duration. cause real_duration = _duration - _repeat_delay;
+    float noise_maker = 0.2f;
+    // total testing time = ceil((4*2*3*2*4) / 7) * (_duration(=0.4) * 2 + 0.01) = 22.68 seconds
+    for( test_case = 0; test_case < test_case_max + test_case_d; test_case += test_case_d )
+    {
+      tet_printf( "test [%d ~ %d / %d]\n" , test_case, test_case + test_case_d - 1, test_case_max);
+
+      VisualFactory factory = VisualFactory::Get();
+      Property::Map propertyMap;
+      Property::Map animationMap;
+      propertyMap.Insert(Visual::Property::TYPE,  DevelVisual::ANIMATED_GRADIENT);
+
+      auto buildAnimatedMap = [&animationMap, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const Property::Value &start, const Property::Value &target, int tc_offset)->Property::Map&
+      {
+        int tc = (test_case + tc_offset);
+        int idx_easing = tc % 4; tc /= 4;
+        int idx_motion = tc % 2; tc /= 2;
+        int idx_loop_count = tc % 3; tc /= 3;
+        int idx_direction = tc % 2; tc /= 2;
+        int idx_delay = tc % 4; tc /= 4;
+
+        float duration = _duration - _repeat_delay;
+        float repeat_delay = _repeat_delay;
+        float delay = _delay[idx_delay] * _duration;
+        int direction = _direction[idx_direction];
+        int loop_count = _loop_count[idx_loop_count];
+        int motion = _motion[idx_motion];
+        int easing = _easing[idx_easing];
+
+        animationMap.Clear();
+        animationMap.Insert( "startValue", start );
+        animationMap.Insert( "targetValue", target );
+        if( direction == 0 )
+        {
+          animationMap.Insert("directionType", "FORWARD");
+        }
+        else
+        {
+          animationMap.Insert("directionType", "BACKWARD");
+        }
+        animationMap.Insert("duration", duration);
+        animationMap.Insert("delay", delay);
+        animationMap.Insert("repeat", loop_count);
+        animationMap.Insert("repeatDelay", repeat_delay);
+        if( motion == 0 )
+        {
+          animationMap.Insert("motionType", "LOOP");
+        }
+        else
+        {
+          animationMap.Insert("motionType", "MIRROR");
+        }
+        if( easing == 0 )
+        {
+          animationMap.Insert("easingType", "LINEAR");
+        }
+        else if( easing == 1 )
+        {
+          animationMap.Insert("easingType", "IN");
+        }
+        else if( easing == 2 )
+        {
+          animationMap.Insert("easingType", "OUT");
+        }
+        else
+        {
+          animationMap.Insert("easingType", "IN_OUT");
+        }
+
+        return animationMap;
+      };
+
+      // Give different values for debuging
+      noise_maker += 0.8f;
+      Vector2 start1(-0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f);
+      Vector2 end1  (0.5f + noise_maker * 0.1f, -0.5f + noise_maker * 0.1f);
+      Vector4 start_color1(1.0f, 0.7f, 0.5f, 1.0f);
+      Vector4 end_color1  (0.7f, 0.5f, 1.0f, 1.0f);
+      Vector2 rotate_center1(0.0f + noise_maker * 0.1f, 0.4f + noise_maker * 0.1f);
+      float rotate_amount1 = 0.0f + noise_maker * 0.1f;
+      float offset1 = 0.f + noise_maker * 0.1f;
+
+      Vector2 start2(0.2f + noise_maker * 0.1f, -0.7f + noise_maker * 0.1f);
+      Vector2 end2  (0.5f + noise_maker * 0.1f, 0.5f + noise_maker * 0.1f);
+      Vector4 start_color2(0.0f, 0.1f, 0.8f, 1.0f);
+      Vector4 end_color2  (0.3f, 1.0f, 0.1f, 0.0f);
+      Vector2 rotate_center2(0.0f + noise_maker * 0.1f, -0.4f + noise_maker * 0.1f);
+      float rotate_amount2 = 7.0f + noise_maker * 0.1f;
+      float offset2 = 2.f + noise_maker * 0.1f;
+
+      propertyMap.Insert("gradientType", "LINEAR");
+      propertyMap.Insert("unitType",     "USER_SPACE");
+      propertyMap.Insert("spreadType",   "CLAMP");
+
+      propertyMap.Insert("startPosition", buildAnimatedMap(start1        , start2        ,0));
+      propertyMap.Insert("endPosition",   buildAnimatedMap(end1          , end2          ,1));
+      propertyMap.Insert("startColor",    buildAnimatedMap(start_color1  , start_color2  ,2));
+      propertyMap.Insert("endColor",      buildAnimatedMap(end_color1    , end_color2    ,3));
+      propertyMap.Insert("rotateCenter",  buildAnimatedMap(rotate_center1, rotate_center2,4));
+      propertyMap.Insert("rotateAmount",  buildAnimatedMap(rotate_amount1, rotate_amount2,5));
+      propertyMap.Insert("offset",        buildAnimatedMap(offset1       , offset2       ,6));
+
+      Visual::Base visual = factory.CreateVisual( propertyMap );
+
+      DummyControl actor = DummyControl::New( true );
+      Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>( actor.GetImplementation() );
+      dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+      actor.SetSize( 2000, 2000 );
+      actor.SetParentOrigin(ParentOrigin::CENTER);
+      actor.SetColor(Color::BLACK);
+      Stage::GetCurrent().Add(actor);
+
+      application.SendNotification();
+      application.Render( 0 );
+      application.SendNotification();
+
+      DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+      application.SendNotification();
+
+      //Compare between CPU calculated value and Shader Visual calculated value
+      auto testProperty = [&application, &_direction, &_duration, &_delay, &_loop_count, &_repeat_delay, &_motion, &_easing, &test_case](const char* name, const Property::Value& start, const Property::Value& target, int tc_offset, int value_type, float progress)->void
+      {
+        int tc = (test_case + tc_offset);
+        int idx_easing = tc % 4; tc /= 4;
+        int idx_motion = tc % 2; tc /= 2;
+        int idx_loop_count = tc % 3; tc /= 3;
+        int idx_direction = tc % 2; tc /= 2;
+        int idx_delay = tc % 4; tc /= 4;
+
+        float duration = _duration - _repeat_delay;
+        float repeat_delay = _repeat_delay;
+        float delay = _delay[idx_delay] * _duration;
+        int direction = _direction[idx_direction];
+        int loop_count = _loop_count[idx_loop_count];
+        int motion = _motion[idx_motion];
+        int easing = _easing[idx_easing];
+
+        progress -= delay / _duration;
+
+        Property::Value s = start;
+        Property::Value t = target;
+        if( direction == 1 )
+        {
+          s = target;
+          t = start;
+        }
+        float x; ///< Animator progress value
+        if( loop_count == 0 )
+        {
+          x = 1.0f;
+        }
+        else if( loop_count > 0 && progress + 0.01f > loop_count )
+        {
+          x = ( motion == 0 ) ? 1.0f : 0.0f;
+        }
+        else
+        {
+          if( progress < 0.0f )
+          {
+            progress = 0.0f;
+          }
+          progress = fmodf( progress, 1.0f );
+          progress = Dali::Clamp( (progress * (duration + repeat_delay) - repeat_delay) / duration, 0.0f, 1.0f );
+
+          x = progress;
+          if( motion == 1 )
+          {
+            x = progress * 2.0f;
+            if( x > 1.0f )
+            {
+              x = 2.0f - x;
+            }
+          }
+
+          if( easing == 1 ) // EASE_IN
+          {
+            x = x*x;
+          }
+          else if( easing == 2 ) // EASE_OUT
+          {
+            x = 2.0f*x - x*x;
+          }
+          else if( easing == 3 ) // EASE_IN_OUT
+          {
+            x = x * x * (3.0f - 2.0f * x);
+          }
+        }
+        if( value_type == 0 ) // result type is Float
+        {
+          float res;
+          float cur;
+          res = s.Get<float>() * (1.0f - x) + t.Get<float>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<float>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else if( value_type == 1 ) // result type is Vector2
+        {
+          Vector2 res;
+          Vector2 cur;
+          res = s.Get<Vector2>() * (1.0f - x) + t.Get<Vector2>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector2>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else if( value_type == 2 ) // result type is Vector3
+        {
+          Vector3 res;
+          Vector3 cur;
+          res = s.Get<Vector3>() * (1.0f - x) + t.Get<Vector3>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector3>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+        else // result type is Vector4
+        {
+          Vector4 res;
+          Vector4 cur;
+          res = s.Get<Vector4>() * (1.0f - x) + t.Get<Vector4>() * (x);
+          DALI_TEST_EQUALS( application.GetGlAbstraction().GetUniformValue<Vector4>(name, cur), true, TEST_LOCATION );
+          DALI_TEST_EQUALS( res, cur, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+        }
+      };
+
+      float step = 0.0f;
+      for( int iter = 0; iter < 2; iter++ ) // test 2*duration seconds
+      {
+        for( int step_iter = 0; step_iter < 3; step_iter++ )
+        {
+          application.SendNotification();
+          application.Render( _duration * 250.f );  // step i/4
+          application.SendNotification();
+          step += 0.25f;
+
+          testProperty( "start_point"    , Property::Value( start1 )        , Property::Value( start2 )        , 0, 1, step );
+          testProperty( "end_point"      , Property::Value( end1 )          , Property::Value( end2 )          , 1, 1, step );
+          testProperty( "start_color"    , Property::Value( start_color1 )  , Property::Value( start_color2 )  , 2, 3, step );
+          testProperty( "end_color"      , Property::Value( end_color1 )    , Property::Value( end_color2 )    , 3, 3, step );
+          testProperty( "rotate_center"  , Property::Value( rotate_center1 ), Property::Value( rotate_center2 ), 4, 1, step );
+          testProperty( "rotate_angle"   , Property::Value( rotate_amount1 ), Property::Value( rotate_amount2 ), 5, 0, step );
+          testProperty( "gradient_offset", Property::Value( offset1 )       , Property::Value( offset2 )       , 6, 0, step );
+        }
+        application.SendNotification();
+        application.Render(_duration * 250.f);  // step 4/4 will not test
+        application.SendNotification();
+        step += 0.25f;
+      }
+
+      application.SendNotification();
+      actor.Unparent();
+      application.SendNotification();
+      application.Render(10.f);  // tempral time
+      application.SendNotification();
+    }
+  }
+
+  END_TEST;
+}
 
 int UtcDaliVisualWireframeVisual(void)
 {
index f93beb1..275e14d 100644 (file)
@@ -45,9 +45,6 @@ devel_api_src_files = \
 devel_api_header_files = \
   $(devel_api_src_dir)/direction-enums.h
 
-devel_api_visuals_header_files = \
-  $(devel_api_src_dir)/visuals/image-visual-properties-devel.h
-
 devel_api_controls_header_files = \
   $(devel_api_src_dir)/controls/control-depth-index-ranges.h \
   $(devel_api_src_dir)/controls/control-devel.h \
@@ -93,6 +90,11 @@ devel_api_visual_factory_header_files = \
   $(devel_api_src_dir)/visual-factory/visual-factory.h \
   $(devel_api_src_dir)/visual-factory/visual-base.h
 
+devel_api_visuals_header_files = \
+  $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
+  $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
+  $(devel_api_src_dir)/visuals/visual-properties-devel.h
+
 devel_api_shadow_view_header_files = \
   $(devel_api_src_dir)/controls/shadow-view/shadow-view.h
 
diff --git a/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h
new file mode 100755 (executable)
index 0000000..41b3f31
--- /dev/null
@@ -0,0 +1,347 @@
+#ifndef DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H
+#define DALI_TOOLKIT_DEVEL_ANIMATED_GRADIENT_VISUAL_PROPERTIES_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/toolkit-property-index-ranges.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ *
+ */
+
+/**
+ * @brief AnimatedGradientVisual is to render a smooth transition of colors to the control's quad with animation.
+ */
+namespace DevelAnimatedGradientVisual
+{
+
+/**
+ * @brief AnimatedGradientVisual Property
+ */
+namespace Property
+{
+
+/**
+ * @brief AnimatedGradientVisual Property
+ */
+enum
+{
+  /**
+   * @brief The form of gradient.
+   * @details Name "gradientType", type GradientType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is GradientType::LINEAR.
+   * @see GradientType::Type
+   */
+  GRADIENT_TYPE = VISUAL_PROPERTY_START_INDEX,
+
+  /**
+   * @brief The coordinate system inside of control's quad.
+   * @details Name "unitType", type UnitType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is UnitType::OBJECT_BOUNDING_BOX.
+   * @see UnitType::Type
+   */
+  UNIT_TYPE,
+
+  /**
+   * @brief The policy of color when gradient coordinate is not between 0 and 1.
+   * @details Name "spreadType", type SpreadType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is SpreadType::REFLECT.
+   * @see SpreadType::Type
+   */
+  SPREAD_TYPE,
+
+  /**
+   * @brief The position of a gradient coordinate is 0. If GRADIENT_TYPE is RADIAL, than it will be center of circle.
+   * @details Name "startPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property
+   * @note If not supplied, default is Vector2( -0.5f, 0.0f ).
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property
+   */
+  START_POSITION,
+
+  /**
+   * @brief The color of a gradient coordinate is 0.
+   * @details Name "startColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is Vector4( 143.0f, 170.0f, 220.0f, 255.0f ) / 255.0f.
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   */
+  START_COLOR,
+
+  /**
+   * @brief The position of a gradient coordinate is 1.
+   * @details Name "endPosition", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is Vector2( 0.5f, 0.0f ).
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   */
+  END_POSITION,
+
+  /**
+   * @brief The color of a gradient coordinate is 1.
+   * @details Name "endColor", type Property::Vector4 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is Vector4( 255.0f, 163.0f, 163.0f, 255.0f ) / 255.0f.
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property
+   */
+  END_COLOR,
+
+  /**
+   * @brief The center of rotate START_POSITION and END_POSITION.
+   * @details Name "rotateCenter", type Property::Vector2 or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is Vector2( 0.0f, 0.0f ).
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property
+   */
+  ROTATE_CENTER,
+
+  /**
+   * @brief The amount of rotate START_POSITION and END_POSITION in radian.
+   * @details Name "rotateAmount", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is 0.0f.
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property
+   */
+  ROTATE_AMOUNT,
+
+  /**
+   * @brief The offset of gradient coordinate. The point will have a color where (gradient coordinate + offset).
+   * @details Name "offset", type Property::FLOAT or Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   * @note If not supplied, default is Animation from 0.0f to 2.0f, with duration 3.0f seconds.
+   * @note This can be animated when you use type as Property::Map which index is AnimatedGradientVisual::AnimationParameter::Property.
+   */
+  OFFSET
+};
+
+} // namespace Property
+
+/**
+ * @brief The type of gradient form. It decide the method of calculate gradient coordinate.
+ * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION.
+ * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION.
+ */
+namespace GradientType
+{
+
+/**
+ * @brief The type of gradient form. It decide the method of calculate gradient coordinate.
+ * - If GradientType::Type is LINEAR, gradient coordinate is dot product with the line which contain START_POSITION and END_POSITION.
+ * - If GradientType::Type is RADIAL, gradient coordinate is euclidean distance from START_POSITION.
+ */
+enum Type
+{
+  LINEAR, ///< Draw gradient linear form.
+  RADIAL ///< Draw gradient radial form.
+};
+
+} // namespace GradientType
+
+/**
+ * @brief The type of coordinate system for certain attributes of the points in a gradients.
+ * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER.
+ */
+namespace UnitType
+{
+
+/**
+ * @brief The type of coordinate system for certain attributes of the points in a gradients.
+ * This applies to the START_POSITION, END_POSITION, and ROTATE_CENTER.
+ */
+enum Type
+{
+  OBJECT_BOUNDING_BOX, ///< Use positions coordinate in bottom-left(-0.5,-0.5) ~ top-right(0.5,0.5).
+  USER_SPACE, ///< Use positions coordinate in bottom-left(-ActorSize.xy * 0.5) ~ top-right(ActorSize.xy * 0.5).
+};
+
+} // namespace UnitType
+
+/**
+ * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1.
+ */
+namespace SpreadType
+{
+
+/**
+ * @brief The policies that define what happens if the gradient coordinate is not between 0 and 1.
+ */
+enum Type
+{
+  REFLECT, ///<  Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc.
+  REPEAT, ///< Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc.
+  CLAMP, ///< Use the terminal colors of gradient.
+};
+
+} // namespace SpreadType
+
+/**
+ * @brief AnimatedGradientVisual::AnimationParameter is information of each properties animation.
+ * Value animate from start to target during duration seconds.
+ * Each start/target value type for AnimatedGradientVisual Property is :
+ * - START_POSITION, END_POSITION, ROTATE_CENTER is Property::Vector2
+ * - START_COLOR, END_COLOR is Property::Vector4
+ * - ROTATE_AMOUNT, OFFSET is Property::FLOAT
+ * You can set the animation information to AnimatedGradientVisual Property by using Property::MAP.
+ */
+namespace AnimationParameter
+{
+
+/**
+ * @brief AnimatedGradientVisual::AnimationParameter Property
+ */
+enum Property
+{
+
+  /**
+   * @brief The start value of this animation.
+   * @details Name "startValue", type depends on AnimatedGradientVisual Property.
+   * @note If not supplied, default is Property::Value( 0.0f ).
+   */
+  START = DevelAnimatedGradientVisual::Property::OFFSET + 1,
+
+  /**
+   * @brief The target value of this animation.
+   * @details Name "targetValue", type depends on AnimatedGradientVisual Property.
+   * @note If not supplied, default is Property::Value( 0.0f ).
+   */
+  TARGET,
+
+  /**
+   * @brief The direction of this animation.
+   * @details Name "directionType", type DirectionType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is DirectionType::FORWARD.
+   * @see DirectionType::Type
+   */
+  DIRECTION,
+
+  /**
+   * @brief The duration of this animation in seconds.
+   * @details Name "duration", type Property::FLOAT.
+   * @note If not supplied, default is 3.0f.
+   */
+  DURATION,
+
+  /**
+   * @brief The delay of this animation in seconds.
+   * If delay is positive, wait the animation 'delay' seconds.
+   * If delay is negative, skip the animation '-delay' seconds.
+   * @details Name "delay", type Property::FLOAT.
+   * @note If not supplied, default is 0.0f.
+   */
+  DELAY,
+
+  /**
+   * @brief The repeat count of this animation.
+   * If repeat is negative, animate unlimited loop.
+   * If repeat is zero, animation will no run.
+   * If repeat is positive, animate 'repeat' times.
+   * @details Name "repeat", type Property::INTEGER.
+   * @note If not supplied, default is 0.
+   */
+  REPEAT,
+
+  /**
+   * @brief The delay before each loop of this animation in seconds.
+   * @details Name "repeatDelay", type Property::FLOAT.
+   * @note If not supplied, default is 0.0f.
+   */
+  REPEAT_DELAY,
+
+  /**
+   * @brief The motion of this animation.
+   * @details Name "motionType", type MotionType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is MotionType::LOOP.
+   * @see MotionType::Type
+   */
+  MOTION_TYPE,
+
+  /**
+   * @brief The easing option of this animation.
+   * @details Name "easingType", type EasingType::Type (Property::INTEGER) or Property::STRING.
+   * @note If not supplied, default is EasingType::LINEAR.
+   * @see EasingType::Type
+   */
+  EASING_TYPE
+};
+
+/**
+ * @brief The type of animation direction
+ */
+namespace DirectionType
+{
+
+/**
+ * @brief The type of animation direction
+ */
+enum Type
+{
+  FORWARD, ///< Animate value from START to TARGET
+  BACKWARD, ///< Animate value frome TARGET to START
+};
+
+} // namespace DirectionType
+
+/**
+ * @brief The type of animation motion
+ */
+namespace MotionType
+{
+
+/**
+ * @brief The type of animation motion
+ */
+enum Type
+{
+  LOOP, ///< Animate loopingmode restart
+  MIRROR, ///< Animate loopingmode auto_reverse
+};
+
+} // namespace MotionType
+
+/**
+ * @brief The type of animation easing
+ */
+namespace EasingType
+{
+
+/**
+ * @brief The type of animation easing
+ */
+enum Type
+{
+  LINEAR, ///< Easing animation linear
+  IN, ///< Ease-in animation (slow start -> fast finish)
+  OUT, ///< Ease-out animation (fast start -> slow finish)
+  IN_OUT, ///< Ease-in and Ease-out animation (slow start -> slow finish)
+};
+
+} // namespace EasingType
+
+} // namespace AnimationParameter
+
+} // namespace DevelAnimatedGradientVisual
+
+/**
+ *
+ */
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif
diff --git a/dali-toolkit/devel-api/visuals/visual-properties-devel.h b/dali-toolkit/devel-api/visuals/visual-properties-devel.h
new file mode 100644 (file)
index 0000000..019b632
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelVisual
+{
+
+/**
+ * @brief All the visual types.
+ */
+enum Type
+{
+  BORDER         = Dali::Toolkit::Visual::BORDER,
+  COLOR          = Dali::Toolkit::Visual::COLOR,
+  GRADIENT       = Dali::Toolkit::Visual::GRADIENT,
+  IMAGE          = Dali::Toolkit::Visual::IMAGE,
+  MESH           = Dali::Toolkit::Visual::MESH,
+  PRIMITIVE      = Dali::Toolkit::Visual::PRIMITIVE,
+  WIREFRAME      = Dali::Toolkit::Visual::WIREFRAME,
+  TEXT           = Dali::Toolkit::Visual::TEXT,
+  N_PATCH        = Dali::Toolkit::Visual::N_PATCH,
+  SVG            = Dali::Toolkit::Visual::SVG,
+  ANIMATED_IMAGE = Dali::Toolkit::Visual::ANIMATED_IMAGE,
+
+  ANIMATED_GRADIENT = ANIMATED_IMAGE + 1,  ///< Renders an animated gradient.
+};
+
+} // namespace DevelVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_VISUAL_PROPERTIES_DEVEL_H
index 3fa035e..b5c1aaf 100755 (executable)
@@ -21,6 +21,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/visuals/gradient/gradient.cpp \
    $(toolkit_src_dir)/visuals/gradient/linear-gradient.cpp \
    $(toolkit_src_dir)/visuals/gradient/radial-gradient.cpp \
+   $(toolkit_src_dir)/visuals/animated-gradient/animated-gradient-visual.cpp \
    $(toolkit_src_dir)/visuals/image-atlas-manager.cpp \
    $(toolkit_src_dir)/visuals/image/image-visual.cpp \
    $(toolkit_src_dir)/visuals/mesh/mesh-visual.cpp \
diff --git a/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp
new file mode 100755 (executable)
index 0000000..f20286c
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+//CLASS HEADER
+#include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+// non-animated property
+const char* const GRADIENT_TYPE_NAME("gradientType");
+const char* const UNIT_TYPE_NAME("unitType");
+const char* const SPREAD_TYPE_NAME("spreadType");
+// animated property
+const char* const START_POSITION_NAME("startPosition");
+const char* const START_COLOR_NAME("startColor");
+const char* const END_POSITION_NAME("endPosition");
+const char* const END_COLOR_NAME("endColor");
+const char* const ROTATE_CENTER_NAME("rotateCenter");
+const char* const ROTATE_AMOUNT_NAME("rotateAmount");
+const char* const OFFSET_NAME("offset");
+// animation parameter property
+const char* const START_VALUE_NAME("startValue");
+const char* const TARGET_VALUE_NAME("targetValue");
+const char* const DIRECTION_TYPE_NAME("directionType");
+const char* const DURATION_NAME("duration");
+const char* const DELAY_NAME("delay");
+const char* const REPEAT_NAME("repeat");
+const char* const REPEAT_DELAY_NAME("repeatDelay");
+const char* const MOTION_TYPE_NAME("motionType");
+const char* const EASING_TYPE_NAME("easingType");
+// common shader property
+const char* const UNIFORM_START_POINT_NAME("start_point");
+const char* const UNIFORM_START_COLOR_NAME("start_color");
+const char* const UNIFORM_END_POINT_NAME("end_point");
+const char* const UNIFORM_END_COLOR_NAME("end_color");
+const char* const UNIFORM_ROTATE_CENTER_NAME("rotate_center");
+const char* const UNIFORM_ROTATE_ANGLE_NAME("rotate_angle");
+const char* const UNIFORM_OFFSET_NAME("gradient_offset");
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( GRADIENT_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, LINEAR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, RADIAL )
+DALI_ENUM_TO_STRING_TABLE_END( GRADIENT_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( UNIT_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, OBJECT_BOUNDING_BOX )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, USER_SPACE )
+DALI_ENUM_TO_STRING_TABLE_END( UNIT_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( SPREAD_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REFLECT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REPEAT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, CLAMP )
+DALI_ENUM_TO_STRING_TABLE_END( SPREAD_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( DIRECTION_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, FORWARD )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, BACKWARD )
+DALI_ENUM_TO_STRING_TABLE_END( DIRECTION_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( MOTION_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, LOOP )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, MIRROR )
+DALI_ENUM_TO_STRING_TABLE_END( MOTION_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( EASING_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, LINEAR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, OUT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN_OUT )
+DALI_ENUM_TO_STRING_TABLE_END( EASING_TYPE )
+
+// Default values of each properties
+const Toolkit::DevelAnimatedGradientVisual::GradientType::Type DEFAULT_GRADIENT_TYPE = Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR;
+const Toolkit::DevelAnimatedGradientVisual::UnitType::Type     DEFAULT_UNIT_TYPE     = Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX;
+const Toolkit::DevelAnimatedGradientVisual::SpreadType::Type   DEFAULT_SPREAD_TYPE   = Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT;
+
+const float DEFAULT_START_POSITION[] = { -0.5f, 0.0f };
+const float DEFAULT_START_COLOR[]    = { 143.0f/255.0f, 170.0f/255.0f, 220.0f/255.0f, 255.0f/255.0f };
+const float DEFAULT_END_POSITION[]   = { 0.5f, 0.0f };
+const float DEFAULT_END_COLOR[]      = { 255.0f/255.0f, 163.0f/255.0f, 163.0f/255.0f, 255.0f/255.0f };
+const float DEFAULT_ROTATE_CENTER[]  = { 0.0f, 0.0f };
+const float DEFAULT_ROTATE_AMOUNT    = 0.0f;
+
+const float DEFAULT_ANIMATION_START_VALUE  = 0.0f;
+const float DEFAULT_ANIMATION_TARGET_VALUE = 0.0f;
+const float DEFAULT_ANIMATION_DURATION     = 3.0f;
+const float DEFAULT_ANIMATION_DELAY        = 0.0f;
+const int   DEFAULT_ANIMATION_REPEAT       = 0;
+const float DEFAULT_ANIMATION_REPEAT_DELAY = 0.0f;
+
+const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type DEFAULT_ANIMATION_DIRECTION_TYPE = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD;
+const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type    DEFAULT_ANIMATION_MOTION_TYPE    = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP;
+const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type    DEFAULT_ANIMATION_EASING_TYPE    = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR;
+
+const char* const BASIC_VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;
+  uniform mediump mat4 uMvpMatrix;
+  uniform mediump vec3 uSize;
+
+  uniform mediump vec2 start_point;
+  uniform mediump vec2 end_point;
+  uniform mediump vec2 rotate_center;
+  uniform mediump float rotate_angle;
+
+  varying mediump vec2 vTexCoord;
+  varying mediump vec2 vStart;
+  varying mediump vec2 vEnd;
+
+  vec2 rotate(vec2 x, vec2 c, float a)
+  {
+    vec2 d = x - c;
+    vec2 r = vec2(d.x * cos(a) - d.y * sin(a), d.x * sin(a) + d.y * cos(a));
+
+\n  #ifdef UNIT_TYPE_BOUNDING_BOX \n return r + c;             \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */
+\n  #ifdef UNIT_TYPE_USER         \n return (r + c) / uSize.x; \n #endif \n /* UnitType::USER_SPACE          */
+  }
+
+  //Visual size and offset
+  uniform mediump vec2 offset;
+  uniform mediump vec2 size;
+  uniform mediump vec4 offsetSizeMode;
+  uniform mediump vec2 origin;
+  uniform mediump vec2 anchorPoint;
+
+  vec4 ComputeVertexPosition()
+  {
+    vec2 visualSize = mix( uSize.xy*size, size, offsetSizeMode.zw );
+    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy );
+    return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );
+  }
+
+  void main()
+  {
+    vStart = rotate( start_point, rotate_center, rotate_angle );
+    vEnd = rotate( end_point, rotate_center, rotate_angle );
+    gl_Position = uMvpMatrix * ComputeVertexPosition();
+
+\n  #ifdef UNIT_TYPE_BOUNDING_BOX \n vTexCoord = vec2(aPosition.x, -aPosition.y);                     \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */
+\n  #ifdef UNIT_TYPE_USER         \n vTexCoord = vec2(aPosition.x, -aPosition.y * uSize.y / uSize.x); \n #endif \n /* UnitType::USER_SPACE          */
+  }
+);
+
+const char* const BASIC_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  precision mediump float;
+
+  uniform mediump vec4 start_color;
+  uniform mediump vec4 end_color;
+  uniform mediump float gradient_offset;
+
+  varying mediump vec2 vTexCoord;
+  varying mediump vec2 vStart;
+  varying mediump vec2 vEnd;
+
+  float get_position(vec2 x, vec2 s, vec2 e)
+  {
+    vec2 df = e - s;
+    vec2 dx = x - s;
+
+\n  #ifdef GRADIENT_TYPE_LINEAR \n return dot(dx,df)/dot(df,df);       \n #endif \n /* GradientType::LINEAR */
+\n  #ifdef GRADIENT_TYPE_RADIAL \n return sqrt(dot(dx,dx)/dot(df,df)); \n #endif \n /* GradientType::RADIAL */
+  }
+  float recalculate(float r)
+  {
+\n  #ifdef SPREAD_TYPE_REFLECT \n return 1.0 - abs(mod(r, 2.0) - 1.0); \n #endif \n /* SpreadType::REFLECT */
+\n  #ifdef SPREAD_TYPE_REPEAT  \n return fract(r);                     \n #endif \n /* SpreadType::REPEAT  */
+\n  #ifdef SPREAD_TYPE_CLAMP   \n return clamp(r, 0.0, 1.0);           \n #endif \n /* SpreadType::CLAMP   */
+  }
+
+  void main()
+  {
+    float r = get_position( vTexCoord, vStart, vEnd );
+    r = recalculate( r + gradient_offset );
+    vec4 color = mix( start_color, end_color, r );
+    gl_FragColor = color;
+  }
+);
+
+Property::Value GetStartValue( const Property::Map& map, Property::Index index, const char* const name )
+{
+  // Get start value of animation parameter
+  Property::Value* res = map.Find( index, name );
+  if( res )
+  {
+    Property::Map* s_map = res->GetMap();
+    if( s_map )
+    {
+      res = s_map->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, START_VALUE_NAME );
+      DALI_ASSERT_ALWAYS( res && "Start value is not setup in Property::Map" );
+    }
+  }
+  else
+  {
+    DALI_ASSERT_ALWAYS( !"Start value is not setup even default" );
+  }
+  return *res;
+}
+
+VisualFactoryCache::ShaderType GetShaderType( Toolkit::DevelAnimatedGradientVisual::GradientType::Type grad, Toolkit::DevelAnimatedGradientVisual::UnitType::Type unit, Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spread )
+{
+  return static_cast<VisualFactoryCache::ShaderType>(
+    VisualFactoryCache::ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT +
+    static_cast<unsigned int>( grad ) * 6 + // 6 is the number of UnitType * SpreadType
+    static_cast<unsigned int>( unit ) * 3 + // 3 is the number of SpreadType.
+    static_cast<unsigned int>( spread )
+  );
+}
+
+} // unnamed namespace
+
+AnimatedGradientVisualPtr AnimatedGradientVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
+{
+  AnimatedGradientVisualPtr animatedGradientVisualPtr( new AnimatedGradientVisual( factoryCache ) );
+  animatedGradientVisualPtr->SetProperties( properties );
+  return animatedGradientVisualPtr;
+}
+
+AnimatedGradientVisual::AnimatedGradientVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache )
+{
+  SetupDefaultValue();
+}
+
+AnimatedGradientVisual::~AnimatedGradientVisual()
+{
+
+}
+
+void AnimatedGradientVisual::SetupDefaultValue()
+{
+  mGradientType = DEFAULT_GRADIENT_TYPE;
+  mUnitType     = DEFAULT_UNIT_TYPE;
+  mSpreadType   = DEFAULT_SPREAD_TYPE;
+
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = Vector2( DEFAULT_START_POSITION );
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR]    = Vector4( DEFAULT_START_COLOR );
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION]   = Vector2( DEFAULT_END_POSITION );
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR]      = Vector4( DEFAULT_END_COLOR );
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER]  = Vector2( DEFAULT_ROTATE_CENTER );
+  mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT]  = DEFAULT_ROTATE_AMOUNT;
+  // Default Offset value is very special. unlimited animation from 0.0f to 2.0f
+  {
+    Property::Map map;
+    map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, 0.0f );
+    map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, 2.0f );
+    map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, -1 );
+
+    mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET] = map;
+  }
+}
+
+void AnimatedGradientVisual::DoSetProperties( const Property::Map& propertyMap )
+{
+  //GRADIENT_TYPE
+  Property::Value* gradientTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, GRADIENT_TYPE_NAME );
+  Toolkit::DevelAnimatedGradientVisual::GradientType::Type gradientType = mGradientType;
+  if( gradientTypeValue )
+  {
+    Scripting::GetEnumerationProperty( *gradientTypeValue, GRADIENT_TYPE_TABLE, GRADIENT_TYPE_TABLE_COUNT, gradientType );
+  }
+
+  //UNIT_TYPE
+  Property::Value* unitTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE, UNIT_TYPE_NAME );
+  Toolkit::DevelAnimatedGradientVisual::UnitType::Type unitType = mUnitType;
+  if( unitTypeValue )
+  {
+    Scripting::GetEnumerationProperty( *unitTypeValue, UNIT_TYPE_TABLE, UNIT_TYPE_TABLE_COUNT, unitType );
+  }
+
+  //SPREAD_TYPE
+  Property::Value* spreadTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, SPREAD_TYPE_NAME );
+  Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spreadType = mSpreadType;
+  if( spreadTypeValue )
+  {
+    Scripting::GetEnumerationProperty( *spreadTypeValue, SPREAD_TYPE_TABLE, SPREAD_TYPE_TABLE_COUNT, spreadType );
+  }
+
+  mGradientType = gradientType;
+  mUnitType = unitType;
+  mSpreadType = spreadType;
+
+  SetupGradientAnimationData(propertyMap);
+}
+
+void AnimatedGradientVisual::SetupGradientAnimationData( const Property::Map& propertyMap )
+{
+  mGradientAnimationDataList.Clear(); // Clear Transition Information. All animation will deleted safely
+
+  static Property::Map propertyNameMap;
+  static Property::Map propertyUniformNameMap;
+  if( propertyNameMap.Empty() )
+  {
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = START_POSITION_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   ] = START_COLOR_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  ] = END_POSITION_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     ] = END_COLOR_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = ROTATE_CENTER_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = ROTATE_AMOUNT_NAME;
+    propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        ] = OFFSET_NAME;
+  }
+  if( propertyUniformNameMap.Empty() )
+  {
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = UNIFORM_START_POINT_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   ] = UNIFORM_START_COLOR_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  ] = UNIFORM_END_POINT_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     ] = UNIFORM_END_COLOR_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = UNIFORM_ROTATE_CENTER_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = UNIFORM_ROTATE_ANGLE_NAME;
+    propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        ] = UNIFORM_OFFSET_NAME;
+  }
+
+  Property::Map::SizeType map_index_end = propertyNameMap.Count();
+  for( Property::Map::SizeType map_index = 0; map_index < map_index_end; map_index++ )
+  {
+    KeyValuePair property_pair = propertyNameMap.GetKeyValue( map_index );
+    KeyValuePair uniform_pair = propertyUniformNameMap.GetKeyValue( map_index );
+    Property::Index index = property_pair.first.indexKey;
+    const std::string property_name = property_pair.second.Get< std::string >();
+    const std::string uniform_name = uniform_pair.second.Get< std::string >();
+
+    Property::Map map;
+    Property::Value default_value = mValueMap[index];
+
+    map["target"] = "background";
+    map["property"] = uniform_name;
+
+    Property::Value *value = propertyMap.Find( index, property_name );
+    if( !value )
+    {
+      value = &default_value;
+    }
+    else
+    {
+      // Update value list
+      mValueMap[index] = (*value);
+    }
+
+    int loop_count = 0;
+    float delay = 0.0f;
+    bool forward = true;
+    bool auto_mirror = false;
+    std::string ease_str = "LINEAR";
+    Property::Map *map_value = value->GetMap();
+    if( map_value )
+    {
+      auto getValueFromMap = [ &map_value ]( const Property::Index& index, const std::string& name, Property::Value& res ) -> void
+      {
+        Property::Value *sub_value = map_value->Find( index, name );
+        if( sub_value )
+        {
+          res = *sub_value;
+        }
+      };
+
+      Property::Value value_start        = DEFAULT_ANIMATION_START_VALUE;
+      Property::Value value_target       = DEFAULT_ANIMATION_TARGET_VALUE;
+      Property::Value value_duration     = DEFAULT_ANIMATION_DURATION;
+      Property::Value value_delay        = DEFAULT_ANIMATION_DELAY;
+      Property::Value value_repeat       = DEFAULT_ANIMATION_REPEAT;
+      Property::Value value_repeat_delay = DEFAULT_ANIMATION_REPEAT_DELAY;
+
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START       , START_VALUE_NAME   , value_start );
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET      , TARGET_VALUE_NAME  , value_target );
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION    , DURATION_NAME      , value_duration );
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY       , DELAY_NAME         , value_delay );
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT      , REPEAT_NAME        , value_repeat );
+      getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, REPEAT_DELAY_NAME  , value_repeat_delay );
+
+      Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type direction_type = DEFAULT_ANIMATION_DIRECTION_TYPE;
+      Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type    motion_type    = DEFAULT_ANIMATION_MOTION_TYPE;
+      Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type    easing_type    = DEFAULT_ANIMATION_EASING_TYPE;
+
+      Property::Value *direction_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DIRECTION_TYPE_NAME );
+      if( direction_sub_value )
+      {
+        Scripting::GetEnumerationProperty( *direction_sub_value, DIRECTION_TYPE_TABLE, DIRECTION_TYPE_TABLE_COUNT, direction_type );
+      }
+      Property::Value *motion_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, MOTION_TYPE_NAME );
+      if( motion_sub_value )
+      {
+        Scripting::GetEnumerationProperty( *motion_sub_value   , MOTION_TYPE_TABLE   , MOTION_TYPE_TABLE_COUNT   , motion_type );
+      }
+      Property::Value *easing_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, EASING_TYPE_NAME );
+      if( easing_sub_value )
+      {
+        Scripting::GetEnumerationProperty( *easing_sub_value   , EASING_TYPE_TABLE   , EASING_TYPE_TABLE_COUNT   , easing_type );
+      }
+
+      forward = ( direction_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
+      delay = value_delay.Get< float >();
+      loop_count = value_repeat.Get< int >();
+      auto_mirror = ( motion_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
+
+      switch( easing_type )
+      {
+        case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR:
+        {
+          ease_str = "LINEAR";
+          break;
+        }
+        case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN:
+        {
+          ease_str = "EASE_IN_SQUARE";
+          break;
+        }
+        case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT:
+        {
+          ease_str = "EASE_OUT_SQUARE";
+          break;
+        }
+        case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT:
+        {
+          ease_str = "EASE_IN_OUT";
+          break;
+        }
+      }
+
+      map["initialValue"] = forward ? value_start : value_target;
+      map["targetValue"] = forward ? value_target : value_start;
+      if( loop_count != 0 )
+      {
+        map["animator"] = Property::Map()
+                          .Add( "alphaFunction", ease_str )
+                          .Add( "timePeriod", Property::Map()
+                                             .Add( "delay", value_repeat_delay.Get< float >() )
+                                             .Add( "duration", value_duration.Get< float >() ) );
+      }
+    }
+    else
+    {
+      map["initialValue"] = *value;
+      map["targetValue"] = *value;
+    }
+
+    AnimatedGradientVisual::GradientAnimationData *animData = new AnimatedGradientVisual::GradientAnimationData();
+    animData->transition = Toolkit::TransitionData::New( map );
+    animData->index = index;
+    animData->loop_count = loop_count;
+    animData->delay = delay;
+    animData->forward = forward;
+    animData->auto_mirror = auto_mirror;
+    mGradientAnimationDataList.PushBack( animData );
+  }
+}
+
+void AnimatedGradientVisual::SetupAnimation()
+{
+  for( auto&& elem : mGradientAnimationDataList )
+  {
+    Toolkit::TransitionData& transition = elem->transition;
+    Animation& animation = elem->animation;
+    int loop_count = elem->loop_count;
+    bool auto_mirror = elem->auto_mirror;
+    bool without_animation = ( loop_count == 0 );
+
+    const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition );
+    for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ )
+    {
+      TransitionData::Animator *animator = (*iter);
+      AnimateProperty( animation, *animator );
+    }
+    if( animation && !without_animation )
+    {
+      if( loop_count < 0 )
+      {
+        animation.SetLooping( true );
+      }
+      else if( loop_count > 0 )
+      {
+        animation.SetLoopCount( loop_count );
+      }
+      if( auto_mirror )
+      {
+        animation.SetLoopingMode( Animation::LoopingMode::AUTO_REVERSE );
+      }
+    }
+  }
+}
+
+void AnimatedGradientVisual::PlayAnimation()
+{
+  for( auto&& elem : mGradientAnimationDataList )
+  {
+    Animation& animation = elem->animation;
+    if( animation )
+    {
+      float delay = elem->delay;
+      if( delay > 0.0f )
+      {
+        animation.PlayAfter( delay );
+      }
+      else if( delay < 0.0f )
+      {
+        float progress = -delay / animation.GetDuration(); // (duration + repeat_duration)
+        if(progress >= 1.0f)
+        {
+          int cur_loop = animation.GetLoopCount();
+          int decrease_loop = floor( progress ) + 1;
+          while( decrease_loop > progress )
+          {
+            decrease_loop--;
+          }
+          progress -= decrease_loop;
+          if( cur_loop == 0 )
+          {
+            animation.PlayFrom( progress );
+          }
+          else
+          {
+            cur_loop -= decrease_loop;
+            if( cur_loop > 0 )
+            {
+              animation.SetLoopCount( cur_loop );
+              animation.PlayFrom( progress );
+            }
+            else
+            {
+              // animation done. make this animation finished safely.
+              animation.SetLoopCount( 1 );
+              animation.PlayFrom( 1.0f );
+            }
+          }
+        }
+        else
+        {
+          animation.PlayFrom( progress );
+        }
+      }
+      else
+      {
+        animation.Play();
+      }
+    }
+  }
+}
+
+void AnimatedGradientVisual::StopAnimation()
+{
+  for( auto&& elem : mGradientAnimationDataList )
+  {
+    Animation& animation = elem->animation;
+    if( animation )
+    {
+      animation.Stop();
+    }
+  }
+}
+
+void AnimatedGradientVisual::OnSetTransform()
+{
+  if( mImpl->mRenderer )
+  {
+    mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+  }
+}
+
+void AnimatedGradientVisual::DoSetOnStage( Actor& actor )
+{
+  InitializeRenderer();
+  actor.AddRenderer( mImpl->mRenderer );
+  SetupAnimation();
+  PlayAnimation();
+
+  ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+}
+
+void AnimatedGradientVisual::DoSetOffStage( Actor& actor )
+{
+  DALI_ASSERT_DEBUG( (bool)mImpl->mRenderer && "There should always be a renderer whilst on stage");
+
+  StopAnimation();
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
+}
+
+void AnimatedGradientVisual::DoCreatePropertyMap( Property::Map& map ) const
+{
+  map.Clear();
+  map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_GRADIENT );
+
+  //Create non-animated properties
+  map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, static_cast<int>(mGradientType) );
+  map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE    , static_cast<int>(mUnitType) );
+  map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE  , static_cast<int>(mSpreadType) );
+
+  //Create animated properties. Get from transition for more realistic test. Not from animation cause Animation may not setuped
+  for( auto&& elem : mGradientAnimationDataList )
+  {
+    Toolkit::TransitionData& transition = elem->transition;
+    Property::Index index = elem->index;
+    int loop_count = elem->loop_count;
+    float delay = elem->delay;
+    bool forward = elem->forward;
+    bool auto_mirror = elem->auto_mirror;
+
+    const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition );
+    for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ )
+    {
+      TransitionData::Animator *animator = (*iter);
+      if( animator->animate )
+      {
+        //with animation
+        Property::Map animation_map;
+        Property::Value value_start = forward ? animator->initialValue : animator->targetValue;
+        Property::Value value_target = forward ? animator->targetValue : animator->initialValue;
+        Property::Value value_direction;
+        Property::Value value_duration = Property::Value( animator->timePeriodDuration );
+        Property::Value value_delay = Property::Value( delay );
+        Property::Value value_repeat = Property::Value( loop_count );
+        Property::Value value_repeat_delay = Property::Value( animator->timePeriodDelay );
+        Property::Value value_motion_type;
+        Property::Value value_easing_type;
+
+        if( forward )
+        {
+          value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
+        }
+        else
+        {
+          value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
+        }
+        if( auto_mirror )
+        {
+          value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
+        }
+        else
+        {
+          value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP );
+        }
+        switch( animator->alphaFunction.GetBuiltinFunction() )
+        {
+          case Dali::AlphaFunction::LINEAR:
+          {
+            value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
+            break;
+          }
+          case Dali::AlphaFunction::EASE_IN_SQUARE:
+          {
+            value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN );
+            break;
+          }
+          case Dali::AlphaFunction::EASE_OUT_SQUARE:
+          {
+            value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT );
+            break;
+          }
+          case Dali::AlphaFunction::EASE_IN_OUT:
+          {
+            value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT );
+            break;
+          }
+          default:
+          {
+            value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
+          }
+        }
+
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START       , value_start );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET      , value_target );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION   , value_direction );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION    , value_duration );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY       , value_delay );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT      , value_repeat );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, value_repeat_delay );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE , value_motion_type );
+        animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE , value_easing_type );
+
+        map.Insert( index, animation_map );
+      }
+      else
+      {
+        //without animation
+        map.Insert( index, animator->targetValue );
+      }
+    }
+  }
+}
+
+void AnimatedGradientVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
+{
+
+}
+
+Shader AnimatedGradientVisual::CreateShader()
+{
+  Shader shader;
+
+  std::string tagUnit;
+  std::string tagGrad;
+  std::string tagSpread;
+  switch( mUnitType )
+  {
+    case Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX:
+    {
+      tagUnit = "UNIT_TYPE_BOUNDING_BOX";
+      break;
+    }
+    case Toolkit::DevelAnimatedGradientVisual::UnitType::USER_SPACE:
+    {
+      tagUnit = "UNIT_TYPE_USER";
+      break;
+    }
+  }
+  switch( mGradientType )
+  {
+    case Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR:
+    {
+      tagGrad = "GRADIENT_TYPE_LINEAR";
+      break;
+    }
+    case Toolkit::DevelAnimatedGradientVisual::GradientType::RADIAL:
+    {
+      tagGrad = "GRADIENT_TYPE_RADIAL";
+      break;
+    }
+  }
+  switch( mSpreadType )
+  {
+    case Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT:
+    {
+      tagSpread = "SPREAD_TYPE_REFLECT";
+      break;
+    }
+    case Toolkit::DevelAnimatedGradientVisual::SpreadType::REPEAT:
+    {
+      tagSpread = "SPREAD_TYPE_REPEAT";
+      break;
+    }
+    case Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP:
+    {
+      tagSpread = "SPREAD_TYPE_CLAMP";
+      break;
+    }
+  }
+
+  std::string vert;
+  std::string frag;
+
+  vert = "#define " + tagUnit + "\n"
+       + BASIC_VERTEX_SHADER;
+  frag = "#define " + tagGrad + "\n"
+       + "#define " + tagSpread + "\n"
+       + BASIC_FRAGMENT_SHADER;
+
+  shader = Shader::New( vert, frag );
+  return shader;
+}
+
+void AnimatedGradientVisual::InitializeRenderer()
+{
+  Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
+  VisualFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, mUnitType, mSpreadType );
+  Shader shader = mFactoryCache.GetShader( shaderType );
+  if( !shader )
+  {
+    shader = CreateShader();
+    mFactoryCache.SaveShader( shaderType, shader );
+  }
+
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+
+  mImpl->mRenderer.RegisterProperty( UNIFORM_START_POINT_NAME  , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, START_POSITION_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_START_COLOR_NAME  , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   , START_COLOR_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_END_POINT_NAME    , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  , END_POSITION_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_END_COLOR_NAME    , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     , END_COLOR_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_CENTER_NAME, GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER , ROTATE_CENTER_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_ANGLE_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , ROTATE_AMOUNT_NAME ) );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_OFFSET_NAME       , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        , OFFSET_NAME ) );
+
+  //Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+}
+
+}//namespace Internal
+
+}//namespace Toolkit
+
+}//namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h b/dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h
new file mode 100755 (executable)
index 0000000..ab480d9
--- /dev/null
@@ -0,0 +1,281 @@
+#ifndef DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H
+#define DALI_TOOLKIT_INTERNAL_ANIMATED_GRADIENT_VISUAL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/devel-api/common/owner-container.h>
+#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
+
+//INTERNAL INCLUDES
+#include <dali/devel-api/scripting/enum-helper.h>
+#include <dali/devel-api/scripting/scripting.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+class AnimatedGradientVisual;
+typedef IntrusivePtr< AnimatedGradientVisual > AnimatedGradientVisualPtr;
+
+/**
+ * This visual which renders smooth transition of colors to the control's quad.
+ * There are two types of properties: non-animated property and animated property
+ *
+ * The following properties are non-animated property.
+ *
+ * | %Property Name | Type         | Default                   |
+ * |----------------|--------------|---------------------------|
+ * | gradientType   | GradientType | Linear                    |
+ * | unitType       | UnitType     | Object bounding box       |
+ * | spreadType     | SpreadType   | Reflect                   |
+ *
+ * The following properties are animated property.
+ *
+ * | %Property Name | Type                                     | Default                         |
+ * |----------------|------------------------------------------|---------------------------------|
+ * | startPosition  | Vector2 or AnimationParameter< Vector2 > | (-0.5, 0)                       |
+ * | startColor     | Vector4 or AnimationParameter< Vector4 > | (143., 170., 220., 255.) / 255. |
+ * | endPosition    | Vector2 or AnimationParameter< Vector2 > | (0.5, 0)                        |
+ * | endColor       | Vector4 or AnimationParameter< Vector4 > | (255., 163., 163., 255.) / 255. |
+ * | rotateCenter   | Vector2 or AnimationParameter< Vector2 > | (0.0, 0.0)                      |
+ * | rotateAmount   | Float   or AnimationParameter< Float >   | 0.0                             |
+ * | offset         | Float   or AnimationParameter< Float >   | (explain details below)         |
+ *
+ * Each animated property can contain follow AnimationParameter
+ *
+ * | %AnimationParameter<T>::Propery Name | Type          | Default  |
+ * |--------------------------------------|---------------|----------|
+ * | start                                | T             | Zero     |
+ * | target                               | T             | Zero     |
+ * | direction                            | DirectionType | Forward  |
+ * | duration                             | Float         | 3.0      |
+ * | delay                                | Float         | 0.0      |
+ * | repeat                               | Integer       | 0        |
+ * | repeat_delay                         | Float         | 0.0      |
+ * | motion_type                          | MotionType    | Loop     |
+ * | easing_type                          | EasingType    | Linear   |
+ *
+ * T is animated property value's type. If property type is AnimationParameter< Vector2 >, start and target type is Vector2.
+ *
+ *
+ * gradientType decide the form of gradient
+ * unitType decide the coordinate of all positions
+ * spreadType decide how to make color where gradient_point is not 0 ~ 1
+ * visualSize decide this visual's size hardly. only use when unitType is SCREEN
+ *
+ * startPoint and startColor decide position and color where gradient_point = 0. if gradientType is RADIAL, here is center of circle.
+ * endPoint and endColor  decide position and color where gradient_point = 1.
+ * rotateCenter and rotateAmount are same job as its name
+ * rotateAmount is radian value
+ *
+ * offset is main feature of this visual.
+ * Image the points which has same gradient_point values. If gradientType is LINEAR, this form is line. If gradientTYPE IS RADIAL, this form is circle.
+ * without think about offset value, gradient_point = t color will be like this
+ *
+ *  color(t) = startColor * (1-t) + endColor * t (0 <= t <= 1)
+ *
+ * so color be smooth changed when gradient_point change smooth.
+ * offset value change the color of gradient_point = t like this
+ *
+ *  realColor(t) = color(t + offset)
+ *
+ * so If offset value increas (or decrease) gradient looks like "Flowing" effect
+ * default offset value is an unlimited simple loop animation from 0 to 2. duration is 3.0 second
+ *
+ * GradientType has two types : LINEAR / RADIAL
+ *  LINEAR draw gradient linear form
+ *  RADIAL draw gradietn circle form
+ * UnitType has two types : OBJECT_BOUNDING_BOX / USER_SPACE
+ *  OBJECT_BOUNDING_BOX use normalized coordinate, relate by Actor bounding box. bottom-left ~ top-right : (-0.5,-0.5) ~ (0.5, 0.5)
+ *  USER_SPACE use coordinate, relate by Actor Size. bottom-left ~ top-right : (ActorSize * -0.5) ~ (ActorSize * 0.5)
+ * SpreadType has three types : REFLECT / REPEAT / CLAMP
+ *  REFLECT use mirror warping
+ *  REPEAT use repeat warping
+ *  CLAMP use clamp warping
+ *
+ * DirectionType has two types : FORWARD / BACKWARD
+ *  FORWARD animate value from start to target
+ *  BACKWARD animate value from target to start
+ * MotionType has two types : LOOP / MIRROR
+ *  LOOP animate loopingmode restart
+ *  MIRROR animate loopingmode auto_reverse
+ * EasingType has four types : LINEAR / IN / OUT / IN_OUT
+ *  LINEAR easing animation linear
+ *  IN easing in (slow start -> fast finish)
+ *  OUT easing out (fast start -> slow finish)
+ *  IN_OUT easing in and out (slow start -> slow finish)
+ */
+class AnimatedGradientVisual : public Visual::Base
+{
+public:
+
+  /**
+   * Animation informations what this visual using
+   */
+  struct GradientAnimationData
+  {
+   GradientAnimationData()
+    : index( Property::INVALID_INDEX ),
+      loop_count( 0 ),
+      delay( 0.0f ),
+      forward( false ),
+      auto_mirror( false )
+    {
+    }
+
+    Toolkit::TransitionData transition;
+    Animation animation;
+    Property::Index index;
+    int loop_count;   ///< if < 0, loop unlimited. else, loop loop_count times.
+    float delay;      ///< delay time. if > 0, wait 'delay' seconds. else, play animation at '-delay' seconds.
+    bool forward;     ///< True if AnimationParameter::DirectionType::Type is FORWARD
+    bool auto_mirror; ///< True if AnimationParameter::LoopType::Type is MIRROR
+  };
+
+  using GradientAnimationDataList =  Dali::OwnerContainer< GradientAnimationData* >;
+
+public:
+
+  /**
+   * @brief Create a new animated gradient visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] properties A Property::Map containing settings for this visual
+   * @return A smart-pointer to the newly allocated visual
+   */
+  static AnimatedGradientVisualPtr New( VisualFactoryCache& factoryCache, const Property::Map& properties );
+
+private: //from Visual
+
+  /**
+   * @copydoc Visual::Base::CreatePropertyMap
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
+  /**
+   * @copydoc Visual::Base::CreateInstancePropertyMap
+   */
+  virtual void DoCreateInstancePropertyMap( Property::Map& map ) const;
+
+protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  AnimatedGradientVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unrefecence()
+   */
+  virtual ~AnimatedGradientVisual();
+
+protected: //from Visual
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
+
+  /**
+   * @copydoc Visual::Base::OnSetTransform
+   */
+  virtual void OnSetTransform();
+
+  /**
+   * @copydoc Visual::Base::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+  /**
+   * @copydoc Visual::Base::DoSetOffStage
+   */
+  virtual void DoSetOffStage( Actor& actor );
+
+private:
+
+  /**
+   * @brief Initialize the default value of properies.
+   */
+  void SetupDefaultValue();
+
+  /**
+   * @brief Initialize the rendere with the geometry from the cache, and shader which made by CreateShader()
+   */
+  void InitializeRenderer();
+
+  /**
+   * @brief Make animations with GradientAnimationData
+   */
+  void SetupAnimation();
+
+  /**
+  * @brief Play animations
+  */
+  void PlayAnimation();
+
+  /**
+  * @brief Stop animations
+  */
+  void StopAnimation();
+
+  /**
+   * @brief Clear all previous GradientAnimationData and Setup new GradientAnimationData information which made by animated properties
+   *
+   * param[in] propertyMap A Property::Map come from DoSetProperties
+   */
+  void SetupGradientAnimationData( const Property::Map& propertyMap );
+
+  /**
+   * @brief Create new shader
+   *
+   * return A Shader which made by non-animated properties
+   */
+  Shader CreateShader();
+
+  // Undefined
+  AnimatedGradientVisual( const AnimatedGradientVisual& gradientRenderer );
+
+  // Undefined
+  AnimatedGradientVisual& operator=( const AnimatedGradientVisual& gradientRenderer );
+
+private:
+  GradientAnimationDataList mGradientAnimationDataList;
+  Property::Map mValueMap;
+
+  Dali::Toolkit::DevelAnimatedGradientVisual::GradientType::Type mGradientType;
+  Dali::Toolkit::DevelAnimatedGradientVisual::UnitType::Type mUnitType;
+  Dali::Toolkit::DevelAnimatedGradientVisual::SpreadType::Type mSpreadType;
+};
+
+}//namespace Internal
+
+}//namespace Toolkit
+
+}//namespace Dali
+
+#endif
index 75c949e..7f13da6 100644 (file)
@@ -74,6 +74,18 @@ public:
     TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE,
     TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI,
     TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI,
+    ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT,
+    ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REPEAT,
+    ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_CLAMP,
+    ANIMATED_GRADIENT_SHADER_LINEAR_USER_REFLECT,
+    ANIMATED_GRADIENT_SHADER_LINEAR_USER_REPEAT,
+    ANIMATED_GRADIENT_SHADER_LINEAR_USER_CLAMP,
+    ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_REFLECT,
+    ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_REPEAT,
+    ANIMATED_GRADIENT_SHADER_RADIAL_BOUNDING_CLAMP,
+    ANIMATED_GRADIENT_SHADER_RADIAL_USER_REFLECT,
+    ANIMATED_GRADIENT_SHADER_RADIAL_USER_REPEAT,
+    ANIMATED_GRADIENT_SHADER_RADIAL_USER_CLAMP,
     WIREFRAME_SHADER,
     SHADER_TYPE_MAX = WIREFRAME_SHADER
   };
index 826de69..c368580 100644 (file)
 #include <dali/devel-api/scripting/scripting.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/internal/visuals/border/border-visual.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
 #include <dali-toolkit/internal/visuals/gradient/gradient-visual.h>
+#include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
 #include <dali-toolkit/internal/visuals/image/image-visual.h>
 #include <dali-toolkit/internal/visuals/mesh/mesh-visual.h>
 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
@@ -88,7 +90,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
   Visual::BasePtr visualPtr;
 
   Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE );
-  Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type.
+  Toolkit::DevelVisual::Type visualType = Toolkit::DevelVisual::IMAGE; // Default to IMAGE type.
   if( typeValue )
   {
     Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType );
@@ -230,6 +232,12 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
       }
       break;
     }
+
+    case Toolkit::DevelVisual::ANIMATED_GRADIENT:
+    {
+      visualPtr = AnimatedGradientVisual::New( *( mFactoryCache.Get() ), propertyMap );
+      break;
+    }
   }
 
   if( !visualPtr )
@@ -237,7 +245,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
     DALI_LOG_ERROR( "Renderer type unknown\n" );
   }
 
-  if( mDebugEnabled && visualType !=  Toolkit::Visual::WIREFRAME )
+  if( mDebugEnabled && visualType !=  Toolkit::DevelVisual::WIREFRAME )
   {
     //Create a WireframeVisual if we have debug enabled
     visualPtr = WireframeVisual::New( *( mFactoryCache.Get() ), visualPtr, propertyMap );
index e28a910..661e251 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 
 namespace Dali
 {
@@ -42,6 +43,7 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, N_PATCH )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, SVG )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, ANIMATED_IMAGE )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, WIREFRAME )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, ANIMATED_GRADIENT )
 DALI_ENUM_TO_STRING_TABLE_END( VISUAL_TYPE )
 
 // Visual Type