Merge "JavaScript support for DALi" into tizen
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / actors / renderable-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 "renderable-actor-api.h"
20
21 // INTERNAL INCLUDES
22 #include <object/handle-wrapper.h>
23 #include <v8-utils.h>
24 #include <object/property-value-wrapper.h>
25 #include <shader-effects/shader-effect-api.h>
26 #include <shader-effects/shader-effect-wrapper.h>
27
28 namespace Dali
29 {
30
31 namespace V8Plugin
32 {
33
34 namespace //unnamed name space
35 {
36 RenderableActor GetRenderableActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
37 {
38   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
39   return RenderableActor::DownCast( handleWrapper->mHandle );
40 }
41 }
42 /***************************************
43  * RENDERABLE ACTOR FUNCTIONS
44  *
45  ****************************************/
46 /**
47  * Allows modification of an actors position in the depth sort algorithm.
48  *
49  * The offset can be altered for each coplanar actor hence allowing an order of painting.
50  * @param { Number }  depthOffset the offset to be given to the actor. Positive values pushing it further back.
51  * @for RenderableActor
52  * @method setSortModifier
53  */
54 void RenderableActorApi::SetSortModifier( const v8::FunctionCallbackInfo<v8::Value>& args )
55 {
56   v8::Isolate* isolate = args.GetIsolate();
57   v8::HandleScope handleScope( isolate );
58   RenderableActor actor = GetRenderableActor( isolate, args );
59
60   bool found( false );
61   float value = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
62   if( !found )
63   {
64     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
65     return;
66   }
67   actor.SetSortModifier( value );
68 }
69
70 /**
71  * Retrieves the offset used to modify an actors position in the depth sort algorithm.
72  * @for RenderableActor
73  * @method getSortModifier .
74  * @return { Number} the offset that has been given to the actor. Positive values pushing it further back
75  */
76 void RenderableActorApi::GetSortModifier( const v8::FunctionCallbackInfo<v8::Value>& args )
77 {
78   v8::Isolate* isolate = args.GetIsolate();
79   v8::HandleScope handleScope( isolate );
80   RenderableActor actor = GetRenderableActor( isolate, args );
81
82   args.GetReturnValue().Set( v8::Number::New( isolate, actor.GetSortModifier() ) );
83
84 }
85
86 /**
87  * Set the face-culling mode for this actor.
88  * @for RenderableActor
89  * @method setCullFace
90  * @param {Number} cullMode
91  * @example
92  *      // cull mode should be one of the following constants
93  *      dali.CULL_FACE_DISABLE        // Face culling disabled
94  *      dali.CULL_FRONT_FACE          // Cull front facing polygons
95  *      dali.CULL_BACK_FACE           // Cull back facing polygons
96  *      dali.CULL_FRONT_AND_BACK_FACE // Cull front and back facing polygons
97  *      actor.SetCullFace( dali.CULL_FRONT_FACE );
98  */
99 void RenderableActorApi::SetCullFace( const v8::FunctionCallbackInfo<v8::Value>& args )
100 {
101   v8::Isolate* isolate = args.GetIsolate();
102   v8::HandleScope handleScope( isolate );
103   RenderableActor actor = GetRenderableActor( isolate, args );
104
105   bool found( false );
106   int cullMode = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
107   if( !found )
108   {
109     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter" );
110     return;
111   }
112
113   actor.SetCullFace(  static_cast<Dali::CullFaceMode>( cullMode ) );
114
115 }
116
117 /**
118  * Retrieve the face-culling mode for this actor.
119  * @for RenderableActor
120  * @method getCullFace
121  * @return {Number} cullMode
122  * @example
123  *      // cull mode is one of the following
124  *      dali.CULL_FACE_DISABLE        // Face culling disabled
125  *      dali.CULL_FRONT_FACE          // Cull front facing polygons
126  *      dali.CULL_BACK_FACE           // Cull back facing polygons
127  *      dali.CULL_FRONT_AND_BACK_FACE // Cull front and back facing polygon
128  */
129 void RenderableActorApi::GetCullFace( const v8::FunctionCallbackInfo<v8::Value>& args )
130 {
131   v8::Isolate* isolate = args.GetIsolate();
132   v8::HandleScope handleScope( isolate );
133   RenderableActor actor = GetRenderableActor( isolate, args );
134
135   args.GetReturnValue().Set( v8::Integer::New( isolate, actor.GetCullFace() ) );
136
137 }
138
139 /**
140  * Sets the blending mode.
141  *
142  * If blending is disabled (BLENDING_OFF) fade in and fade out animations do not work.
143  *
144  * @example
145  *      // blend mode is one of the following
146  *      dali.BLENDING_OFF       // Blending is disabled.
147  *      dali.BLENDING_AUTO      // Blending is enabled if there is alpha channel.
148  *      dali.BLENDING_ON        // Blending is enabled.
149  *      actor.SetBlendMode( dali.BLENDING_AUTO );
150  *
151  * @for RenderableActor
152  * @method setBlendMode
153  * @param { Number } blendMode
154  */
155 void RenderableActorApi::SetBlendMode( const v8::FunctionCallbackInfo<v8::Value>& args )
156 {
157   v8::Isolate* isolate = args.GetIsolate();
158   v8::HandleScope handleScope( isolate );
159   RenderableActor actor = GetRenderableActor( isolate, args );
160
161   bool found( false );
162   int mode = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
163   if( !found )
164   {
165     DALI_SCRIPT_EXCEPTION( isolate, "invalid BlendMode parameter" );
166     return;
167   }
168   actor.SetBlendMode( static_cast<Dali::BlendingMode::Type>( mode ) );
169
170 }
171
172 /**
173  * @for RenderableActor
174  * @method getBlendMode
175  * @return { Number } blendMode
176  * @example returns one of the following:
177  *
178  *        dali.BLENDING_OFF       // Blending is disabled.
179  *        dali.BLENDING_AUTO      // Blending is enabled if there is alpha channel.
180  *        dali.BLENDING_ON        // Blending is enabled.
181  *
182  */
183 void RenderableActorApi::GetBlendMode( const v8::FunctionCallbackInfo<v8::Value>& args )
184 {
185   v8::Isolate* isolate = args.GetIsolate();
186   v8::HandleScope handleScope( isolate );
187   RenderableActor actor = GetRenderableActor( isolate, args );
188
189   args.GetReturnValue().Set( v8::Integer::New( isolate, actor.GetBlendMode() ) );
190
191 }
192
193 // 2 function definitions, as Dali uses 2 functions.
194 // JavaScript can't overload but we can document it twice with different params
195 /**
196  * @for RenderableActor
197  * @method setBlendFunc
198  * @param {Number} SourceBlending RGBA
199  * @param {Number} DestinationBlending RGBA
200  * @example
201  *      blending constants
202       dali.BLEND_FACTOR_ZERO
203       dali.BLEND_FACTOR_ONE
204       dali.BLEND_FACTOR_SRC_COLOR
205       dali.BLEND_FACTOR_ONE_MINUS_SRC_COLOR
206       dali.BLEND_FACTOR_SRC_ALPHA
207       dali.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
208       dali.BLEND_FACTOR_DST_ALPHA
209       dali.BLEND_FACTOR_ONE_MINUS_DST_ALPHA
210       dali.BLEND_FACTOR_DST_COLOR
211       dali.BLEND_FACTOR_ONE_MINUS_DST_COLOR
212       dali.BLEND_FACTOR_SRC_ALPHA_SATURATE
213       dali.BLEND_FACTOR_CONSTANT_COLOR
214       dali.BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
215       dali.BLEND_FACTOR_CONSTANT_ALPHA
216       dali.BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
217
218       actor.setBlendFunc( dali.BLEND_FACTOR_ONE_MINUS_SRC_COLOR, dali.BLEND_FACTOR_ONE_MINUS_DST_COLOR);
219  */
220
221 /**
222  * @for RenderableActor
223  * @method setBlendFunc
224  * @param {Number} SourceBlending RGB
225  * @param {Number} DestinationBlending RGB
226  * @param {Number} SourceBlending Alpha
227  * @param {Number} DestinatinoBlending Alpha
228  * @example
229  *      //blending constants
230       dali.BLEND_FACTOR_ZERO
231       dali.BLEND_FACTOR_ONE
232       dali.BLEND_FACTOR_SRC_COLOR
233       dali.BLEND_FACTOR_ONE_MINUS_SRC_COLOR
234       dali.BLEND_FACTOR_SRC_ALPHA
235       dali.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
236       dali.BLEND_FACTOR_DST_ALPHA
237       dali.BLEND_FACTOR_ONE_MINUS_DST_ALPHA
238       dali.BLEND_FACTOR_DST_COLOR
239       dali.BLEND_FACTOR_ONE_MINUS_DST_COLOR
240       dali.BLEND_FACTOR_SRC_ALPHA_SATURATE
241       dali.BLEND_FACTOR_CONSTANT_COLOR
242       dali.BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
243       dali.BLEND_FACTOR_CONSTANT_ALPHA
244       dali.BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
245
246       actor.setBlendFunc(  dali.BLEND_FACTOR_CONSTANT_COLOR, BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
247                                 dali.BLEND_FACTOR_CONSTANT_ALPHA, BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA);
248
249       );
250  */
251 void RenderableActorApi::SetBlendFunc( const v8::FunctionCallbackInfo< v8::Value >& args )
252 {
253   v8::Isolate* isolate = args.GetIsolate();
254   v8::HandleScope handleScope( isolate );
255   RenderableActor actor =  GetRenderableActor( isolate, args );
256
257   int params[4];
258   if( args.Length() == 2 )
259   {
260     bool foundAllParams(false);
261     V8Utils::ReadIntegerArguments( foundAllParams, &params[0], 2, args,0 );
262     if( foundAllParams )
263     {
264       actor.SetBlendFunc(  static_cast< Dali::BlendingFactor::Type>(params[0]),
265                            static_cast< Dali::BlendingFactor::Type>(params[1]) );
266     }
267     else
268     {
269       DALI_SCRIPT_EXCEPTION( isolate, "invalid BlendMode parameter");
270       return;
271     }
272   }
273   else if ( args.Length() == 4)
274   {
275     bool foundAllParams(false);
276     V8Utils::ReadIntegerArguments( foundAllParams, &params[0], 4, args,0 );
277     if( foundAllParams )
278     {
279       actor.SetBlendFunc(  static_cast< Dali::BlendingFactor::Type>(params[0]),
280                            static_cast< Dali::BlendingFactor::Type>(params[1]),
281                            static_cast< Dali::BlendingFactor::Type>(params[2]),
282                            static_cast< Dali::BlendingFactor::Type>(params[3]));
283     }
284     else
285     {
286       DALI_SCRIPT_EXCEPTION( isolate, "invalid BlendMode parameter");
287       return;
288     }
289   }
290
291 }
292
293 /**
294  * @for RenderableActor
295  * @method GetBlendFunc
296  * @return {Object} BlendProperties
297  * @example Blend properties object has 4 fields
298  *
299  *      blendProperties.sourceRgb // source rgb enum
300  *      blendProperties.destinationRgb  // destination rgb enum
301  *      blendProperties.sourceAlpha source // alpha enum
302  *      blendProperties.destinationAlpha // destination alpha enum
303  */
304 void RenderableActorApi::GetBlendFunc( const v8::FunctionCallbackInfo< v8::Value >& args )
305 {
306   // @todo pass by reference doesn't work in Javascript so need to decide what to return
307   // for now just return a vector 4...
308
309   BlendingFactor::Type srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha;
310   v8::Isolate* isolate = args.GetIsolate();
311   v8::HandleScope handleScope( isolate );
312   RenderableActor actor = GetRenderableActor( isolate, args );
313
314   actor.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
315
316   v8::Local<v8::Object> blendInfo = v8::Object::New( isolate );
317
318   blendInfo->Set( v8::String::NewFromUtf8( isolate, "sourceRgb" ),        v8::Integer::New( isolate, srcFactorRgb) );
319   blendInfo->Set( v8::String::NewFromUtf8( isolate, "destinationRgb" ),   v8::Integer::New( isolate, destFactorRgb ) );
320   blendInfo->Set( v8::String::NewFromUtf8( isolate, "sourceAlpha" ),      v8::Integer::New( isolate, srcFactorAlpha  ) );
321   blendInfo->Set( v8::String::NewFromUtf8( isolate, "destinationAlpha" ), v8::Integer::New( isolate, destFactorAlpha ) );
322
323   args.GetReturnValue().Set( blendInfo );
324
325 }
326 // 2 function definitions, as Dali uses 2 functions.
327 // JavaScript can't overload but we can document it twice with different params
328 /**
329  * @for RenderableActor
330  * @method setBlendEquation
331  * @param {Number } BlendEquation for RGBA
332  * @example
333  *
334  *      //blending equation constants
335       dali.BLEND_EQUATION_ADD
336       dali.BLEND_EQUATION_SUBTRACT
337       dali.BLEND_EQUATION_REVERSE_SUBTRACT
338       actor.setBlendEquation( dali.BLEND_EQUATION_ADD );
339
340  */
341
342 /**
343  * @for RenderableActor
344  * @method setBlendEquation
345  * @param {Number } BlendEquation for RGB
346  * @param {Number } BlendEquation for Alpha
347  * @example
348  *
349  *      //blending equation constants
350       dali.BLEND_EQUATION_ADD
351       dali.BLEND_EQUATION_SUBTRACT
352       dali.BLEND_EQUATION_REVERSE_SUBTRACT
353       actor.setBlendEquationSeparate( dali.BLEND_EQUATION_ADD, dali.BLEND_EQUATION_SUBTRACT  );
354
355  */
356 void RenderableActorApi::SetBlendEquation( const v8::FunctionCallbackInfo< v8::Value >& args )
357 {
358   v8::Isolate* isolate = args.GetIsolate();
359   v8::HandleScope handleScope( isolate );
360   RenderableActor actor = GetRenderableActor( isolate, args );
361
362   int params[2];
363   if( args.Length() == 1 )
364   {
365     bool foundAllParams( false );
366     V8Utils::ReadIntegerArguments( foundAllParams, &params[0], 1, args, 0 );
367     if( foundAllParams )
368     {
369       actor.SetBlendEquation( static_cast<Dali::BlendingEquation::Type>( params[0] ) );
370     }
371     else
372     {
373       DALI_SCRIPT_EXCEPTION( isolate, "invalid BlendEquation parameter" );
374       return;
375     }
376   }
377   else if( args.Length() == 2 )
378   {
379     bool foundAllParams( false );
380     V8Utils::ReadIntegerArguments( foundAllParams, &params[0], 2, args, 0 );
381     if( foundAllParams )
382     {
383       actor.SetBlendEquation( static_cast<Dali::BlendingEquation::Type>( params[0] ), static_cast<Dali::BlendingEquation::Type>( params[1] ) );
384     }
385     else
386     {
387       DALI_SCRIPT_EXCEPTION( isolate, "invalid BlendEquation parameter" );
388       return;
389     }
390   }
391 }
392
393 /**
394  * @for RenderableActor
395  * @method getBlendEquation
396  * @return {Object} equationProperties
397  * @example equation properties object has 2 fields
398  *
399  *      equationProperties.equationRgb    // rbg blend equation
400  *      equationProperties.equationAlpha  // alpha blend equation
401  */
402 void RenderableActorApi::GetBlendEquation( const v8::FunctionCallbackInfo< v8::Value >& args )
403 {
404   v8::Isolate* isolate = args.GetIsolate();
405   v8::HandleScope handleScope( isolate );
406   RenderableActor actor = GetRenderableActor( isolate, args );
407
408   BlendingEquation::Type equationRgb, equationAlpha;
409   actor.GetBlendEquation( equationRgb, equationAlpha );
410
411   v8::Local<v8::Object> object = v8::Object::New( isolate );
412
413   object->Set( v8::String::NewFromUtf8( isolate, "equationRgb" ),   v8::Integer::New( isolate, equationRgb) );
414   object->Set( v8::String::NewFromUtf8( isolate, "equationAlpha" ), v8::Integer::New( isolate, equationAlpha ) );
415
416   args.GetReturnValue().Set( object );
417 }
418
419 /**
420  * @for RenderableActor
421  * @method setBlendColor
422  * @param {Vector4} Color
423  * @example
424  *
425  *        actor.SetBlendColor( dali.COLOR_RED );
426  */
427 void RenderableActorApi::SetBlendColor( const v8::FunctionCallbackInfo< v8::Value >& args )
428 {
429   v8::Isolate* isolate = args.GetIsolate();
430   v8::HandleScope handleScope( isolate );
431   RenderableActor actor = GetRenderableActor( isolate, args );
432
433   Dali::Vector4 color;
434
435   bool foundAllArguments( false );
436
437   V8Utils::ReadFloatArguments( foundAllArguments, color.AsFloat(), 4, args, 1.f ); // read the parameters
438   if( !foundAllArguments )
439   {
440     DALI_SCRIPT_EXCEPTION( isolate, "invalid color parameter, should red,green,blue,alpha" );
441     return;
442   }
443   actor.SetBlendColor( color );
444
445 }
446
447 /**
448  * @for RenderableActor
449  * @method getBlendColor
450  * @return {Object} Dali vector 4 object
451  */
452 void RenderableActorApi::GetBlendColor( const v8::FunctionCallbackInfo< v8::Value >& args )
453 {
454   v8::Isolate* isolate = args.GetIsolate();
455   v8::HandleScope handleScope( isolate );
456   RenderableActor actor = GetRenderableActor( isolate, args );
457
458   Dali::Vector4 color = actor.GetBlendColor();
459
460   Dali::Property::Value value( color );
461
462   v8::Local<v8::Object> object = PropertyValueWrapper::WrapDaliProperty( isolate, value );
463
464   args.GetReturnValue().Set( object );
465
466 }
467
468
469 /**
470  * @for RenderableActor
471  * @method getShaderEffect
472  * @return {Object} ShaderEffect object
473  *
474  * Retrieve the shader effect for the Actor.
475  *
476  * @example
477  *    var shaderEffect = actor.getShaderEffect();
478  *
479  */
480 void RenderableActorApi::GetShaderEffect( const v8::FunctionCallbackInfo<v8::Value>& args )
481 {
482   v8::Isolate* isolate = args.GetIsolate();
483   v8::HandleScope handleScope( isolate );
484   RenderableActor actor = GetRenderableActor( isolate, args );
485
486   v8::Local < v8::Object > object = ShaderEffectWrapper::WrapShaderEffect( isolate, actor.GetShaderEffect() );
487   args.GetReturnValue().Set( object );
488
489 }
490
491 /**
492  * @for RenderableActor
493  * @method setShaderEffect
494  * @param {Object} shaderEffect The shader effect.
495  *
496  * Sets the shader effect for the Actor.
497  *
498  * Shader effects provide special effects like rippling and bending.
499  * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
500  * @example
501  *      // first create the shaderOptions, then the shaderEffect
502  *      var shader = new dali.ShaderEffect( shaderOptions );
503  *      actor.setShaderEffect( shader );
504  *
505  */
506 void RenderableActorApi::SetShaderEffect( const v8::FunctionCallbackInfo<v8::Value>& args )
507 {
508   v8::Isolate* isolate = args.GetIsolate();
509   v8::HandleScope handleScope( isolate );
510   RenderableActor actor = GetRenderableActor( isolate, args );
511
512   bool found( false );
513   ShaderEffect effect = ShaderEffectApi::GetShaderEffectFromParams( 0, found, isolate, args );
514   if( found )
515   {
516     actor.SetShaderEffect( effect );
517   }
518   else
519   {
520     DALI_SCRIPT_EXCEPTION( isolate, "shader effect parameter missing" );
521   }
522 }
523
524 /**
525  *
526  * Removes the current shader effect
527  *
528  * @example
529  *    actor.removeShaderEffect();
530  *
531  * @for RenderableActor
532  * @method removeShaderEffect
533  */
534 void RenderableActorApi::RemoveShaderEffect( const v8::FunctionCallbackInfo<v8::Value>& args )
535 {
536   v8::Isolate* isolate = args.GetIsolate();
537   v8::HandleScope handleScope( isolate );
538   RenderableActor actor = GetRenderableActor( isolate, args );
539   actor.RemoveShaderEffect();
540 }
541
542
543
544 } // namespace V8Plugin
545
546 } // namespace Dali