ebc1fa7129e577cfb0a54e787f5b2eb80188529d
[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-view/text-view.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 TextViewApi
45 {
46  Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
47  {
48    return Dali::Toolkit::TextView::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 name or alias.
339  *
340  * Actors can customize this function to provide actors with preferred alias'
341  * For example 'previous' could return the last selected child.
342  * If no aliased actor is found then FindChildByName() is called.
343  *
344  * @for Actor
345  * @method findChildByAlias
346  * @param {String} actor alias
347  * @return {Object} actor on success, empty actor handle if not found
348  */
349 void ActorApi::FindChildByAlias( const v8::FunctionCallbackInfo<v8::Value>& args )
350 {
351   v8::Isolate* isolate = args.GetIsolate();
352   v8::HandleScope handleScope( isolate );
353   Actor parent = GetActor( isolate, args );
354   bool found( false );
355   std::string name = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
356   if( !found )
357   {
358     DALI_SCRIPT_EXCEPTION( isolate, "String parameter not found" );
359     return;
360   }
361   Actor childActor = parent.FindChildByAlias( name );
362   if( childActor )
363   {
364     // wrap the child
365     v8::Local < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, childActor );
366     args.GetReturnValue().Set( wrappedLayer );
367   }
368 }
369
370 /**
371  * Search through this actor's hierarchy for an actor with the given unique ID.
372  * The actor itself is also considered in the search
373  *
374  * @for Actor
375  * @method findChildById
376  * @param {Integer} id
377  * @return {Object} actor on success, empty actor handle if not found
378  */
379 void ActorApi::FindChildById( const v8::FunctionCallbackInfo<v8::Value>& args )
380 {
381   v8::Isolate* isolate = args.GetIsolate();
382   v8::HandleScope handleScope( isolate );
383   Actor parent = GetActor( isolate, args );
384
385   bool found( false );
386   int id = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
387   if( !found )
388   {
389     DALI_SCRIPT_EXCEPTION( isolate, "Integer parameter missing" );
390     return;
391   }
392   Actor childActor = parent.FindChildById( id );
393   if( childActor )
394   {
395     // wrap the child
396     v8::Local < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, childActor );
397     args.GetReturnValue().Set( wrappedLayer );
398   }
399 }
400
401
402 /**
403  * retrieve the actor's parent.
404  *
405  * @for Actor
406  * @method getParent
407  * @return {Object} actor on success, empty actor handle if actor has no parent
408  */
409 void ActorApi::GetParent( const v8::FunctionCallbackInfo<v8::Value>& args )
410 {
411   v8::Isolate* isolate = args.GetIsolate();
412   v8::HandleScope handleScope( isolate );
413   Actor actor = GetActor( isolate, args );
414   Actor parent = actor.GetParent();
415
416   if( parent )
417   {
418     v8::Local < v8::Object > wrappedLayer = ActorWrapper::WrapActor( isolate, parent );
419     args.GetReturnValue().Set( wrappedLayer );
420   }
421 }
422 /**
423  * Converts screen coordinates into the actor's coordinate system using the default camera.
424  *
425  * The actor coordinates are relative to the top-left (0.0, 0.0, 0.5)
426  *
427  * @example
428  *    var local = actor.screenToLocal( [ 10, 53 ]);
429  *    var xPos = local.x;
430  *    var yPos = local.y;
431  *
432  *
433  * @for Actor
434  * @method screenToLocal
435  * @param {Object}  ScreenCoordinates array of 2 objects
436  * @return {Object} local coordinates object with x,y properties
437  */
438 void ActorApi::ScreenToLocal( const v8::FunctionCallbackInfo<v8::Value>& args )
439 {
440   v8::Isolate* isolate = args.GetIsolate();
441   v8::HandleScope handleScope( isolate );
442   Actor actor = GetActor( isolate, args );
443
444   //ool ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const;
445   bool found( false );
446
447   int argCount( args.Length() );
448   Vector2 vector;
449
450   if( argCount == 1 )
451   {
452     vector = V8Utils::GetVector2Parameter( PARAMETER_0, found, isolate, args );
453     if( !found )
454     {
455       DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters (x,y)" );
456       return;
457     }
458   }
459   else
460   {
461     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters (x,y)" );
462     return;
463   }
464   float localX, localY;
465   actor.ScreenToLocal( localX, localY, vector.x, vector.y );
466
467   v8::Local < v8::Object > localCoordinates = v8::Object::New( isolate );
468
469   localCoordinates->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Number::New( isolate, localX ) );
470   localCoordinates->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Number::New( isolate, localY ) );
471
472   args.GetReturnValue().Set( localCoordinates );
473
474 }
475
476 /**
477  * Sets whether the actor should be focusable by keyboard navigation.
478  *
479  * @for Actor
480  * @method setKeyboardFocusable
481  * @param {Boolean}  folcusable
482  */
483 void ActorApi::SetKeyboardFocusable( const v8::FunctionCallbackInfo<v8::Value>& args )
484 {
485   v8::Isolate* isolate = args.GetIsolate();
486   v8::HandleScope handleScope( isolate );
487   Actor actor = GetActor( isolate, args );
488   bool parameterFound( false );
489   bool focus = V8Utils::GetBooleanParameter( PARAMETER_0, parameterFound, isolate, args );
490   if( !parameterFound )
491   {
492     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
493     return;
494   }
495
496   actor.SetKeyboardFocusable( focus );
497 }
498
499 /**
500  * Returns whether the actor is focusable by keyboard navigation.
501  *
502  *
503  * @for Actor
504  * @method isKeyboardFocusable
505  * @return {Boolean}  folcusable
506  */
507 void ActorApi::IsKeyboardFocusable( const v8::FunctionCallbackInfo<v8::Value>& args )
508 {
509   v8::Isolate* isolate = args.GetIsolate();
510   v8::HandleScope handleScope( isolate );
511   Actor actor = GetActor( isolate, args );
512
513   args.GetReturnValue().Set( v8::Boolean::New( isolate, actor.IsKeyboardFocusable() ) );
514
515 }
516 /**
517  * retrieve the actor type
518  *
519  * @for Actor
520  * @method getActorType
521  * @return {String} Actor, ImageActor, TextActor, MeshActor, Layer, CameraActor ...
522  */
523 void ActorApi::GetActorType( const v8::FunctionCallbackInfo<v8::Value>& args )
524 {
525   v8::Isolate* isolate = args.GetIsolate();
526   v8::HandleScope handleScope( isolate );
527   Actor actor = GetActor( isolate, args );
528
529   std::string name = actor.GetTypeName();
530   v8::Local < v8::String > v8String = v8::String::NewFromUtf8( isolate, name.c_str() );
531   args.GetReturnValue().Set( v8String );
532 }
533 /**
534  * Move an actor relative to its existing position.
535  * @example
536  *
537  *    // using an array
538  *    actor.moveBy( [20,40,0] );
539  *
540  * @for Actor
541  * @method moveBy
542  * @param {object} an array of 3 numbers
543  */
544 void ActorApi::MoveBy( const v8::FunctionCallbackInfo<v8::Value>& args )
545 {
546   v8::Isolate* isolate = args.GetIsolate();
547   v8::HandleScope handleScope( isolate );
548   Actor actor = GetActor( isolate, args );
549
550   //Get displacement vector
551   Vector3 vector;
552   int argCount( args.Length() );
553   if( argCount == 1 )
554   {
555     bool found(false);
556     vector = V8Utils::GetVector3Parameter( PARAMETER_0, found, isolate, args );
557     if( !found )
558     {
559       DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
560       return;
561     }
562   }
563   else
564   {
565     DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
566     return;
567   }
568   actor.MoveBy( vector );
569
570 }
571
572
573 /**
574  * Apply a relative rotation to an actor.
575  * @example
576  *
577  *     var rotation =new dali.Rotation( pitch, roll, yaw );
578  *     actor.rotateBy( rotation );
579  *
580  * @for Actor
581  * @method rotateBy
582  * @param {object} dali rotation object
583  */
584 void ActorApi::RotateBy( const v8::FunctionCallbackInfo<v8::Value>& args )
585 {
586   v8::Isolate* isolate = args.GetIsolate();
587   v8::HandleScope handleScope( isolate );
588   Actor actor = GetActor( isolate, args );
589
590   bool found( false );
591   Property::Value rotation = V8Utils::GetPropertyValueParameter( PARAMETER_0, found, isolate, args );
592
593   if( rotation.GetType() != Property::ROTATION )
594   {
595     DALI_SCRIPT_EXCEPTION( isolate, "Rotation parameter missing" );
596     return;
597   }
598   // the rotation parameter has to be either a AngleAxis or a Quaternion
599   // both will work when calling Get( Quaternion);
600
601   Quaternion quaternionValue;
602   rotation.Get( quaternionValue );
603
604   actor.RotateBy( quaternionValue );
605 }
606
607 /**
608  * Apply a relative scale to an actor.
609  * @example
610  *    // Double actor width and height ( keep depth the same )
611  *    // using an array
612  *    actor.scaleBy( [2,2,1] );
613  *
614  *
615  * @for Actor
616  * @method scaleBy
617  * @param {object} JavaScript array
618  */
619 void ActorApi::ScaleBy( const v8::FunctionCallbackInfo<v8::Value>& args )
620 {
621   v8::Isolate* isolate = args.GetIsolate();
622   v8::HandleScope handleScope( isolate );
623   Actor actor = GetActor( isolate, args );
624
625   Vector3 vector;
626   int argCount( args.Length() );
627   if( argCount == 1 )
628   {
629     bool found(false);
630     vector = V8Utils::GetVector3Parameter( PARAMETER_0, found, isolate, args );
631     if( !found )
632     {
633       DALI_SCRIPT_EXCEPTION( isolate, "Vector3 move parameter missing" );
634       return;
635     }
636   }
637   else
638   {
639     DALI_SCRIPT_EXCEPTION( isolate, "Vector3 parameter missing" );
640     return;
641   }
642   actor.ScaleBy( vector );
643 }
644 /**
645  * Apply a relative scale to an actor.
646  * Actor opacity ranges from 0 (see through ) to 1 ( solid )
647  * @example
648  *    // reduce actor opactiy by a half
649  *    actor.opaictyBy(-0.5);
650  *
651  * @for Actor
652  * @method OpacityBy
653  * @param {float} relative opacity
654  */
655 void ActorApi::OpacityBy( const v8::FunctionCallbackInfo<v8::Value>& args )
656 {
657   v8::Isolate* isolate = args.GetIsolate();
658   v8::HandleScope handleScope( isolate );
659   Actor actor = GetActor( isolate, args );
660
661   // void OpacityBy(float relativeOpacity);
662   bool found;
663   float opacity = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
664   if( !found )
665   {
666     DALI_SCRIPT_EXCEPTION( isolate, "float parameter missing" );
667     return;
668   }
669   actor.OpacityBy( opacity );
670 }
671
672 /**
673  * Apply a relative color change to an actor.
674  *
675  * @example
676  *    // increase actor red by half
677  *    actor.colorBy( [0.5, 0, 0, 0]);
678  *
679  *
680  * @for Actor
681  * @method colorBy
682  * @param {Object} Color JavaScript array
683  */
684 void ActorApi::ColorBy( const v8::FunctionCallbackInfo<v8::Value>& args )
685 {
686   v8::Isolate* isolate = args.GetIsolate();
687   v8::HandleScope handleScope( isolate );
688   Actor actor = GetActor( isolate, args );
689
690   bool found;
691   int argCount( args.Length() );
692   Vector4 color;
693
694   if( argCount == 1 )
695   {
696     color = V8Utils::GetVector4Parameter( PARAMETER_0, found, isolate, args );
697     if( !found )
698     {
699       DALI_SCRIPT_EXCEPTION( isolate, "Vector4 parameter missing" );
700       return;
701     }
702   }
703   else
704   {
705     DALI_SCRIPT_EXCEPTION( isolate, "Vector4 parameter missing" );
706     return;
707   }
708
709   actor.ColorBy( color );
710 }
711
712
713 } // namespace V8Plugin
714
715 } // namespace Dali