PathConstrainer changes in JS Plugin + LinearConstrainer
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / animation / constrainer-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 "constrainer-api.h"
20
21 //EXTERNAL INCLUDES
22 #include <cfloat> //For FLT_MAX
23
24 // INTERNAL INCLUDES
25 #include <animation/linear-constrainer-wrapper.h>
26 #include <animation/path-constrainer-wrapper.h>
27 #include <object/property-value-wrapper.h>
28 #include <v8-utils.h>
29
30 namespace Dali
31 {
32
33 namespace V8Plugin
34 {
35
36 namespace // un named namespace
37 {
38
39 PathConstrainer GetPathConstrainer( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
40 {
41   v8::HandleScope handleScope( isolate );
42
43   v8::Local<v8::Object> object = args.This();
44   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
45   void* ptr = field->Value();
46
47   PathConstrainerWrapper* wrapper = static_cast<PathConstrainerWrapper *>( ptr );
48   return wrapper->GetPathConstrainer();
49 }
50
51 LinearConstrainer GetLinearConstrainer( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
52 {
53   v8::HandleScope handleScope( isolate );
54
55   v8::Local<v8::Object> object = args.This();
56   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
57   void* ptr = field->Value();
58
59   LinearConstrainerWrapper* wrapper = static_cast<LinearConstrainerWrapper *>( ptr );
60   return wrapper->GetLinearConstrainer();
61 }
62
63 bool GetApplyParameters( const v8::FunctionCallbackInfo< v8::Value >& args, Actor& targetActor, Property::Index& targetPropertyIndex,
64                          Actor& sourceActor, Property::Index& sourcePropertyIndex, Vector2& range, Vector2& wrap )
65 {
66   v8::Isolate* isolate = args.GetIsolate();
67   v8::HandleScope handleScope( isolate );
68
69   if( args[0]->IsObject() )
70   {
71     bool found(false);
72
73     v8::Local<v8::Object> obj = args[0]->ToObject();
74     v8::Local<v8::Value> member = obj->Get( v8::String::NewFromUtf8( isolate, "target" ) );
75
76     //Get target actor
77     if( member->IsObject() )
78     {
79       v8::Local<v8::Object> targetActorObject = member->ToObject();
80       targetActor = V8Utils::GetActorFromObject( isolate, found, targetActorObject );
81       if( !targetActor )
82       {
83         DALI_SCRIPT_EXCEPTION( isolate, "Target actor not found" );
84         return false;
85       }
86     }
87     else
88     {
89       DALI_SCRIPT_EXCEPTION( isolate, "Target actor not specified" );
90       return false;
91     }
92
93     //Get source actor
94     member = obj->Get( v8::String::NewFromUtf8( isolate, "source" ) );
95     if( member->IsObject() )
96     {
97       v8::Local<v8::Object> sourceActorObject = member->ToObject();
98       sourceActor = V8Utils::GetActorFromObject( isolate, found, sourceActorObject );
99       if( !sourceActor )
100       {
101         DALI_SCRIPT_EXCEPTION( isolate, "Source actor not found" );
102         return false;
103       }
104     }
105     else
106     {
107       DALI_SCRIPT_EXCEPTION( isolate, "Source actor not specified" );
108       return false;
109     }
110
111     //Get target property
112     member = obj->Get( v8::String::NewFromUtf8( isolate, "targetProperty" ) );
113     if( member->IsString() )
114     {
115       std::string propertyName = V8Utils::v8StringToStdString( member );
116       targetPropertyIndex = targetActor.GetPropertyIndex( propertyName );
117       if( targetPropertyIndex == Property::INVALID_INDEX )
118       {
119         std::string convertedName = V8Utils::JavaScriptNameToPropertyName( propertyName );
120         targetPropertyIndex = targetActor.GetPropertyIndex( convertedName );
121
122         if( targetPropertyIndex == Property::INVALID_INDEX )
123         {
124           DALI_SCRIPT_EXCEPTION( isolate, "Target property not found" );
125           return false;
126         }
127       }
128     }
129     else
130     {
131       DALI_SCRIPT_EXCEPTION( isolate, "Target property not specified" );
132       return false;
133     }
134
135     //Get source property
136     member = obj->Get( v8::String::NewFromUtf8( isolate, "sourceProperty" ) );
137     if( member->IsString() )
138     {
139       std::string propertyName = V8Utils::v8StringToStdString( member );
140       sourcePropertyIndex = targetActor.GetPropertyIndex( propertyName );
141       if( sourcePropertyIndex == Property::INVALID_INDEX )
142       {
143         std::string convertedName = V8Utils::JavaScriptNameToPropertyName( propertyName );
144         sourcePropertyIndex = targetActor.GetPropertyIndex( convertedName );
145
146         if( sourcePropertyIndex == Property::INVALID_INDEX )
147         {
148           DALI_SCRIPT_EXCEPTION( isolate, "Source property not found" );
149           return false;
150         }
151       }
152     }
153     else
154     {
155       DALI_SCRIPT_EXCEPTION( isolate, "Source property not specified" );
156       return false;
157     }
158
159     //Get range
160     member = obj->Get( v8::String::NewFromUtf8( isolate, "range" ) );
161     if( member->IsObject() )
162     {
163       v8::Local<v8::Object> rangeObject = member->ToObject();
164       Property::Value value = V8Utils::GetPropertyValueFromObject( found, isolate, rangeObject );
165       value.Get( range );
166     }
167     else
168     {
169       DALI_SCRIPT_EXCEPTION( isolate, "Range not specified" );
170       return false;
171     }
172
173     //Get wrap range
174     member = obj->Get( v8::String::NewFromUtf8( isolate, "wrap" ) );
175     if( member->IsObject() )
176     {
177       v8::Local<v8::Object> wrapObject = member->ToObject();
178       Property::Value value = V8Utils::GetPropertyValueFromObject( found, isolate, wrapObject );
179       value.Get( wrap );
180     }
181     else
182     {
183       wrap =  Vector2(-FLT_MAX, FLT_MAX);
184     }
185
186     return true;
187   }
188   else
189   {
190     DALI_SCRIPT_EXCEPTION( isolate, "Bad parameter (Object)" );
191     return false;
192   }
193 }
194
195 } // un-named namespace
196
197 /**
198  * Apply the constraint
199  * @method applyConstraint
200  * @for PathConstrainer and LinearConstrainer
201  * @param {Object}  Constraint
202  * @param {Object}  Constraint.targetActor
203  * @param {String}  Constraint.targetProperty
204  * @param {String}  Constraint.sourceProperty
205  * @param {Vector2} Constraint.range
206  * @param {Vector2} Constraint.wrap
207  *
208  * @example
209  *
210  *        var constraintPosition = {  "target":targetActor,
211  *                                    "targetProperty":"position",
212  *                                    "source":sourceActor,
213  *                                    "sourceProperty":"color-alpha",
214  *                                    "range":range
215  *                                    "wrap":wrap
216  *                                 };
217  *        pathConstrainer.applyConstraint( constraintPosition );
218  */
219 void ConstrainerApi::Apply( const v8::FunctionCallbackInfo< v8::Value >& args )
220 {
221   v8::Isolate* isolate = args.GetIsolate();
222   v8::HandleScope handleScope( isolate );
223
224   Actor target, source;
225   Property::Index targetPropertyIndex = Property::INVALID_INDEX;
226   Property::Index sourcePropertyIndex = Property::INVALID_INDEX;
227
228   Vector2 range, wrap;
229   if( GetApplyParameters(args, target, targetPropertyIndex, source,  sourcePropertyIndex, range, wrap ) )
230   {
231
232     PathConstrainer pathConstrainer = GetPathConstrainer( isolate, args );
233     if( pathConstrainer )
234     {
235       pathConstrainer.Apply( Property(target, targetPropertyIndex),
236                              Property(source, sourcePropertyIndex),
237                              range, wrap );
238     }
239     else
240     {
241       LinearConstrainer linearConstrainer = GetLinearConstrainer( isolate, args );
242       if( linearConstrainer )
243       {
244         linearConstrainer.Apply( Property(target, targetPropertyIndex),
245                                  Property(source, sourcePropertyIndex),
246                                  range, wrap );
247       }
248     }
249   }
250 }
251
252 /**
253  * Remove the constraint
254  * @method remove
255  * @for PathConstrainer
256  * @param {Object} Actor
257  * @example
258  *        pathConstrainer.remove( targetActor );
259  */
260 void ConstrainerApi::Remove( const v8::FunctionCallbackInfo< v8::Value >& args )
261 {
262   v8::Isolate* isolate = args.GetIsolate();
263   v8::HandleScope handleScope( isolate );
264
265   //Get target actor
266   bool found( false );
267   Actor targetActor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
268   if( !found )
269   {
270     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 (Actor)" );
271     return;
272   }
273
274
275   PathConstrainer pathConstrainer = GetPathConstrainer( isolate, args );
276   if( pathConstrainer )
277   {
278     pathConstrainer.Remove(targetActor);
279   }
280   else
281   {
282     LinearConstrainer linearConstrainer = GetLinearConstrainer( isolate, args );
283     if( linearConstrainer )
284     {
285       linearConstrainer.Remove(targetActor);
286     }
287   }
288 }
289
290 } // namespace V8Plugin
291
292 } // namespace Dali