Merge "Refactoring Button: remove painter" into tizen
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / animation / animation-api.cpp
1 /*
2  * Copyright (c) 2015 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
18 // CLASS HEADER
19 #include "animation-api.h"
20 #include "path-wrapper.h"
21
22 // INTERNAL INCLUDES
23 #include <v8-utils.h>
24 #include <dali/integration-api/debug.h>
25 #include <animation/animation-wrapper.h>
26 #include <object/property-value-wrapper.h>
27 #include <dali/public-api/common/map-wrapper.h>
28
29 namespace Dali
30 {
31
32 namespace V8Plugin
33 {
34
35 namespace // un named namespace
36 {
37
38 // @todo think about alternative ways of passing around
39 struct AlphaFuncStruct
40 {
41   const char* const name;
42   AlphaFunction alphaFunc;
43 };
44 /**
45  * Contains a list of alpha functions that can be used.
46  * We use a stl map as lookup to map a string name to the function
47  */
48 const AlphaFuncStruct AlphaFunctionTable[]=
49 {
50  {"default"               , AlphaFunctions::Default              },
51  {"linear"                , AlphaFunctions::Linear               },
52  {"square"                , AlphaFunctions::Square               },
53  {"reverse"               , AlphaFunctions::Reverse              },
54  {"easeIn"                , AlphaFunctions::EaseIn               },
55  {"easeOut"               , AlphaFunctions::EaseOut              },
56  {"easeInOut"             , AlphaFunctions::EaseInOut            },
57  {"easeInSine"            , AlphaFunctions::EaseInSine           },
58  {"easeOutSine"           , AlphaFunctions::EaseOutSine          },
59  {"easeInOutSine"         , AlphaFunctions::EaseInOutSine        },
60  {"easeInSine33"          , AlphaFunctions::EaseInSine33         },
61  {"easeOutSine33"         , AlphaFunctions::EaseOutSine33        },
62  {"easeInOutSine33"       , AlphaFunctions::EaseInOutSine33      },
63  {"easeInOutSine50"       , AlphaFunctions::EaseInOutSine50      },
64  {"easeInOutSine60"       , AlphaFunctions::EaseInOutSine60      },
65  {"easeInOutSine70"       , AlphaFunctions::EaseInOutSine70      },
66  {"easeInOutSine80"       , AlphaFunctions::EaseInOutSine80      },
67  {"easeInOutSine90"       , AlphaFunctions::EaseInOutSine90      },
68  {"doubleEaseInOutSine60" , AlphaFunctions::DoubleEaseInOutSine60},
69  {"easeOutQuint50"        , AlphaFunctions::EaseOutQuint50       },
70  {"easeOutQuint80"        , AlphaFunctions::EaseOutQuint80       },
71  {"bounce"                , AlphaFunctions::Bounce               },
72  {"bounceBack"            , AlphaFunctions::BounceBack           },
73  {"easeInBack"            , AlphaFunctions::EaseInBack           },
74  {"easeOutBack"           , AlphaFunctions::EaseOutBack          },
75  {"easeInOutBack"         , AlphaFunctions::EaseInOutBack        },
76  {"sin"                   , AlphaFunctions::Sin                  },
77  {"sin2x"                 , AlphaFunctions::Sin2x                }
78 };
79 const unsigned int AlphaFunctionTableCount = sizeof(AlphaFunctionTable)/sizeof(AlphaFunctionTable[0]);
80 const char* const DEFAULT_ALPHA_NAME = "default";
81 static AlphaFunction DEFAULT_ALPHA_FUNCTION = AlphaFunctions::Default;
82
83
84
85 AlphaFunction GetAlphaFunction( const std::string& alphaFuncName )
86 {
87   // This will normally get called just a few times during the application, so no point in doing anything clever
88   for( unsigned int i = 0; i < AlphaFunctionTableCount; i++)
89   {
90     const AlphaFuncStruct& alphaStruct( AlphaFunctionTable[i] );
91
92     if( std::strcmp( alphaStruct.name , alphaFuncName.c_str() ) == 0 )
93     {
94       return alphaStruct.alphaFunc;
95     }
96   }
97
98   DALI_LOG_ERROR("Failed to find alpha func |%s| \n", alphaFuncName.c_str() );
99   return AlphaFunctions::Default;
100 }
101
102 const char* const GetAlphaFunctionName(  AlphaFunction alphaFunc )
103 {
104   // This may get called 3 times during the application, so no point
105   // in doing anything clever
106
107   for( unsigned int i = 0; i < AlphaFunctionTableCount; i++)
108   {
109     const AlphaFuncStruct& alphaStruct( AlphaFunctionTable[i] );
110
111
112     if( alphaStruct.alphaFunc  == alphaFunc )
113     {
114       return alphaStruct.name;
115     }
116   }
117   return "default";
118 }
119
120
121 struct AnimationParameters
122 {
123   AnimationParameters( const Animation& anim)
124   : propertyIndex( Property::INVALID_INDEX  ),
125     alphaFunction( DEFAULT_ALPHA_FUNCTION),
126     delay( 0.f ),
127     duration(anim.GetDuration()),
128     optionsFound( false )
129   {
130   }
131
132   Handle target;
133   Property::Index propertyIndex;
134   Property::Value value;
135   KeyFrames keyFrames;
136   AlphaFunction alphaFunction;
137   float delay;
138   float duration;
139   bool optionsFound;
140 };
141
142 void GetAnimationOptions( v8::Isolate* isolate,
143                           v8::Local<v8::Value > options,
144                           AnimationParameters& animParams )
145 {
146   // animation options is an optional parameter passed in which holds
147   // optional settings
148   // var animOptions = {
149   //  alpha: "Bounce",
150   //  delay: 5,
151   //  duration: 20
152   // };
153   v8::HandleScope handleScope( isolate );
154
155   if( options->IsObject() )
156   {
157     v8::Local<v8::Object> obj = options->ToObject();
158     v8::Local<v8::Value> alphaValue = obj->Get( v8::String::NewFromUtf8( isolate, "alpha" ) );
159     if( alphaValue->IsString() )
160     {
161       animParams.optionsFound = true;
162       std::string alphaName = V8Utils::v8StringToStdString( alphaValue );
163       animParams.alphaFunction = GetAlphaFunction( alphaName );
164     }
165
166     v8::Local<v8::Value> delayValue = obj->Get( v8::String::NewFromUtf8( isolate, "delay" ) );
167     if( delayValue->IsNumber() )
168     {
169       animParams.optionsFound = true;
170       v8::Local<v8::Number> num = delayValue->ToNumber();
171       animParams.delay = num->Value();
172     }
173
174     v8::Local<v8::Value> durationValue = obj->Get( v8::String::NewFromUtf8( isolate, "duration" ) );
175     if( durationValue->IsNumber() )
176     {
177       animParams.optionsFound = true;
178       v8::Local<v8::Number> num = durationValue->ToNumber();
179       animParams.duration = num->Value();
180     }
181
182   }
183 }
184 KeyFrames GetKeyFrames( v8::Isolate* isolate, v8::Local<v8::Value > keyFrameArray )
185 {
186   // keyframe object is an array of
187   // {
188   //   float: progress
189   //   value: property value ( position/ rotation etc)
190   //   alpha: function
191   //
192   v8::HandleScope handleScope( isolate );
193
194   if( !keyFrameArray->IsObject() || !keyFrameArray->IsArray() )
195   {
196     DALI_SCRIPT_EXCEPTION( isolate, "missing keyframe array" );
197     return KeyFrames();
198   }
199
200   KeyFrames keyframes = KeyFrames::New();
201
202   v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( keyFrameArray );
203   for( uint32_t i=0; i < array->Length() ; ++i)
204   {
205     v8::Handle<v8::Value> arrayItem =  array->Get( i );
206
207     if(!arrayItem->IsObject() )
208     {
209       DALI_SCRIPT_EXCEPTION( isolate, "missing keyframe object" );
210       return KeyFrames();
211     }
212     v8::Handle<v8::Object> keyFrameObject = arrayItem->ToObject();
213
214     // get keyframe.progress
215     v8::Handle<v8::Value> progress = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "progress"));
216     if( !progress->IsNumber() )
217     {
218       DALI_SCRIPT_EXCEPTION( isolate, "keyframe missing progress property" );
219       return keyframes;
220     }
221
222     // get keyframe.value
223     bool found(false);
224     v8::Handle<v8::Value> propertyValue = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "value"));
225     Property::Value value =  V8Utils::GetPropertyValueFromObject( found, isolate, propertyValue );
226     if( !found )
227     {
228       DALI_SCRIPT_EXCEPTION( isolate, "keyframe missing value property" );
229       return keyframes;
230     }
231
232     // get keyframe.alpha
233     v8::Handle<v8::Value> alphaValue = keyFrameObject->Get(v8::String::NewFromUtf8( isolate, "alpha"));
234     if( alphaValue->IsString() )
235     {
236       std::string alphaName = V8Utils::v8StringToStdString( alphaValue );
237       AlphaFunction alphaFunction = GetAlphaFunction( alphaName );
238       keyframes.Add( progress->NumberValue(), value, alphaFunction );
239     }
240     else
241     {
242       keyframes.Add( progress->NumberValue(), value );
243     }
244
245   }
246   return keyframes;
247
248 }
249 bool GetAnimationParameters(  v8::Isolate* isolate,
250                               const v8::FunctionCallbackInfo< v8::Value >& args,
251                               AnimationParameters& animParams,
252                               AnimationApi::AnimationParameterType type)
253 {
254   // used for things like anim.AnimateBy(  myImageActor, property-name,  property-value (or Javascript number array));
255   // 1 extract property handle from param1.
256   // 2 extract property name from param2  ( can be in the format "u-color" or "uColor"
257   // 3 extract PropertyValue from param3
258   // 4 extract animation options ( delay, duration, alpha func)
259
260   // 1 extract HANDLE
261   bool foundHandle;
262   animParams.target = V8Utils::GetHandleParameter( PARAMETER_0, foundHandle, isolate, args );
263   if( !foundHandle )
264   {
265     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 (Handle)" );
266     return false;
267   }
268
269   // 2 extract property name
270   bool foundPropName;
271   std::string propertyName = V8Utils::GetStringParameter( PARAMETER_1, foundPropName, isolate, args );
272   if( !foundPropName )
273   {
274     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 ( PropertyName )" );
275     return false;
276   }
277   // try both properties with dashes and without
278   Property::Index index = animParams.target.GetPropertyIndex( propertyName );
279
280   if( index == Property::INVALID_INDEX )
281   {
282     // convert the property name from "uColor" to "u-color"
283     std::string convetedName = V8Utils::JavaScriptNameToPropertyName( propertyName );
284     index = animParams.target.GetPropertyIndex( convetedName );
285   }
286
287   animParams.propertyIndex = index;
288
289   if( type == AnimationApi::PROPERTY_VALUE )
290   {
291     // 3 extract property value
292     bool foundPropValue( false );
293     animParams.value = V8Utils::GetPropertyValueParameter( PARAMETER_2, foundPropValue, isolate, args );
294     if( !foundPropValue )
295     {
296       DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 2 ( value )" );
297       return false;
298     }
299   }
300   else  // type == KEYFRAMES
301   {
302     animParams.keyFrames = GetKeyFrames(isolate, args[2]);
303   }
304   // 4 extract animation options
305   GetAnimationOptions( isolate, args[3], animParams );
306
307   return true;
308 }
309
310 Animation GetAnimation( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
311 {
312   v8::HandleScope handleScope( isolate );
313
314   v8::Local<v8::Object> object = args.This();
315   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
316   void* ptr = field->Value();
317
318   AnimationWrapper* wrapper = static_cast<AnimationWrapper *>( ptr );
319   return wrapper->GetAnimation();
320 }
321
322
323 } // un-named namespace
324
325 /**
326  * Constructor
327  *
328  * @constructor
329  * @for Animation
330  * @method Animation
331  * @param {float} duration
332  *
333  */
334 Animation AnimationApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
335 {
336   v8::Isolate* isolate = args.GetIsolate();
337   v8::HandleScope handleScope( isolate );
338
339   bool found( false );
340   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
341   if( !found )
342   {
343     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
344     return Animation();
345   }
346   // get the duration
347   return Animation::New( value );
348 }
349
350 /**
351  * Set the animation duration.
352  * @method setDuration
353  * @for Animation
354  * @param {float} duration in seconds
355  *
356  */
357 void AnimationApi::SetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
358 {
359   v8::Isolate* isolate = args.GetIsolate();
360   v8::HandleScope handleScope( isolate );
361
362   Animation anim = GetAnimation( isolate, args );
363
364   bool found( false );
365   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 1.f /* default */);
366   if( !found )
367   {
368     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
369     return;
370   }
371   anim.SetDuration( value );
372 }
373 /**
374  * Get the animation duration.
375  * @method getDuration
376  * @for Animation
377  * @return {float} duration in seconds
378  *
379  */
380 void AnimationApi::GetDuration( const v8::FunctionCallbackInfo< v8::Value >& args )
381 {
382   v8::Isolate* isolate = args.GetIsolate();
383   v8::HandleScope handleScope( isolate );
384
385   Animation anim = GetAnimation( isolate, args );
386
387   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetDuration() ) );
388
389 }
390 /**
391  * Set whether the animation will loop.
392  * @method setLooping
393  * @for Animation
394  * @param {bool} looping enabled
395  *
396  */
397 void AnimationApi::SetLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
398 {
399   v8::Isolate* isolate = args.GetIsolate();
400   v8::HandleScope handleScope( isolate );
401
402   Animation anim = GetAnimation( isolate, args );
403
404   bool found( false );
405   bool value = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
406   if( !found )
407   {
408     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
409   }
410   else
411   {
412     anim.SetLooping( value );
413   }
414
415 }
416 /**
417  * Query whether the animation will loop.
418  * @method isLooping
419  * @for Animation
420  * @return {bool} looping enabled
421  *
422  */
423 void AnimationApi::IsLooping( const v8::FunctionCallbackInfo< v8::Value >& args )
424 {
425   v8::Isolate* isolate = args.GetIsolate();
426   v8::HandleScope handleScope( isolate );
427
428   Animation anim = GetAnimation( isolate, args );
429
430   args.GetReturnValue().Set( v8::Boolean::New( isolate, anim.IsLooping() ) );
431 }
432
433 /**
434  * Set the end action of the animation.
435  *
436  * This action is performed when the animation ends.
437  * Default end action is bake
438  * @method setEndAction
439  * @for Animation
440  * @param {integer} bake mode
441  * @example
442  *       anim.setEndAction( dali.ANIMATION_BAKE ); // When the animation ends, the animated property values are saved.
443  *       anim.setEndAction( dali.ANIMATION_DISCARD ); //  When the animation ends, the animated property values are forgotten.
444  *       anim.setEndAction( dali.ANIMATION_BAKE_FINAL ); // If the animation is stopped, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
445  */
446 void AnimationApi::SetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
447 {
448   v8::Isolate* isolate = args.GetIsolate();
449   v8::HandleScope handleScope( isolate );
450
451   Animation anim = GetAnimation( isolate, args );
452
453   bool found( false );
454   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
455   if( !found )
456   {
457     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
458   }
459   else
460   {
461     anim.SetEndAction( static_cast<Animation::EndAction>( value ) );
462   }
463 }
464
465 /**
466  * Returns the end action of the animation.
467
468  * @method getEndAction
469  * @for Animation
470  * @return {integer} bake mode
471  *
472  * There are 3 different bake modes
473  * @example
474  *     dali.ANIMATION_BAKE  // When the animation ends, the animated property values are saved.
475  *     dali.ANIMATION_DISCARD // When the animation ends, the animated property values are forgotten.
476  *     dali.ANIMATION_BAKE_FINAL  // If the animation is stopped, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
477  */
478 void AnimationApi::GetEndAction( const v8::FunctionCallbackInfo< v8::Value >& args )
479 {
480   v8::Isolate* isolate = args.GetIsolate();
481   v8::HandleScope handleScope( isolate );
482
483   Animation anim = GetAnimation( isolate, args );
484
485   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetEndAction() ) );
486 }
487
488 /**
489  * Set the disconnect action of the animation.
490  * If any of the animated property owners are disconnected from the stage, this action is performed.
491  * Default disconnection action is BakeFinal.
492  * @method setDisconnectAction
493  * @for Animation
494  * @param {integer} end mode
495  *
496  * There are 3 different end modes
497  * @example
498  *     dali.ANIMATION_BAKE  // When the animation is destroyed, the animated property values are saved.
499  *     dali.ANIMATION_DISCARD // When the animation is destroyed, the animated property values are forgotten.
500  *     dali.ANIMATION_BAKE_FINAL  // When the animation is destroyed, the animated property values are saved as if the animation had run to completion, otherwise behaves like Bake.
501  */
502 void AnimationApi::SetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
503 {
504   v8::Isolate* isolate = args.GetIsolate();
505   v8::HandleScope handleScope( isolate );
506
507   Animation anim = GetAnimation( isolate, args );
508
509   bool found( false );
510   int value = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
511   if( !found )
512   {
513     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
514   }
515   else
516   {
517     anim.SetDisconnectAction( static_cast<Animation::EndAction>( value ) );
518   }
519 }
520
521 /**
522  * Returns the disconnect action of the animation.
523  * @method getDisconnectAction
524  * @for Animation
525  * @return {integer} end mode
526  */
527 void AnimationApi::GetDisconnectAction( const v8::FunctionCallbackInfo< v8::Value >& args )
528 {
529   v8::Isolate* isolate = args.GetIsolate();
530   v8::HandleScope handleScope( isolate );
531
532   Animation anim = GetAnimation( isolate, args );
533
534   args.GetReturnValue().Set( v8::Integer::New( isolate, anim.GetDisconnectAction() ) );
535 }
536 /**
537  * Set the default alpha function for an animation.
538  * @method setDefaultAlphaFunction
539  * @for Animation
540  * @param {string} alpha function
541  */
542 void AnimationApi::SetDefaultAlphaFunction( const v8::FunctionCallbackInfo< v8::Value >& args )
543 {
544   v8::Isolate* isolate = args.GetIsolate();
545   v8::HandleScope handleScope( isolate );
546
547   Animation anim = GetAnimation( isolate, args );
548
549   bool found( false );
550   std::string alphaFunc = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
551   if( !found )
552   {
553     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
554   }
555   else
556   {
557     AlphaFunction func = GetAlphaFunction( alphaFunc );
558     anim.SetDefaultAlphaFunction( func );
559   }
560
561 }
562 /**
563  * Get the default alpha function for an animation.
564  * @method getDefaultAlphaFunction
565  * @for Animation
566  * @return {string} alpha function
567  */
568 void AnimationApi::GetDefaultAlphaFunction( const v8::FunctionCallbackInfo<v8::Value>& args )
569 {
570   v8::Isolate* isolate = args.GetIsolate();
571   v8::HandleScope handleScope( isolate );
572
573   Animation anim = GetAnimation( isolate, args );
574
575   std::string alphaName = GetAlphaFunctionName(  anim.GetDefaultAlphaFunction() );
576
577
578   args.GetReturnValue().Set( v8::String::NewFromUtf8( isolate, alphaName.c_str() ) );
579 }
580
581 /**
582  * Get the current progress of the animation.
583  * @method getCurrentProgress
584  * @for Animation
585  * @return {float} The current progress as a normalized value between [0..1].
586  *
587  */
588 void AnimationApi::GetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
589 {
590   v8::Isolate* isolate = args.GetIsolate();
591   v8::HandleScope handleScope( isolate );
592
593   Animation anim = GetAnimation( isolate, args );
594
595   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetCurrentProgress() ) );
596 }
597
598 /**
599  * Specifies an speed factor for the animation.
600  *
601  * The speed factor is a multiplier of the normal velocity of the animation. Values between [0,1] will
602  * slow down the animation and values above one will speed up the animation. It is also possible to specify a negative multiplier
603  * to play the animation in reverse.
604  *
605  * @method setSpeedFactor
606  * @for Animation
607  * @param {float}  value which will multiply the velocity.
608  * @example
609  *     anim.setSpeedFactor(2);
610  *     anim.play();             // plays the animation twice as fast
611  *
612  *
613  *     anim.setSpeedFactor(0.5);
614  *     anim.play();             // plays the animation half speed
615  *
616  */
617 void AnimationApi::SetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
618 {
619   v8::Isolate* isolate = args.GetIsolate();
620   v8::HandleScope handleScope( isolate );
621
622   Animation anim = GetAnimation( isolate, args );
623
624   bool found( false );
625   float speedFactor = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
626   if( !found )
627   {
628     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
629   }
630   else
631   {
632     anim.SetSpeedFactor( speedFactor );
633   }
634
635 }
636
637 /**
638  * Retrieve the speed factor of the animation
639  *
640  *
641  * @method getSpeedFactor
642  * @for Animation
643  * @return {float} speed factor
644  */
645 void AnimationApi::GetSpeedFactor( const v8::FunctionCallbackInfo< v8::Value >& args )
646 {
647   v8::Isolate* isolate = args.GetIsolate();
648   v8::HandleScope handleScope( isolate );
649
650   Animation anim = GetAnimation( isolate, args );
651
652   args.GetReturnValue().Set( v8::Number::New( isolate, anim.GetSpeedFactor() ) );
653 }
654
655 /**
656  * Set the playing range.
657  * Animation will play between the values specified.
658  * Both values ( range.x and range.y ) should be between 0-1,
659  * otherwise they will be ignored.
660  * If the range provided is not in proper order ( minimum,maximum), it will be reordered.
661  * @method setPlayRange
662  * @for Animation
663  * @param {Object} Range
664  * @param {Float} Range.start
665  * @param {Float} Range.end
666  * @example
667  *     var range = {  start:0.1, end:0.6 };
668  *     anim.setPlayRange( range );
669  */
670 void AnimationApi::SetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
671 {
672   v8::Isolate* isolate = args.GetIsolate();
673   v8::HandleScope handleScope( isolate );
674
675   Animation anim = GetAnimation( isolate, args );
676   Vector2 range(0,0);
677
678   if( args.Length() != 1 )
679   {
680     DALI_SCRIPT_EXCEPTION( isolate, "missing / invalid parameters" );
681     return;
682   }
683   v8::Local<v8::Value > rangeValue = args[0];
684   if( !rangeValue->IsObject() )
685   {
686     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters" );
687     return;
688   }
689   v8::Local<v8::Object> obj = rangeValue->ToObject();
690   v8::Local<v8::Value> startValue = obj->Get( v8::String::NewFromUtf8( isolate, "start" ) );
691   v8::Local<v8::Value> endValue = obj->Get( v8::String::NewFromUtf8( isolate, "end" ) );
692
693   if( startValue->IsNumber() &&  endValue->IsNumber())
694   {
695         range.x= startValue->ToNumber()->Value();
696         range.y = endValue->ToNumber()->Value();
697   }
698   else
699   {
700     DALI_SCRIPT_EXCEPTION( isolate, "missing start/end value" );
701     return;
702   }
703
704   anim.SetPlayRange( range );
705
706 }
707
708 /**
709  * Get the playing range.
710  * @method getPlayRange
711  * @for Animation
712  * @return {Object} Range with { start: ,  end: } properties.
713  */
714 void AnimationApi::GetPlayRange( const v8::FunctionCallbackInfo< v8::Value >& args )
715 {
716   v8::Isolate* isolate = args.GetIsolate();
717   v8::EscapableHandleScope handleScope( isolate );
718   Animation anim = GetAnimation( isolate, args );
719
720
721   v8::Local<v8::Object> rangeObject = v8::Object::New( isolate );
722
723   Vector2 range = anim.GetPlayRange();
724
725  // set device id
726   rangeObject->Set( v8::String::NewFromUtf8( isolate, "start"), v8::Number::New( isolate,range.x ));
727
728    // set state
729   rangeObject->Set( v8::String::NewFromUtf8( isolate, "end"), v8::Number::New( isolate,range.y ));
730
731   args.GetReturnValue().Set( rangeObject );
732 }
733
734
735 /**
736  * Sets the progress of the animation.
737  * The animation will play (or continue playing) from this point. The progress
738  * must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
739  * otherwise, it will be ignored.
740  *
741  * @method setCurrentProgress
742  * @for Animation
743  * @param {float}  progress The new progress as a normalized value between [0,1] or between the
744  * play range if specified.
745  */
746 void AnimationApi::SetCurrentProgress( const v8::FunctionCallbackInfo< v8::Value >& args )
747 {
748   v8::Isolate* isolate = args.GetIsolate();
749   v8::HandleScope handleScope( isolate );
750
751   Animation anim = GetAnimation( isolate, args );
752
753   bool found( false );
754
755   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
756   if( !found )
757   {
758     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
759     return;
760   }
761   anim.SetCurrentProgress( progress );
762
763 }
764
765 /**
766  *
767  *  Play the animation from a given point.
768  * The progress must be in the 0-1 interval or in the play range interval if defined ( See SetPlayRange ),
769  * otherwise, it will be ignored.
770  * @method playFrom
771  * @for Animation
772  * @param {float} progress A value between [0,1], or between the play range if specified, form where the animation should start playing
773  */
774 void AnimationApi::PlayFrom( const v8::FunctionCallbackInfo< v8::Value >& args )
775 {
776   v8::Isolate* isolate = args.GetIsolate();
777   v8::HandleScope handleScope( isolate );
778
779   Animation anim = GetAnimation( isolate, args );
780
781   bool found( false );
782
783   float progress = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
784   if( !found )
785   {
786     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
787     return;
788   }
789   anim.PlayFrom( progress );
790
791 }
792
793 /**
794  * Play the animation
795  * @method play
796  * @for Animation
797  */
798 void AnimationApi::Play( const v8::FunctionCallbackInfo<v8::Value>& args )
799 {
800   v8::Isolate* isolate = args.GetIsolate();
801   v8::HandleScope handleScope( isolate );
802
803   Animation anim = GetAnimation( isolate, args );
804   anim.Play();
805 }
806 /**
807  * Pause the animation
808  * @method pause
809  * @for Animation
810  */
811 void AnimationApi::Pause( const v8::FunctionCallbackInfo<v8::Value>& args )
812 {
813   v8::Isolate* isolate = args.GetIsolate();
814   v8::HandleScope handleScope( isolate );
815
816   Animation anim = GetAnimation( isolate, args );
817   anim.Pause();
818 }
819 /**
820  * Stop the animation
821  * @method stop
822  * @for Animation
823  */
824 void AnimationApi::Stop( const v8::FunctionCallbackInfo<v8::Value>& args )
825 {
826   v8::Isolate* isolate = args.GetIsolate();
827   v8::HandleScope handleScope( isolate );
828
829   Animation anim = GetAnimation( isolate, args );
830   anim.Stop();
831 }
832 /**
833  * Clear the animation
834  * This disconnects any objects that were being animated, effectively stopping the animation.
835  * @method clear
836  * @for Animation
837  */
838 void AnimationApi::Clear( const v8::FunctionCallbackInfo<v8::Value>& args )
839 {
840   v8::Isolate* isolate = args.GetIsolate();
841   v8::HandleScope handleScope( isolate );
842
843   Animation anim = GetAnimation( isolate, args );
844   anim.Clear();
845 }
846
847
848 void AnimationApi::Animate( const v8::FunctionCallbackInfo<v8::Value>& args )
849 {
850   v8::Isolate* isolate = args.GetIsolate();
851   v8::HandleScope handleScope( isolate );
852
853   Animation anim = GetAnimation( isolate, args );
854   AnimationParameters animParams( anim );
855   bool found(false);
856
857   //Get actor
858   Dali::Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
859   if( !found )
860   {
861     DALI_SCRIPT_EXCEPTION( isolate, "Missing actor parameter");
862     return;
863   }
864
865   //Get path
866   Dali::Path path;
867   BaseWrappedObject* wrapper = V8Utils::GetWrappedDaliObjectParameter( PARAMETER_1, BaseWrappedObject::PATH, isolate, args);
868   PathWrapper* pathWrapper = static_cast< PathWrapper*>( wrapper );
869   if( !pathWrapper )
870   {
871     return;
872   }
873   path = pathWrapper->GetPath();
874
875   //Get forward vector
876   bool bFound(false);
877   Vector3 forward = V8Utils::GetVector3Parameter( PARAMETER_2, bFound, isolate, args );
878   if( !bFound )
879   {
880     return;
881   }
882
883   //Get animation options
884   GetAnimationOptions( isolate, args[3], animParams );
885   if( animParams.optionsFound )
886   {
887     anim.Animate( actor, path, forward, animParams.alphaFunction, TimePeriod( animParams.delay, animParams.duration) );
888   }
889   else
890   {
891     anim.Animate( actor, path, forward );
892   }
893 }
894
895 /**
896  *
897  * Animate a property value by a relative amount.
898  *
899  * The effect will start & end when the animation begins & ends.
900  * @method animateBy
901  * @for Animation
902  * @param {Object} target object that contains a property to be animated (e.g. myActor )
903  * @param {String} property name (e.g. "position" )
904  * @param {Object} relativeValue The property value will change by this amount.
905  * @param {Object} [options] Animation options.
906  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
907  * @param {Float} [options.duration] duration of the animation
908  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
909  *
910  * @example
911  *
912  *     // animation x position
913  *     var anim = new dali.Animation( 1 );
914  *     anim.animateBy( imageActor,"positionX", 30 );
915  *     anim.play();
916  *
917  *     // animate x,y,z position with the optional animation options
918  *     var options = {
919  *        delay: 3,     // 3 second delay before starting
920  *        duration: 5,  // 5 second duration
921  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
922  *     }
923  *
924  *     anim.animateBy( imageActor,"position", [100,200,0], options );
925  *
926  */
927 void AnimationApi::AnimateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
928 {
929   v8::Isolate* isolate = args.GetIsolate();
930   v8::HandleScope handleScope( isolate );
931
932   Animation anim = GetAnimation( isolate, args );
933   AnimationParameters animParams( anim );
934
935   // grab all the parameters
936   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE);
937   if( !ok )
938   {
939     // GetAnimationParameters will log
940     return;
941   }
942
943   if( animParams.optionsFound )
944   {
945     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ),
946                               animParams.value,
947                               animParams.alphaFunction,
948                               TimePeriod( animParams.delay, animParams.duration) );
949   }
950   else
951   {
952     anim.AnimateBy( Property( animParams.target, animParams.propertyIndex ), animParams.value );
953   }
954
955 }
956
957 /**
958  *
959  * Animate a property to a destination value.
960  *
961  * The effect will start & end when the animation begins & ends.
962  * @method animateTo
963  * @for Animation
964  * @param {Object} target object that contains a property to be animated (e.g. myActor )
965  * @param {String} property name (e.g. "position" )
966  * @param {Object} destinationValue The property value will changed to this value
967  * @param {Object} [options] Animation options.
968  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
969  * @param {Float} [options.duration] duration of the animation
970  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
971  *
972  * @example
973  *
974  *     var anim = new dali.Animation( 1 );
975  *     anim.animateTo( imageActor,"positionX", 30 );
976  *     anim.play();
977  *
978  *
979  *     // with the optional animation options object
980  *     var options = {
981  *        delay: 3,     // 3 second delay before starting
982  *        duration: 5,  // 5 second duration
983  *        alpha:"easeInOutSine"   // Speeds up and slows to a gradual stop
984  *     }
985  *
986  *     anim.animateTo( imageActor,"position", [100,200,0], options );
987  *
988  */
989 void AnimationApi::AnimateTo( const v8::FunctionCallbackInfo< v8::Value >& args )
990 {
991   v8::Isolate* isolate = args.GetIsolate();
992   v8::HandleScope handleScope( isolate );
993
994   Animation anim = GetAnimation( isolate, args );
995   AnimationParameters animParams( anim );
996
997   // grab all the parameters
998   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::PROPERTY_VALUE );
999   if( !ok )
1000   {
1001     // GetAnimationParameters will log
1002     return;
1003   }
1004
1005   if( animParams.optionsFound )
1006   {
1007
1008     anim.AnimateTo( Property( animParams.target,animParams.propertyIndex ),
1009                                   animParams.value,
1010                                   animParams.alphaFunction,
1011                                   TimePeriod( animParams.delay, animParams.duration) );
1012   }
1013   else
1014   {
1015     anim.AnimateTo( Property( animParams.target, animParams.propertyIndex ), animParams.value );
1016   }
1017 }
1018
1019 /**
1020  *
1021  * Animate a property between keyframes.
1022  *
1023  * The effect will start & end when the animation begins & ends.
1024  * @method animateBetween
1025  * @for Animation
1026  * @param {Object} target object that contains a property to be animated (e.g. myActor )
1027  * @param {String} property name (e.g. "position" )
1028  * @param {Object} keyframes array of keyframe objects
1029  * @param {Object} [options] Animation options.
1030  * @param {Float} [options.delay] amount to delay the start of the animation in seconds
1031  * @param {Float} [options.duration] duration of the animation
1032  * @param {String} [options.alpha] Animation alpha function (e.g. "linear")
1033  *
1034  *
1035  * @example
1036  *
1037  *  create some keyframes to move an actor around a square, and return to the start
1038  * </br >
1039  *  <img src="../assets/img/keyframe-animation.png">
1040  *
1041  *
1042  *     var keyframes = [
1043  *     {
1044  *       progress:0.0,
1045  *       value: [0,0,0]
1046  *     },
1047  *     {
1048  *       progress:0.25,
1049  *       value: [500,0,0]
1050  *     },
1051  *
1052  *     {
1053  *       progress:0.5,
1054  *       value: [500,500,0]
1055  *     },
1056  *     {
1057  *       progress:0.75,
1058  *       value: [0,500,0]
1059  *     },
1060  *     {
1061  *       progress:1.0,
1062  *       value: [0,0,0]
1063  *     } ];
1064  *
1065  *
1066  *     anim.animateBetween( imageActor,"position", keyframes );
1067  *
1068  */
1069 void AnimationApi::AnimateBetween( const v8::FunctionCallbackInfo< v8::Value >& args )
1070 {
1071   v8::Isolate* isolate = args.GetIsolate();
1072   v8::HandleScope handleScope( isolate );
1073
1074   Animation anim = GetAnimation( isolate, args );
1075   AnimationParameters animParams( anim );
1076
1077   // grab all the parameters
1078   bool ok = GetAnimationParameters( isolate, args, animParams, AnimationApi::KEYFRAMES );
1079   if( !ok )
1080   {
1081     // GetAnimationParameters will log
1082     return;
1083   }
1084
1085   // if animation options exist...
1086   if( animParams.optionsFound )
1087   {
1088
1089     anim.AnimateBetween( Property( animParams.target,animParams.propertyIndex ),
1090                                   animParams.keyFrames,
1091                                   animParams.alphaFunction,
1092                                   TimePeriod( animParams.delay, animParams.duration) );
1093   }
1094   else
1095   {
1096     anim.AnimateBetween( Property( animParams.target, animParams.propertyIndex ), animParams.keyFrames );
1097   }
1098 }
1099
1100 /**
1101  * show an actor during the animation.
1102  *
1103  * This is a helper, which simulates animating the visibility property of an actor
1104  * with zero duration ( it is just a boolean).
1105  * e.g. it performs  anim.AnimateTo( actor,"visible",true, { delay:delay: duration:0 } );
1106  * @method show
1107  * @for Animation
1108  * @param {Object} Actor
1109  * @param {float} delay until the actor is shown
1110  */
1111 void AnimationApi::Show( const v8::FunctionCallbackInfo< v8::Value >& args )
1112 {
1113   v8::Isolate* isolate = args.GetIsolate();
1114   v8::HandleScope handleScope( isolate );
1115   Animation anim = GetAnimation( isolate, args );
1116   bool found( false );
1117
1118   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1119   if( !found)
1120   {
1121     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1122     return;
1123   }
1124   // get the duration
1125   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1126   if( !found )
1127   {
1128     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1129     return;
1130   }
1131   anim.Show( actor, delay );
1132
1133 }
1134
1135 /**
1136  * hide an actor during the animation.
1137  *
1138  * This is a helper, which simulates animating the visibility property of an actor
1139  * with zero duration ( it is just a boolean).
1140  * e.g. it performs  anim.AnimateTo( actor,"visible",false, { delay:delay: duration:0 } );
1141  * @method hide
1142  * @for Animation
1143  * @param {Object} Actor
1144  * @param {float} delay until the actor is hidden
1145  */
1146 void AnimationApi::Hide( const v8::FunctionCallbackInfo< v8::Value >& args )
1147 {
1148   v8::Isolate* isolate = args.GetIsolate();
1149   v8::HandleScope handleScope( isolate );
1150   Animation anim = GetAnimation( isolate, args );
1151   bool found( false );
1152   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
1153   if( !found )
1154   {
1155     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 actor" );
1156     return;
1157   }
1158
1159   // get the duration
1160   float delay = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 1.f /* default */);
1161   if( !found )
1162   {
1163     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 1 delay" );
1164     return;
1165   }
1166   anim.Hide( actor, delay );
1167 }
1168
1169
1170
1171
1172 } // namespace V8Plugin
1173
1174 } // namespace Dali