Merge "Add a TextEditor property to limit input to maximum characters" into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-gradient / animated-gradient-visual.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 //CLASS HEADER
18 #include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
19
20 //INTERNAL INCLUDES
21 #include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
22 #include <dali-toolkit/public-api/visuals/visual-properties.h>
23 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
24 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
25 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
26 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
27 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40 DALI_ENUM_TO_STRING_TABLE_BEGIN( GRADIENT_TYPE )
41 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, LINEAR )
42 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::GradientType, RADIAL )
43 DALI_ENUM_TO_STRING_TABLE_END( GRADIENT_TYPE )
44
45 DALI_ENUM_TO_STRING_TABLE_BEGIN( UNIT_TYPE )
46 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, OBJECT_BOUNDING_BOX )
47 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::UnitType, USER_SPACE )
48 DALI_ENUM_TO_STRING_TABLE_END( UNIT_TYPE )
49
50 DALI_ENUM_TO_STRING_TABLE_BEGIN( SPREAD_TYPE )
51 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REFLECT )
52 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, REPEAT )
53 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::SpreadType, CLAMP )
54 DALI_ENUM_TO_STRING_TABLE_END( SPREAD_TYPE )
55
56 DALI_ENUM_TO_STRING_TABLE_BEGIN( DIRECTION_TYPE )
57 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, FORWARD )
58 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType, BACKWARD )
59 DALI_ENUM_TO_STRING_TABLE_END( DIRECTION_TYPE )
60
61 DALI_ENUM_TO_STRING_TABLE_BEGIN( MOTION_TYPE )
62 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, LOOP )
63 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType, MIRROR )
64 DALI_ENUM_TO_STRING_TABLE_END( MOTION_TYPE )
65
66 DALI_ENUM_TO_STRING_TABLE_BEGIN( EASING_TYPE )
67 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, LINEAR )
68 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN )
69 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, OUT )
70 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType, IN_OUT )
71 DALI_ENUM_TO_STRING_TABLE_END( EASING_TYPE )
72
73 // Default values of each properties
74 const Toolkit::DevelAnimatedGradientVisual::GradientType::Type DEFAULT_GRADIENT_TYPE = Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR;
75 const Toolkit::DevelAnimatedGradientVisual::UnitType::Type     DEFAULT_UNIT_TYPE     = Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX;
76 const Toolkit::DevelAnimatedGradientVisual::SpreadType::Type   DEFAULT_SPREAD_TYPE   = Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT;
77
78 const float DEFAULT_START_POSITION[] = { -0.5f, 0.0f };
79 const float DEFAULT_START_COLOR[]    = { 143.0f/255.0f, 170.0f/255.0f, 220.0f/255.0f, 255.0f/255.0f };
80 const float DEFAULT_END_POSITION[]   = { 0.5f, 0.0f };
81 const float DEFAULT_END_COLOR[]      = { 255.0f/255.0f, 163.0f/255.0f, 163.0f/255.0f, 255.0f/255.0f };
82 const float DEFAULT_ROTATE_CENTER[]  = { 0.0f, 0.0f };
83 const float DEFAULT_ROTATE_AMOUNT    = 0.0f;
84
85 const float DEFAULT_ANIMATION_START_VALUE  = 0.0f;
86 const float DEFAULT_ANIMATION_TARGET_VALUE = 0.0f;
87 const float DEFAULT_ANIMATION_DURATION     = 3.0f;
88 const float DEFAULT_ANIMATION_DELAY        = 0.0f;
89 const int   DEFAULT_ANIMATION_REPEAT       = 0;
90 const float DEFAULT_ANIMATION_REPEAT_DELAY = 0.0f;
91
92 const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type DEFAULT_ANIMATION_DIRECTION_TYPE = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD;
93 const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type    DEFAULT_ANIMATION_MOTION_TYPE    = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP;
94 const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type    DEFAULT_ANIMATION_EASING_TYPE    = Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR;
95
96 const char* const BASIC_VERTEX_SHADER = DALI_COMPOSE_SHADER(
97   attribute mediump vec2 aPosition;
98   uniform highp   mat4 uMvpMatrix;
99   uniform mediump vec3 uSize;
100
101   uniform mediump vec2 start_point;
102   uniform mediump vec2 end_point;
103   uniform mediump vec2 rotate_center;
104   uniform mediump float rotate_angle;
105
106   varying mediump vec2 vTexCoord;
107   varying mediump vec2 vStart;
108   varying mediump vec2 vEnd;
109
110   vec2 rotate(vec2 x, vec2 c, float a)
111   {
112     vec2 d = x - c;
113     vec2 r = vec2(d.x * cos(a) - d.y * sin(a), d.x * sin(a) + d.y * cos(a));
114
115 \n  #ifdef UNIT_TYPE_BOUNDING_BOX \n return r + c;             \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */
116 \n  #ifdef UNIT_TYPE_USER         \n return (r + c) / uSize.x; \n #endif \n /* UnitType::USER_SPACE          */
117   }
118
119   //Visual size and offset
120   uniform mediump vec2 offset;
121   uniform mediump vec2 size;
122   uniform mediump vec4 offsetSizeMode;
123   uniform mediump vec2 origin;
124   uniform mediump vec2 anchorPoint;
125
126   vec4 ComputeVertexPosition()
127   {
128     vec2 visualSize = mix( uSize.xy*size, size, offsetSizeMode.zw );
129     vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy );
130     return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );
131   }
132
133   void main()
134   {
135     vStart = rotate( start_point, rotate_center, rotate_angle );
136     vEnd = rotate( end_point, rotate_center, rotate_angle );
137     gl_Position = uMvpMatrix * ComputeVertexPosition();
138
139 \n  #ifdef UNIT_TYPE_BOUNDING_BOX \n vTexCoord = vec2(aPosition.x, -aPosition.y);                     \n #endif \n /* UnitType::OBJECT_BOUNDING_BOX */
140 \n  #ifdef UNIT_TYPE_USER         \n vTexCoord = vec2(aPosition.x, -aPosition.y * uSize.y / uSize.x); \n #endif \n /* UnitType::USER_SPACE          */
141   }
142 );
143
144 const char* const BASIC_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
145   precision mediump float;
146
147   uniform mediump vec4 start_color;
148   uniform mediump vec4 end_color;
149   uniform mediump float gradient_offset;
150
151   varying mediump vec2 vTexCoord;
152   varying mediump vec2 vStart;
153   varying mediump vec2 vEnd;
154
155   float get_position(vec2 x, vec2 s, vec2 e)
156   {
157     vec2 df = e - s;
158     vec2 dx = x - s;
159
160 \n  #ifdef GRADIENT_TYPE_LINEAR \n return dot(dx,df)/dot(df,df);       \n #endif \n /* GradientType::LINEAR */
161 \n  #ifdef GRADIENT_TYPE_RADIAL \n return sqrt(dot(dx,dx)/dot(df,df)); \n #endif \n /* GradientType::RADIAL */
162   }
163   float recalculate(float r)
164   {
165 \n  #ifdef SPREAD_TYPE_REFLECT \n return 1.0 - abs(mod(r, 2.0) - 1.0); \n #endif \n /* SpreadType::REFLECT */
166 \n  #ifdef SPREAD_TYPE_REPEAT  \n return fract(r);                     \n #endif \n /* SpreadType::REPEAT  */
167 \n  #ifdef SPREAD_TYPE_CLAMP   \n return clamp(r, 0.0, 1.0);           \n #endif \n /* SpreadType::CLAMP   */
168   }
169
170   void main()
171   {
172     float r = get_position( vTexCoord, vStart, vEnd );
173     r = recalculate( r + gradient_offset );
174     vec4 color = mix( start_color, end_color, r );
175     gl_FragColor = color;
176   }
177 );
178
179 Property::Value GetStartValue( const Property::Map& map, Property::Index index, const char* const name )
180 {
181   // Get start value of animation parameter
182   Property::Value* res = map.Find( index, name );
183   if( res )
184   {
185     Property::Map* s_map = res->GetMap();
186     if( s_map )
187     {
188       res = s_map->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, START_VALUE_NAME );
189       DALI_ASSERT_ALWAYS( res && "Start value is not setup in Property::Map" );
190     }
191   }
192   else
193   {
194     DALI_ASSERT_ALWAYS( !"Start value is not setup even default" );
195   }
196   return *res;
197 }
198
199 VisualFactoryCache::ShaderType GetShaderType( Toolkit::DevelAnimatedGradientVisual::GradientType::Type grad, Toolkit::DevelAnimatedGradientVisual::UnitType::Type unit, Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spread )
200 {
201   return static_cast<VisualFactoryCache::ShaderType>(
202     VisualFactoryCache::ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT +
203     static_cast<unsigned int>( grad ) * 6 + // 6 is the number of UnitType * SpreadType
204     static_cast<unsigned int>( unit ) * 3 + // 3 is the number of SpreadType.
205     static_cast<unsigned int>( spread )
206   );
207 }
208
209 } // unnamed namespace
210
211 AnimatedGradientVisualPtr AnimatedGradientVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
212 {
213   AnimatedGradientVisualPtr animatedGradientVisualPtr( new AnimatedGradientVisual( factoryCache ) );
214   animatedGradientVisualPtr->SetProperties( properties );
215   return animatedGradientVisualPtr;
216 }
217
218 AnimatedGradientVisual::AnimatedGradientVisual( VisualFactoryCache& factoryCache )
219 : Visual::Base( factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>( Toolkit::DevelVisual::ANIMATED_GRADIENT ) )
220 {
221   SetupDefaultValue();
222 }
223
224 AnimatedGradientVisual::~AnimatedGradientVisual()
225 {
226
227 }
228
229 void AnimatedGradientVisual::SetupDefaultValue()
230 {
231   mGradientType = DEFAULT_GRADIENT_TYPE;
232   mUnitType     = DEFAULT_UNIT_TYPE;
233   mSpreadType   = DEFAULT_SPREAD_TYPE;
234
235   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = Vector2( DEFAULT_START_POSITION );
236   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR]    = Vector4( DEFAULT_START_COLOR );
237   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION]   = Vector2( DEFAULT_END_POSITION );
238   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR]      = Vector4( DEFAULT_END_COLOR );
239   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER]  = Vector2( DEFAULT_ROTATE_CENTER );
240   mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT]  = DEFAULT_ROTATE_AMOUNT;
241   // Default Offset value is very special. unlimited animation from 0.0f to 2.0f
242   {
243     Property::Map map;
244     map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START, 0.0f );
245     map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, 2.0f );
246     map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, -1 );
247
248     mValueMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET] = map;
249   }
250 }
251
252 void AnimatedGradientVisual::DoSetProperties( const Property::Map& propertyMap )
253 {
254   //GRADIENT_TYPE
255   Property::Value* gradientTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, GRADIENT_TYPE_NAME );
256   Toolkit::DevelAnimatedGradientVisual::GradientType::Type gradientType = mGradientType;
257   if( gradientTypeValue )
258   {
259     Scripting::GetEnumerationProperty( *gradientTypeValue, GRADIENT_TYPE_TABLE, GRADIENT_TYPE_TABLE_COUNT, gradientType );
260   }
261
262   //UNIT_TYPE
263   Property::Value* unitTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE, UNIT_TYPE_NAME );
264   Toolkit::DevelAnimatedGradientVisual::UnitType::Type unitType = mUnitType;
265   if( unitTypeValue )
266   {
267     Scripting::GetEnumerationProperty( *unitTypeValue, UNIT_TYPE_TABLE, UNIT_TYPE_TABLE_COUNT, unitType );
268   }
269
270   //SPREAD_TYPE
271   Property::Value* spreadTypeValue = propertyMap.Find( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, SPREAD_TYPE_NAME );
272   Toolkit::DevelAnimatedGradientVisual::SpreadType::Type spreadType = mSpreadType;
273   if( spreadTypeValue )
274   {
275     Scripting::GetEnumerationProperty( *spreadTypeValue, SPREAD_TYPE_TABLE, SPREAD_TYPE_TABLE_COUNT, spreadType );
276   }
277
278   mGradientType = gradientType;
279   mUnitType = unitType;
280   mSpreadType = spreadType;
281
282   SetupGradientAnimationData(propertyMap);
283 }
284
285 void AnimatedGradientVisual::SetupGradientAnimationData( const Property::Map& propertyMap )
286 {
287   mGradientAnimationDataList.Clear(); // Clear Transition Information. All animation will deleted safely
288
289   static Property::Map propertyNameMap;
290   static Property::Map propertyUniformNameMap;
291   if( propertyNameMap.Empty() )
292   {
293     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = START_POSITION_NAME;
294     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   ] = START_COLOR_NAME;
295     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  ] = END_POSITION_NAME;
296     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     ] = END_COLOR_NAME;
297     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = ROTATE_CENTER_NAME;
298     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = ROTATE_AMOUNT_NAME;
299     propertyNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        ] = OFFSET_NAME;
300   }
301   if( propertyUniformNameMap.Empty() )
302   {
303     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION] = UNIFORM_START_POINT_NAME;
304     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   ] = UNIFORM_START_COLOR_NAME;
305     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  ] = UNIFORM_END_POINT_NAME;
306     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     ] = UNIFORM_END_COLOR_NAME;
307     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER ] = UNIFORM_ROTATE_CENTER_NAME;
308     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT ] = UNIFORM_ROTATE_ANGLE_NAME;
309     propertyUniformNameMap[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        ] = UNIFORM_OFFSET_NAME;
310   }
311
312   Property::Map::SizeType map_index_end = propertyNameMap.Count();
313   for( Property::Map::SizeType map_index = 0; map_index < map_index_end; map_index++ )
314   {
315     KeyValuePair property_pair = propertyNameMap.GetKeyValue( map_index );
316     KeyValuePair uniform_pair = propertyUniformNameMap.GetKeyValue( map_index );
317     Property::Index index = property_pair.first.indexKey;
318     const std::string property_name = property_pair.second.Get< std::string >();
319     const std::string uniform_name = uniform_pair.second.Get< std::string >();
320
321     Property::Map map;
322     Property::Value default_value = mValueMap[index];
323
324     map["target"] = "background";
325     map["property"] = uniform_name;
326
327     Property::Value *value = propertyMap.Find( index, property_name );
328     if( !value )
329     {
330       value = &default_value;
331     }
332     else
333     {
334       // Update value list
335       mValueMap[index] = (*value);
336     }
337
338     int loop_count = 0;
339     float delay = 0.0f;
340     bool forward = true;
341     bool auto_mirror = false;
342     std::string ease_str = "LINEAR";
343     Property::Map *map_value = value->GetMap();
344     if( map_value )
345     {
346       auto getValueFromMap = [ &map_value ]( const Property::Index& index, const std::string& name, Property::Value& res ) -> void
347       {
348         Property::Value *sub_value = map_value->Find( index, name );
349         if( sub_value )
350         {
351           res = *sub_value;
352         }
353       };
354
355       Property::Value value_start        = DEFAULT_ANIMATION_START_VALUE;
356       Property::Value value_target       = DEFAULT_ANIMATION_TARGET_VALUE;
357       Property::Value value_duration     = DEFAULT_ANIMATION_DURATION;
358       Property::Value value_delay        = DEFAULT_ANIMATION_DELAY;
359       Property::Value value_repeat       = DEFAULT_ANIMATION_REPEAT;
360       Property::Value value_repeat_delay = DEFAULT_ANIMATION_REPEAT_DELAY;
361
362       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START       , START_VALUE_NAME   , value_start );
363       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET      , TARGET_VALUE_NAME  , value_target );
364       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION    , DURATION_NAME      , value_duration );
365       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY       , DELAY_NAME         , value_delay );
366       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT      , REPEAT_NAME        , value_repeat );
367       getValueFromMap( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, REPEAT_DELAY_NAME  , value_repeat_delay );
368
369       Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::Type direction_type = DEFAULT_ANIMATION_DIRECTION_TYPE;
370       Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::Type    motion_type    = DEFAULT_ANIMATION_MOTION_TYPE;
371       Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type    easing_type    = DEFAULT_ANIMATION_EASING_TYPE;
372
373       Property::Value *direction_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DIRECTION_TYPE_NAME );
374       if( direction_sub_value )
375       {
376         Scripting::GetEnumerationProperty( *direction_sub_value, DIRECTION_TYPE_TABLE, DIRECTION_TYPE_TABLE_COUNT, direction_type );
377       }
378       Property::Value *motion_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, MOTION_TYPE_NAME );
379       if( motion_sub_value )
380       {
381         Scripting::GetEnumerationProperty( *motion_sub_value   , MOTION_TYPE_TABLE   , MOTION_TYPE_TABLE_COUNT   , motion_type );
382       }
383       Property::Value *easing_sub_value = map_value->Find( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, EASING_TYPE_NAME );
384       if( easing_sub_value )
385       {
386         Scripting::GetEnumerationProperty( *easing_sub_value   , EASING_TYPE_TABLE   , EASING_TYPE_TABLE_COUNT   , easing_type );
387       }
388
389       forward = ( direction_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
390       delay = value_delay.Get< float >();
391       loop_count = value_repeat.Get< int >();
392       auto_mirror = ( motion_type == Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
393
394       switch( easing_type )
395       {
396         case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR:
397         {
398           ease_str = "LINEAR";
399           break;
400         }
401         case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN:
402         {
403           ease_str = "EASE_IN_SQUARE";
404           break;
405         }
406         case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT:
407         {
408           ease_str = "EASE_OUT_SQUARE";
409           break;
410         }
411         case Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT:
412         {
413           ease_str = "EASE_IN_OUT";
414           break;
415         }
416       }
417
418       map["initialValue"] = forward ? value_start : value_target;
419       map["targetValue"] = forward ? value_target : value_start;
420       if( loop_count != 0 )
421       {
422         map["animator"] = Property::Map()
423                           .Add( "alphaFunction", ease_str )
424                           .Add( "timePeriod", Property::Map()
425                                              .Add( "delay", value_repeat_delay.Get< float >() )
426                                              .Add( "duration", value_duration.Get< float >() ) );
427       }
428     }
429     else
430     {
431       map["initialValue"] = *value;
432       map["targetValue"] = *value;
433     }
434
435     AnimatedGradientVisual::GradientAnimationData *animData = new AnimatedGradientVisual::GradientAnimationData();
436     animData->transition = Toolkit::TransitionData::New( map );
437     animData->index = index;
438     animData->loop_count = loop_count;
439     animData->delay = delay;
440     animData->forward = forward;
441     animData->auto_mirror = auto_mirror;
442     mGradientAnimationDataList.PushBack( animData );
443   }
444 }
445
446 void AnimatedGradientVisual::SetupAnimation()
447 {
448   for( auto&& elem : mGradientAnimationDataList )
449   {
450     Toolkit::TransitionData& transition = elem->transition;
451     Animation& animation = elem->animation;
452     int loop_count = elem->loop_count;
453     bool auto_mirror = elem->auto_mirror;
454     bool without_animation = ( loop_count == 0 );
455
456     const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition );
457     for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ )
458     {
459       TransitionData::Animator *animator = (*iter);
460       AnimateProperty( animation, *animator );
461     }
462     if( animation && !without_animation )
463     {
464       if( loop_count < 0 )
465       {
466         animation.SetLooping( true );
467       }
468       else if( loop_count > 0 )
469       {
470         animation.SetLoopCount( loop_count );
471       }
472       if( auto_mirror )
473       {
474         animation.SetLoopingMode( Animation::LoopingMode::AUTO_REVERSE );
475       }
476     }
477   }
478 }
479
480 void AnimatedGradientVisual::PlayAnimation()
481 {
482   for( auto&& elem : mGradientAnimationDataList )
483   {
484     Animation& animation = elem->animation;
485     if( animation )
486     {
487       float delay = elem->delay;
488       if( delay > 0.0f )
489       {
490         animation.PlayAfter( delay );
491       }
492       else if( delay < 0.0f )
493       {
494         float progress = -delay / animation.GetDuration(); // (duration + repeat_duration)
495         if(progress >= 1.0f)
496         {
497           int cur_loop = animation.GetLoopCount();
498           int decrease_loop = floor( progress ) + 1;
499           while( decrease_loop > progress )
500           {
501             decrease_loop--;
502           }
503           progress -= decrease_loop;
504           if( cur_loop == 0 )
505           {
506             animation.PlayFrom( progress );
507           }
508           else
509           {
510             cur_loop -= decrease_loop;
511             if( cur_loop > 0 )
512             {
513               animation.SetLoopCount( cur_loop );
514               animation.PlayFrom( progress );
515             }
516             else
517             {
518               // animation done. make this animation finished safely.
519               animation.SetLoopCount( 1 );
520               animation.PlayFrom( 1.0f );
521             }
522           }
523         }
524         else
525         {
526           animation.PlayFrom( progress );
527         }
528       }
529       else
530       {
531         animation.Play();
532       }
533     }
534   }
535 }
536
537 void AnimatedGradientVisual::StopAnimation()
538 {
539   for( auto&& elem : mGradientAnimationDataList )
540   {
541     Animation& animation = elem->animation;
542     if( animation )
543     {
544       animation.Stop();
545     }
546   }
547 }
548
549 void AnimatedGradientVisual::OnSetTransform()
550 {
551   if( mImpl->mRenderer )
552   {
553     mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
554   }
555 }
556
557 void AnimatedGradientVisual::DoSetOnScene( Actor& actor )
558 {
559   InitializeRenderer();
560   actor.AddRenderer( mImpl->mRenderer );
561   SetupAnimation();
562   PlayAnimation();
563
564   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
565 }
566
567 void AnimatedGradientVisual::DoSetOffScene( Actor& actor )
568 {
569   DALI_ASSERT_DEBUG( (bool)mImpl->mRenderer && "There should always be a renderer whilst on stage");
570
571   StopAnimation();
572   actor.RemoveRenderer( mImpl->mRenderer );
573   mImpl->mRenderer.Reset();
574 }
575
576 void AnimatedGradientVisual::DoCreatePropertyMap( Property::Map& map ) const
577 {
578   map.Clear();
579   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_GRADIENT );
580
581   //Create non-animated properties
582   map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::GRADIENT_TYPE, static_cast<int>(mGradientType) );
583   map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::UNIT_TYPE    , static_cast<int>(mUnitType) );
584   map.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE  , static_cast<int>(mSpreadType) );
585
586   //Create animated properties. Get from transition for more realistic test. Not from animation cause Animation may not setuped
587   for( auto&& elem : mGradientAnimationDataList )
588   {
589     Toolkit::TransitionData& transition = elem->transition;
590     Property::Index index = elem->index;
591     int loop_count = elem->loop_count;
592     float delay = elem->delay;
593     bool forward = elem->forward;
594     bool auto_mirror = elem->auto_mirror;
595
596     const Internal::TransitionData& transitionData = Toolkit::GetImplementation( transition );
597     for( auto iter = transitionData.Begin(); iter != transitionData.End(); iter++ )
598     {
599       TransitionData::Animator *animator = (*iter);
600       if( animator->animate )
601       {
602         //with animation
603         Property::Map animation_map;
604         Property::Value value_start = forward ? animator->initialValue : animator->targetValue;
605         Property::Value value_target = forward ? animator->targetValue : animator->initialValue;
606         Property::Value value_direction;
607         Property::Value value_duration = Property::Value( animator->timePeriodDuration );
608         Property::Value value_delay = Property::Value( delay );
609         Property::Value value_repeat = Property::Value( loop_count );
610         Property::Value value_repeat_delay = Property::Value( animator->timePeriodDelay );
611         Property::Value value_motion_type;
612         Property::Value value_easing_type;
613
614         if( forward )
615         {
616           value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
617         }
618         else
619         {
620           value_direction = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
621         }
622         if( auto_mirror )
623         {
624           value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
625         }
626         else
627         {
628           value_motion_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP );
629         }
630         switch( animator->alphaFunction.GetBuiltinFunction() )
631         {
632           case Dali::AlphaFunction::LINEAR:
633           {
634             value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
635             break;
636           }
637           case Dali::AlphaFunction::EASE_IN_SQUARE:
638           {
639             value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN );
640             break;
641           }
642           case Dali::AlphaFunction::EASE_OUT_SQUARE:
643           {
644             value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT );
645             break;
646           }
647           case Dali::AlphaFunction::EASE_IN_OUT:
648           {
649             value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT );
650             break;
651           }
652           default:
653           {
654             value_easing_type = Property::Value( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
655           }
656         }
657
658         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::START       , value_start );
659         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET      , value_target );
660         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION   , value_direction );
661         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION    , value_duration );
662         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY       , value_delay );
663         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT      , value_repeat );
664         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, value_repeat_delay );
665         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE , value_motion_type );
666         animation_map.Insert( Toolkit::DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE , value_easing_type );
667
668         map.Insert( index, animation_map );
669       }
670       else
671       {
672         //without animation
673         map.Insert( index, animator->targetValue );
674       }
675     }
676   }
677 }
678
679 void AnimatedGradientVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
680 {
681
682 }
683
684 Shader AnimatedGradientVisual::CreateShader()
685 {
686   Shader shader;
687
688   std::string tagUnit;
689   std::string tagGrad;
690   std::string tagSpread;
691   switch( mUnitType )
692   {
693     case Toolkit::DevelAnimatedGradientVisual::UnitType::OBJECT_BOUNDING_BOX:
694     {
695       tagUnit = "UNIT_TYPE_BOUNDING_BOX";
696       break;
697     }
698     case Toolkit::DevelAnimatedGradientVisual::UnitType::USER_SPACE:
699     {
700       tagUnit = "UNIT_TYPE_USER";
701       break;
702     }
703   }
704   switch( mGradientType )
705   {
706     case Toolkit::DevelAnimatedGradientVisual::GradientType::LINEAR:
707     {
708       tagGrad = "GRADIENT_TYPE_LINEAR";
709       break;
710     }
711     case Toolkit::DevelAnimatedGradientVisual::GradientType::RADIAL:
712     {
713       tagGrad = "GRADIENT_TYPE_RADIAL";
714       break;
715     }
716   }
717   switch( mSpreadType )
718   {
719     case Toolkit::DevelAnimatedGradientVisual::SpreadType::REFLECT:
720     {
721       tagSpread = "SPREAD_TYPE_REFLECT";
722       break;
723     }
724     case Toolkit::DevelAnimatedGradientVisual::SpreadType::REPEAT:
725     {
726       tagSpread = "SPREAD_TYPE_REPEAT";
727       break;
728     }
729     case Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP:
730     {
731       tagSpread = "SPREAD_TYPE_CLAMP";
732       break;
733     }
734   }
735
736   std::string vert;
737   std::string frag;
738
739   vert = "#define " + tagUnit + "\n"
740        + BASIC_VERTEX_SHADER;
741   frag = "#define " + tagGrad + "\n"
742        + "#define " + tagSpread + "\n"
743        + BASIC_FRAGMENT_SHADER;
744
745   shader = Shader::New( vert, frag );
746   return shader;
747 }
748
749 void AnimatedGradientVisual::InitializeRenderer()
750 {
751   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
752   VisualFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, mUnitType, mSpreadType );
753   Shader shader = mFactoryCache.GetShader( shaderType );
754   if( !shader )
755   {
756     shader = CreateShader();
757     mFactoryCache.SaveShader( shaderType, shader );
758   }
759
760   mImpl->mRenderer = Renderer::New( geometry, shader );
761
762   mImpl->mRenderer.RegisterProperty( UNIFORM_START_POINT_NAME  , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, START_POSITION_NAME ) );
763   mImpl->mRenderer.RegisterProperty( UNIFORM_START_COLOR_NAME  , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR   , START_COLOR_NAME ) );
764   mImpl->mRenderer.RegisterProperty( UNIFORM_END_POINT_NAME    , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION  , END_POSITION_NAME ) );
765   mImpl->mRenderer.RegisterProperty( UNIFORM_END_COLOR_NAME    , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR     , END_COLOR_NAME ) );
766   mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_CENTER_NAME, GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER , ROTATE_CENTER_NAME ) );
767   mImpl->mRenderer.RegisterProperty( UNIFORM_ROTATE_ANGLE_NAME , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT , ROTATE_AMOUNT_NAME ) );
768   mImpl->mRenderer.RegisterProperty( UNIFORM_OFFSET_NAME       , GetStartValue( mValueMap, Toolkit::DevelAnimatedGradientVisual::Property::OFFSET        , OFFSET_NAME ) );
769
770   //Register transform properties
771   mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
772 }
773
774 }//namespace Internal
775
776 }//namespace Toolkit
777
778 }//namespace Dali