Merge "Remove JavaScript binding for NativeImage, NinePatchImage, ImageActor and...
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / toolkit / builder / builder-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 "builder-api.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <string>
24 #include <fstream>
25 #include <streambuf>
26
27 // INTERNAL INCLUDES
28 #include <v8-utils.h>
29 #include <object/property-value-wrapper.h>
30 #include <object/handle-wrapper.h>
31 #include <toolkit/builder/builder-wrapper.h>
32 #include <actors/actor-wrapper.h>
33 #include <image/image-wrapper.h>
34 #include <animation/animation-wrapper.h>
35 #include <rendering/shader-wrapper.h>
36
37
38 namespace Dali
39 {
40
41 namespace V8Plugin
42 {
43
44 namespace // un named namespace
45 {
46
47
48 Dali::Toolkit::Builder GetBuilder( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
49 {
50   v8::HandleScope handleScope( isolate );
51
52   v8::Local<v8::Object> object = args.This();
53   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
54   void* ptr = field->Value();
55
56   BuilderWrapper* wrapper = static_cast<BuilderWrapper *>( ptr );
57   return wrapper->GetBuilder();
58 }
59
60
61 void GetMapAndString( v8::Isolate* isolate,
62                       std::string stringKey,
63                       std::string& stringValue,
64                       std::string mapKey,
65                       Dali::Property::Map& map,
66                       v8::Local<v8::Object> object)
67 {
68     v8::Local<v8::Value> stringNameValue = object->Get( v8::String::NewFromUtf8( isolate, stringKey.c_str() ) );
69     if( !stringNameValue->IsString() )
70     {
71       std::string message = "missing field :"+stringKey;
72       DALI_SCRIPT_EXCEPTION( isolate,  message);
73       return;
74     }
75     stringValue = V8Utils::v8StringToStdString( stringNameValue );
76
77     // constants is optional
78
79     v8::Local<v8::Value> constants = object->Get( v8::String::NewFromUtf8( isolate, mapKey.c_str() ) );
80     if( constants->IsObject() )
81     {
82       map = V8Utils::GetPropertyMapFromObject( isolate, constants->ToObject() );
83     }
84 }
85
86
87 } // un-named namespace
88
89
90 Dali::Toolkit::Builder BuilderApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
91 {
92   v8::Isolate* isolate = args.GetIsolate();
93   v8::HandleScope handleScope( isolate );
94
95   return Dali::Toolkit::Builder::New();
96 }
97
98 void BuilderApi::LoadFromString( const v8::FunctionCallbackInfo< v8::Value >& args )
99 {
100   v8::Isolate* isolate = args.GetIsolate();
101   v8::HandleScope handleScope( isolate );
102
103   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
104
105   bool found(false);
106   std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
107   if( found )
108   {
109     builder.LoadFromString( str );
110   }
111   else
112   {
113     DALI_SCRIPT_EXCEPTION( isolate,  "missing string parameter");
114   }
115 }
116
117 void BuilderApi::LoadFromFile( const v8::FunctionCallbackInfo< v8::Value >& args )
118 {
119   v8::Isolate* isolate = args.GetIsolate();
120   v8::HandleScope handleScope( isolate );
121
122   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
123
124   bool found(false);
125   std::string fileName= V8Utils::GetStringParameter( 0, found, isolate, args );
126   if( !found )
127   {
128     DALI_SCRIPT_EXCEPTION( isolate,  "missing string parameter");
129     return;
130   }
131
132   std::ifstream fileStream( fileName.c_str() );
133   if( !fileStream.is_open() )
134   {
135     std::string message = "failed to open JSON file" + fileName;
136     DALI_SCRIPT_EXCEPTION( isolate,  message );
137     return;
138   }
139
140   //single-pass input iterator that reads successive characters from the input stream
141   std::string json = std::string( (std::istreambuf_iterator< char >( fileStream )), std::istreambuf_iterator< char >() );
142
143   builder.LoadFromString( json );
144
145 }
146
147 void BuilderApi::AddConstants( const v8::FunctionCallbackInfo< v8::Value >& args )
148 {
149   v8::Isolate* isolate = args.GetIsolate();
150   v8::HandleScope handleScope( isolate );
151
152   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
153
154   bool found(false);
155   Dali::Property::Map map = V8Utils::GetPropertyMapParameter( 0,found, isolate, args );
156
157   if( found )
158   {
159     builder.AddConstants( map );
160   }
161   else
162   {
163     DALI_SCRIPT_EXCEPTION( isolate,  "no constants found" );
164   }
165
166 }
167
168 void BuilderApi::GetConstants( const v8::FunctionCallbackInfo< v8::Value >& args )
169 {
170   v8::Isolate* isolate = args.GetIsolate();
171   v8::HandleScope handleScope( isolate );
172
173   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
174
175   const Dali::Property::Map& map  = builder.GetConstants();
176
177   v8::Local<v8::Object> object = v8::Object::New( isolate );
178
179   V8Utils::CreatePropertyMap( isolate, map, object );
180
181   args.GetReturnValue().Set( object );
182
183 }
184 void BuilderApi::CreateAnimation( const v8::FunctionCallbackInfo< v8::Value >& args )
185 {
186   v8::Isolate* isolate = args.GetIsolate();
187   v8::HandleScope handleScope( isolate );
188
189   // options =
190   // {
191   //    animation: ..
192   //    constants:
193   //    actor:
194   // }
195   //
196
197   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
198
199   if( !args[0]->IsObject() )
200   {
201     DALI_SCRIPT_EXCEPTION( isolate,  "invalid property map, expecting { animation: x, constants: y, actor: z}" );
202     return;
203   }
204   v8::Local<v8::Object> object = args[0]->ToObject();
205
206   std::string animationName;
207   Dali::Property::Map map;
208
209   //  get the animation name and constant map
210
211   GetMapAndString( isolate,
212                    "animation",
213                    animationName,
214                    "constants",
215                    map,
216                    object );
217
218   // actor is optional
219   Actor actor;
220   v8::Local<v8::Value> actorValue = object->Get( v8::String::NewFromUtf8( isolate, "actor" ) );
221   if( actorValue->IsObject() )
222   {
223     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, actorValue->ToObject() );
224     if( handleWrapper )
225     {
226       actor = Actor::DownCast( handleWrapper->mHandle );
227     }
228   }
229   Animation anim;
230   if( actor )
231   {
232     //  Animation CreateAnimation( const std::string& animationName, const Dali::Property::Map& map, Dali::Actor sourceActor );
233     anim = builder.CreateAnimation( animationName, map, actor );
234   }
235   else
236   {
237     anim = builder.CreateAnimation( animationName, map);
238   }
239   v8::Local<v8::Object> localObject = AnimationWrapper::WrapAnimation( isolate, anim );
240   args.GetReturnValue().Set( localObject );
241 }
242
243 void BuilderApi::Create( const v8::FunctionCallbackInfo< v8::Value >& args )
244 {
245   v8::Isolate* isolate = args.GetIsolate();
246   v8::HandleScope handleScope( isolate );
247
248   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
249
250   if( !args[0]->IsObject() )
251   {
252     DALI_SCRIPT_EXCEPTION( isolate,  "invalid param");
253     return;
254   }
255   v8::Local<v8::Object> object = args[0]->ToObject();
256
257   // options =
258   // {
259   //    template: "myTemplate",
260   //    constants: {  IMAGE_DIR: "/usr/apps" ,  SHADER_DIR: "/usr/apps/.."}
261   // }
262   //
263   std::string templateName;
264   Dali::Property::Map map;
265
266   GetMapAndString( isolate,
267                    "template",
268                    templateName,
269                    "constants",
270                    map,
271                    object );
272
273   BaseHandle handle = builder.Create( templateName, map );
274   std::string typeName = handle.GetTypeName();
275   ActorWrapper::ActorType actorType = ActorWrapper::GetActorType( typeName );
276
277   if( actorType != ActorWrapper::UNKNOWN_ACTOR )
278   {
279     v8::Local<v8::Object> actorObject =  ActorWrapper::WrapActor(isolate, Actor::DownCast(handle),actorType);
280     args.GetReturnValue().Set( actorObject );
281     return;
282   }
283
284   if( typeName == "Animation")
285   {
286     v8::Local<v8::Object> animation = AnimationWrapper::WrapAnimation(isolate, Animation::DownCast(handle) );
287     args.GetReturnValue().Set( animation );
288   }
289
290   if( typeName == "Image")
291   {
292     v8::Local<v8::Object> image = ImageWrapper::WrapImage(isolate, Image::DownCast(handle) );
293     args.GetReturnValue().Set( image );
294   }
295   if( typeName == "Shader")
296   {
297     v8::Local<v8::Object> shader = ShaderWrapper::WrapShader(isolate, Shader::DownCast( handle ));
298     args.GetReturnValue().Set( shader );
299   }
300 }
301 void BuilderApi::ApplyStyle( const v8::FunctionCallbackInfo< v8::Value >& args )
302 {
303   v8::Isolate* isolate = args.GetIsolate();
304   v8::HandleScope handleScope( isolate );
305   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
306
307   // bool ApplyStyle( const std::string& styleName, Handle& handle );
308
309   bool found(false);
310   std::string styleName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args);
311   if( !found )
312   {
313     DALI_SCRIPT_EXCEPTION( isolate,  "missing style name" );
314     return;
315   }
316
317   Dali::Handle handle = V8Utils::GetHandleParameter( PARAMETER_1, found, isolate, args  );
318   if( !found )
319   {
320     DALI_SCRIPT_EXCEPTION( isolate,  "missing handle parameter" );
321     return;
322   }
323
324   builder.ApplyStyle( styleName, handle );
325
326 }
327
328 void BuilderApi::ApplyFromJson( const v8::FunctionCallbackInfo< v8::Value >& args )
329 {
330   v8::Isolate* isolate = args.GetIsolate();
331   v8::HandleScope handleScope( isolate );
332   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
333
334   bool found;
335
336   Dali::Handle handle = V8Utils::GetHandleParameter( PARAMETER_0, found, isolate, args  );
337   if( !found )
338   {
339     DALI_SCRIPT_EXCEPTION( isolate,  "missing handle parameter" );
340     return;
341   }
342   std::string jsonString = V8Utils::GetStringParameter( PARAMETER_1, found, isolate, args);
343   if( !found )
344   {
345     DALI_SCRIPT_EXCEPTION( isolate,  "missing JSON string" );
346     return;
347   }
348   builder.ApplyFromJson( handle, jsonString );
349 }
350
351 void BuilderApi::AddActors( const v8::FunctionCallbackInfo< v8::Value >& args )
352 {
353   v8::Isolate* isolate = args.GetIsolate();
354   v8::HandleScope handleScope( isolate );
355   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
356
357   //{
358   //  actor:actor
359   //  section: name
360   //}
361
362   Actor actor;
363
364   if( !args[0]->IsObject() )
365   {
366     DALI_SCRIPT_EXCEPTION( isolate,  "invalid param");
367     return;
368   }
369   v8::Local<v8::Object> object = args[0]->ToObject();
370
371   v8::Local<v8::Value> actorValue = object->Get( v8::String::NewFromUtf8( isolate, "actor" ) );
372   if( actorValue->IsObject() )
373   {
374     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, actorValue->ToObject() );
375     if( handleWrapper )
376     {
377       actor = Actor::DownCast( handleWrapper->mHandle );
378     }
379   }
380   else
381   {
382     DALI_SCRIPT_EXCEPTION( isolate,  "actor field not found in param");
383     return;
384   }
385
386   v8::Local<v8::Value> stringNameValue = object->Get( v8::String::NewFromUtf8( isolate, "section" ) );
387   if( !stringNameValue->IsString() )
388   {
389     std::string message = "missing field: section";
390     DALI_SCRIPT_EXCEPTION( isolate,  message);
391     return;
392   }
393   std::string sectionName = V8Utils::v8StringToStdString( stringNameValue );
394   if( !sectionName.empty() )
395   {
396     builder.AddActors( sectionName, actor );
397   }
398   else
399   {
400     builder.AddActors(  actor );
401   }
402
403 }
404
405 void BuilderApi::CreateRenderTask( const v8::FunctionCallbackInfo< v8::Value >& args )
406 {
407   v8::Isolate* isolate = args.GetIsolate();
408   v8::HandleScope handleScope( isolate );
409   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
410   bool found(false);
411   std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
412
413   if( found )
414   {
415     builder.CreateRenderTask( str );
416   }
417   else
418   {
419      DALI_SCRIPT_EXCEPTION( isolate, "render task name");
420   }
421 }
422
423 void BuilderApi::GetFrameBufferImage( const v8::FunctionCallbackInfo< v8::Value >& args )
424 {
425   v8::Isolate* isolate = args.GetIsolate();
426    v8::HandleScope handleScope( isolate );
427    Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
428
429    bool found(false);
430    std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
431    if( found )
432    {
433      // wrap the image
434      // @TODO Test this, may need to implement a Framebuffer image wrapper.?
435      v8::Local<v8::Object> localObject = ImageWrapper::WrapImage( isolate, builder.GetFrameBufferImage(str)  );
436      args.GetReturnValue().Set( localObject );
437    }
438    else
439    {
440      DALI_SCRIPT_EXCEPTION( isolate,  "frame buffer name");
441    }
442
443 }
444
445 } // namespace V8Plugin
446
447 } // namespace Dali