Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / actors / actor-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 "actor-api.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
23
24 // INTERNAL INCLUDES
25 #include <v8-utils.h>
26 #include <actors/actor-wrapper.h>
27
28 namespace Dali
29 {
30
31 namespace V8Plugin
32 {
33
34 namespace  // unanmed namespace
35 {
36 Actor GetActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
37 {
38   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
39   return Actor::DownCast( handleWrapper->mHandle );
40 }
41 } //unanmed namespace
42
43
44 namespace TextLabelApi
45 {
46  Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
47  {
48    return Dali::Toolkit::TextLabel::New();
49  }
50 }
51
52 /***************************************
53  * ACTOR API FUNCTIONS
54  ****************************************/
55 /**
56  * Constructor
57  *
58  * @for Actor
59  * @constructor
60  * @method Actor
61  * @return {Object} actor
62  */
63 Actor ActorApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
64 {
65   return Actor::New();
66 }
67
68 /**
69  * get the actors unique id
70  *
71  * @for Actor
72  * @method getId
73  * @return {Integer} id
74  */
75 void ActorApi::GetId( const v8::FunctionCallbackInfo<v8::Value>& args )
76 {
77   v8::Isolate* isolate = args.GetIsolate();
78   v8::HandleScope handleScope( isolate );
79   Actor actor = GetActor( isolate, args );
80
81   args.GetReturnValue().Set( v8::Integer::New( isolate, actor.GetId() ) );
82 }
83
84 /**
85  * Query whether an actor is the root actor, which is owned by the Stage
86  *
87  * @for Actor
88  * @method isRoot
89  * @return {Boolean} true if it is root
90  *
91  */
92 void ActorApi::IsRoot( const v8::FunctionCallbackInfo<v8::Value>& args )
93 {
94   v8::Isolate* isolate = args.GetIsolate();
95   v8::HandleScope handleScope( isolate );
96   Actor actor = GetActor( isolate, args );
97
98   args.GetReturnValue().Set( v8::Boolean::New( isolate, actor.IsRoot() ) );
99 }
100
101 /**
102  *
103  * Query whether the actor is connected to the Stage.
104  * When an actor is connected, it will be directly or indirectly parented to the root Actor.
105  * The root Actor is provided automatically by dali.stage, and is always considered to be connected.
106  *
107  * @for Actor
108  * @method onStage
109  * @return {Boolean} True if the actor is connected to the Stage
110  */
111 void ActorApi::OnStage( const v8::FunctionCallbackInfo<v8::Value>& args )
112 {
113   v8::Isolate* isolate = args.GetIsolate();
114   v8::HandleScope handleScope( isolate );
115   Actor actor = GetActor( isolate, args );
116
117   args.GetReturnValue().Set( v8::Boolean::New( isolate, actor.OnStage() ) );
118 }
119
120 /**
121  * Query whether an actor is a layer
122  *
123  * @for Actor
124  * @method isLayer
125  * @return {Boolean} true if it is a layer
126  */
127 void ActorApi::IsLayer( const v8::FunctionCallbackInfo<v8::Value>& args )
128 {
129   v8::Isolate* isolate = args.GetIsolate();
130   v8::HandleScope handleScope( isolate );
131   Actor actor = GetActor( isolate, args );
132
133   args.GetReturnValue().Set( v8::Boolean::New( isolate, actor.IsLayer() ) );
134 }
135
136 /**
137  * Gets the layer in which the actor is present.
138  *
139  * @for Actor
140  * @method getLayer
141  * @return {Object} Layer
142  */
143 void ActorApi::GetLayer( const v8::FunctionCallbackInfo<v8::Value>& args )
144 {
145   v8::Isolate* isolate = args.GetIsolate();
146   v8::HandleScope handleScope( isolate );
147   Actor actor = GetActor( isolate, args );
148   Layer layer = actor.GetLayer();
149   if( layer ) // actors don't always have a layer
150   {
151     v8::Handle < v8::Object > wrappedLayer = ActorWrapper::ActorWrapper::WrapActor( isolate, layer, ActorWrapper::LAYER_ACTOR );
152     args.GetReturnValue().Set( wrappedLayer );
153   }
154   // else return an empty object
155 }
156
157 /**
158  * Adds a child Actor to this Actor.
159  *
160  * NOTE! if the child already has a parent, it will be removed from old parent
161  * and reparented to this actor. This may change childs position, color, shader effect,
162  * scale etc as it now inherits them from this actor
163  *
164  * Pre-conditions
165  * - The child actor is not the same as the parent actor.
166  * - The actor is not the Root actor
167
168  * Once added The child will be referenced by its parent. This means that the child will be kept alive,
169  * even if the handle passed into this method is reset or destroyed.
170  *
171  * @for Actor
172  * @method add
173  * @param {Object} Actor
174  */
175 void ActorApi::AddActor( const v8::FunctionCallbackInfo<v8::Value>& args )
176 {
177   v8::Isolate* isolate = args.GetIsolate();
178   v8::HandleScope handleScope( isolate );
179   Actor parent = GetActor( isolate, args );
180   bool found(false);
181   Actor child = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
182   if( found )
183   {
184     parent.Add( child );
185   }
186   else
187   {
188     DALI_SCRIPT_EXCEPTION( isolate, "child parameter missing" );
189   }
190 }
191
192 /**
193  * Removes a child Actor from this Actor.
194  *
195  * If the actor was not a child of this actor, this is a no-op.
196  *
197  * Preconditions:
198  * -  The child actor is not the same as the parent actor.
199  *
200  * @for Actor
201  * @param{Object} Actor the child actor
202  * @method Remove
203  */
204 void ActorApi::RemoveActor( const v8::FunctionCallbackInfo<v8::Value>& args )
205 {
206   v8::Isolate* isolate = args.GetIsolate();
207   v8::HandleScope handleScope( isolate );
208   Actor parent = GetActor( isolate, args );
209   bool found( false );
210   Actor child = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
211
212   if( found )
213   {
214     parent.Remove( child );
215   }
216   else
217   {
218     DALI_SCRIPT_EXCEPTION( isolate, "child parameter missing" );
219   }
220 }
221
222 /**
223  * Checks whether an Actor is equal to this Actor.
224  *
225  * @for Actor
226  * @method iIsEqualTo
227  * @param {Object} Actor
228  */
229 void ActorApi::IsEqualTo( const v8::FunctionCallbackInfo<v8::Value>& args )
230 {
231   v8::Isolate* isolate = args.GetIsolate();
232   v8::HandleScope handleScope( isolate );
233   Actor self = GetActor( isolate, args );
234   bool found( false );
235
236   Actor actor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
237   if( found )
238   {
239     args.GetReturnValue().Set( v8::Boolean::New( isolate, (actor == self) ) );
240   }
241   else
242   {
243     DALI_SCRIPT_EXCEPTION( isolate, "actor parameter missing" );
244   }
245 }
246
247 /** Removes an actor from its parent.
248  *
249  * If the actor has no parent, this method does nothing.
250  *
251  * @for Actor
252  * @method Unparent
253  */
254 void ActorApi::Unparent( const v8::FunctionCallbackInfo< v8::Value >& args)
255 {
256   v8::Isolate* isolate = args.GetIsolate();
257   v8::HandleScope handleScope( isolate );
258   Actor actor = GetActor( isolate, args );
259   actor.Unparent();
260 }
261
262 /**
263  * get number of child actors
264  *
265  * @for Actor
266  * @method getChildCount
267  * @return {Integer} count
268  */
269 void ActorApi::GetChildCount( const v8::FunctionCallbackInfo<v8::Value>& args )
270 {
271   v8::Isolate* isolate = args.GetIsolate();
272   v8::HandleScope handleScope( isolate );
273   Actor actor = GetActor( isolate, args );
274
275   args.GetReturnValue().Set( v8::Integer::New( isolate, actor.GetChildCount() ) );
276 }
277
278 /**
279  * Retrieve and child actor by index.
280  *
281  * @for Actor
282  * @method getChildAt
283  * @param {Integer} actor index
284  * @return {Object} actor on success, empty actor handle if not found
285  */
286 void ActorApi::GetChildAt( const v8::FunctionCallbackInfo<v8::Value>& args )
287 {
288   v8::Isolate* isolate = args.GetIsolate();
289   v8::HandleScope handleScope( isolate );
290   Actor parent = GetActor( isolate, args );
291   bool found( false );
292   int id = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
293   if( !found )
294   {
295     DALI_SCRIPT_EXCEPTION( isolate, "Integer parameter missing" );
296     return;
297   }
298   Actor childActor = parent.GetChildAt( id );
299   if( childActor )
300   {
301     // wrap the child
302     v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, childActor );
303     args.GetReturnValue().Set( wrappedActor );
304   }
305 }
306
307 /**
308  * Search through this actor's hierarchy for an actor with the given name
309  * The actor itself is also considered in the search
310  *
311  * @for Actor
312  * @method findChildByName
313  * @param {String} actor name
314  * @return {Object} actor on success, empty actor handle if not found
315  */
316 void ActorApi::FindChildByName( const v8::FunctionCallbackInfo<v8::Value>& args )
317 {
318   v8::Isolate* isolate = args.GetIsolate();
319   v8::HandleScope handleScope( isolate );
320   Actor parent = GetActor( isolate, args );
321   bool found( false );
322   std::string name = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
323   if( !found )
324   {
325     DALI_SCRIPT_EXCEPTION( isolate, "string parameter missing" );
326     return;
327   }
328   Actor childActor = parent.FindChildByName( name );
329   if( childActor )
330   {
331     // wrap the child
332     v8::Handle < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, childActor );
333     args.GetReturnValue().Set( wrappedLayer );
334   }
335 }
336
337 /**
338  * Search through this actor's hierarchy for an actor with the given unique ID.
339  * The actor itself is also considered in the search
340  *
341  * @for Actor
342  * @method findChildById
343  * @param {Integer} id
344  * @return {Object} actor on success, empty actor handle if not found
345  */
346 void ActorApi::FindChildById( const v8::FunctionCallbackInfo<v8::Value>& args )
347 {
348   v8::Isolate* isolate = args.GetIsolate();
349   v8::HandleScope handleScope( isolate );
350   Actor parent = GetActor( isolate, args );
351
352   bool found( false );
353   int id = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
354   if( !found )
355   {
356     DALI_SCRIPT_EXCEPTION( isolate, "Integer parameter missing" );
357     return;
358   }
359   Actor childActor = parent.FindChildById( id );
360   if( childActor )
361   {
362     // wrap the child
363     v8::Local < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, childActor );
364     args.GetReturnValue().Set( wrappedLayer );
365   }
366 }
367
368
369 /**
370  * retrieve the actor's parent.
371  *
372  * @for Actor
373  * @method getParent
374  * @return {Object} actor on success, empty actor handle if actor has no parent
375  */
376 void ActorApi::GetParent( const v8::FunctionCallbackInfo<v8::Value>& args )
377 {
378   v8::Isolate* isolate = args.GetIsolate();
379   v8::HandleScope handleScope( isolate );
380   Actor actor = GetActor( isolate, args );
381   Actor parent = actor.GetParent();
382
383   if( parent )
384   {
385     v8::Local < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, parent );
386     args.GetReturnValue().Set( wrappedLayer );
387   }
388 }
389 /**
390  * Converts screen coordinates into the actor's coordinate system using the default camera.
391  *
392  * The actor coordinates are relative to the top-left (0.0, 0.0, 0.5)
393  *
394  * @example
395  *    var local = actor.screenToLocal( [ 10, 53 ]);
396  *    var xPos = local.x;
397  *    var yPos = local.y;
398  *
399  *
400  * @for Actor
401  * @method screenToLocal
402  * @param {Object}  ScreenCoordinates array of 2 objects
403  * @return {Object} local coordinates object with x,y properties
404  */
405 void ActorApi::ScreenToLocal( const v8::FunctionCallbackInfo<v8::Value>& args )
406 {
407   v8::Isolate* isolate = args.GetIsolate();
408   v8::HandleScope handleScope( isolate );
409   Actor actor = GetActor( isolate, args );
410
411   //ool ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const;
412   bool found( false );
413
414   int argCount( args.Length() );
415   Vector2 vector;
416
417   if( argCount == 1 )
418   {
419     vector = V8Utils::GetVector2Parameter( PARAMETER_0, found, isolate, args );
420     if( !found )
421     {
422       DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters (x,y)" );
423       return;
424     }
425   }
426   else
427   {
428     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters (x,y)" );
429     return;
430   }
431   float localX, localY;
432   actor.ScreenToLocal( localX, localY, vector.x, vector.y );
433
434   v8::Local < v8::Object > localCoordinates = v8::Object::New( isolate );
435
436   localCoordinates->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Number::New( isolate, localX ) );
437   localCoordinates->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Number::New( isolate, localY ) );
438
439   args.GetReturnValue().Set( localCoordinates );
440
441 }
442
443 /**
444  * Sets whether the actor should be focusable by keyboard navigation.
445  *
446  * @for Actor
447  * @method setKeyboardFocusable
448  * @param {Boolean}  folcusable
449  */
450 void ActorApi::SetKeyboardFocusable( const v8::FunctionCallbackInfo<v8::Value>& args )
451 {
452   v8::Isolate* isolate = args.GetIsolate();
453   v8::HandleScope handleScope( isolate );
454   Actor actor = GetActor( isolate, args );
455   bool parameterFound( false );
456   bool focus = V8Utils::GetBooleanParameter( PARAMETER_0, parameterFound, isolate, args );
457   if( !parameterFound )
458   {
459     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
460     return;
461   }
462
463   actor.SetKeyboardFocusable( focus );
464 }
465
466 /**
467  * Returns whether the actor is focusable by keyboard navigation.
468  *
469  *
470  * @for Actor
471  * @method isKeyboardFocusable
472  * @return {Boolean}  folcusable
473  */
474 void ActorApi::IsKeyboardFocusable( const v8::FunctionCallbackInfo<v8::Value>& args )
475 {
476   v8::Isolate* isolate = args.GetIsolate();
477   v8::HandleScope handleScope( isolate );
478   Actor actor = GetActor( isolate, args );
479
480   args.GetReturnValue().Set( v8::Boolean::New( isolate, actor.IsKeyboardFocusable() ) );
481
482 }
483 /**
484  * retrieve the actor type
485  *
486  * @for Actor
487  * @method getActorType
488  * @return {String} Actor, ImageActor, MeshActor, Layer, CameraActor ...
489  */
490 void ActorApi::GetActorType( const v8::FunctionCallbackInfo<v8::Value>& args )
491 {
492   v8::Isolate* isolate = args.GetIsolate();
493   v8::HandleScope handleScope( isolate );
494   Actor actor = GetActor( isolate, args );
495
496   std::string name = actor.GetTypeName();
497   v8::Local < v8::String > v8String = v8::String::NewFromUtf8( isolate, name.c_str() );
498   args.GetReturnValue().Set( v8String );
499 }
500 /**
501  * Move an actor relative to its existing position.
502  * @example
503  *
504  *    // using an array
505  *    actor.translateBy( [20,40,0] );
506  *
507  * @for Actor
508  * @method translateBy
509  * @param {object} an array of 3 numbers
510  */
511 void ActorApi::TranslateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
512 {
513   v8::Isolate* isolate = args.GetIsolate();
514   v8::HandleScope handleScope( isolate );
515   Actor actor = GetActor( isolate, args );
516
517   //Get displacement vector
518   Vector3 vector;
519   int argCount( args.Length() );
520   if( argCount == 1 )
521   {
522     bool found(false);
523     vector = V8Utils::GetVector3Parameter( PARAMETER_0, found, isolate, args );
524     if( !found )
525     {
526       DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
527       return;
528     }
529   }
530   else
531   {
532     DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
533     return;
534   }
535   actor.TranslateBy( vector );
536
537 }
538
539
540 /**
541  * Apply a relative rotation to an actor.
542  * @example
543  *
544  *     var rotation =new dali.Rotation( pitch, roll, yaw );
545  *     actor.rotateBy( rotation );
546  *
547  * @for Actor
548  * @method rotateBy
549  * @param {object} dali rotation object
550  */
551 void ActorApi::RotateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
552 {
553   v8::Isolate* isolate = args.GetIsolate();
554   v8::HandleScope handleScope( isolate );
555   Actor actor = GetActor( isolate, args );
556
557   bool found( false );
558   Property::Value rotation = V8Utils::GetPropertyValueParameter( PARAMETER_0, found, isolate, args );
559
560   if( rotation.GetType() != Property::ROTATION )
561   {
562     DALI_SCRIPT_EXCEPTION( isolate, "Rotation parameter missing" );
563     return;
564   }
565   // the rotation parameter has to be either a AngleAxis or a Quaternion
566   // both will work when calling Get( Quaternion);
567
568   Quaternion quaternionValue;
569   rotation.Get( quaternionValue );
570
571   actor.RotateBy( quaternionValue );
572 }
573
574 /**
575  * Apply a relative scale to an actor.
576  * @example
577  *    // Double actor width and height ( keep depth the same )
578  *    // using an array
579  *    actor.scaleBy( [2,2,1] );
580  *
581  *
582  * @for Actor
583  * @method scaleBy
584  * @param {object} JavaScript array
585  */
586 void ActorApi::ScaleBy( const v8::FunctionCallbackInfo<v8::Value>& args )
587 {
588   v8::Isolate* isolate = args.GetIsolate();
589   v8::HandleScope handleScope( isolate );
590   Actor actor = GetActor( isolate, args );
591
592   Vector3 vector;
593   int argCount( args.Length() );
594   if( argCount == 1 )
595   {
596     bool found(false);
597     vector = V8Utils::GetVector3Parameter( PARAMETER_0, found, isolate, args );
598     if( !found )
599     {
600       DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
601       return;
602     }
603   }
604   else
605   {
606     DALI_SCRIPT_EXCEPTION( isolate, "Vector3 parameter missing" );
607     return;
608   }
609   actor.ScaleBy( vector );
610 }
611
612 } // namespace V8Plugin
613
614 } // namespace Dali