Scripting: Json format changes; style sets, includes
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / builder-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali-toolkit/internal/builder/builder-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <sys/stat.h>
22
23 // INTERNAL INCLUDES
24 #include <dali/dali.h>
25 #include <dali/integration-api/debug.h>
26
27 #include <dali-toolkit/public-api/controls/control.h>
28 #include <dali-toolkit/public-api/builder/json-parser.h>
29
30 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
31 #include <dali-toolkit/internal/builder/builder-filesystem.h>
32 #include <dali-toolkit/internal/builder/builder-declarations.h>
33 #include <dali-toolkit/internal/builder/replacement.h>
34
35 namespace Dali
36 {
37
38 namespace Toolkit
39 {
40
41 namespace Internal
42 {
43 class Replacement;
44
45 extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot );
46 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
47 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
48 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
49 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
50 extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
51 extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor);
52 extern Actor SetupActor( const TreeNode& node, Actor& actor );
53 extern Control SetupControl( const TreeNode& node, Control& actor );
54
55 #if defined(DEBUG_ENABLED)
56 Integration::Log::Filter* gFilterScript  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_SCRIPT");
57 #endif
58
59 namespace
60 {
61
62 const std::string KEYNAME_STYLES    = "styles";
63 const std::string KEYNAME_TYPE      = "type";
64 const std::string KEYNAME_ACTORS    = "actors";
65 const std::string KEYNAME_SIGNALS   = "signals";
66 const std::string KEYNAME_NAME      = "name";
67 const std::string KEYNAME_TEMPLATES = "templates";
68 const std::string KEYNAME_INCLUDES  = "includes";
69
70 typedef std::vector<const TreeNode*> TreeNodeList;
71
72 template <typename T>
73 std::string ToString(const T& value)
74 {
75   std::stringstream ss;
76   ss << value;
77   return ss.str();
78 }
79
80 template <>
81 std::string ToString(const Rect<int>& value)
82 {
83   std::stringstream ss;
84   ss << value.x << "," << value.y << "," << value.width << "," << value.height;
85   return ss.str();
86 }
87
88
89 std::string PropertyValueToString( const Property::Value& value )
90 {
91   std::string ret;
92
93   switch( value.GetType() )
94   {
95     case Property::NONE:
96     {
97       ret = "NONE";
98       break;
99     }            ///< No type
100     case Property::BOOLEAN:
101     {
102       ret = value.Get<bool>() ? "True" : "False";
103       break;
104     }
105     case Property::FLOAT:
106     {
107
108       ret = ToString( value.Get<float>() );
109       break;
110     }
111     case Property::INTEGER:
112     {
113       ret = ToString( value.Get<int>() );
114       break;
115     }
116     case Property::UNSIGNED_INTEGER:
117     {
118       ret = ToString( value.Get<unsigned int>() );
119       break;
120     }
121     case Property::VECTOR2:
122     {
123       ret = ToString( value.Get<Vector2>() );
124       break;
125     }
126     case Property::VECTOR3:
127     {
128       ret = ToString( value.Get<Vector3>() );
129       break;
130     }
131     case Property::VECTOR4:
132     {
133       ret = ToString( value.Get<Vector4>() );
134       break;
135     }
136     case Property::MATRIX3:
137     {
138       ret = ToString( value.Get<Matrix3>() );
139       break;
140     }
141     case Property::MATRIX:
142     {
143       ret = ToString( value.Get<Matrix>() );
144       break;
145     }
146     case Property::RECTANGLE:
147     {
148       ret = ToString( value.Get< Rect<int> >() );
149       break;
150     }
151     case Property::ROTATION:
152     {
153       break;
154     }
155     case Property::STRING:
156     {
157       ret = value.Get<std::string>();
158       break;
159     }
160     case Property::ARRAY:
161     {
162       ret = std::string("Array Size=") + ToString( value.Get<Property::Array>().size() );
163       break;
164     }
165     case Property::MAP:
166     {
167       ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().size() );
168       break;
169     }
170     case Property::TYPE_COUNT:
171     {
172       ret = "";
173       break;
174     }
175   }
176
177   return ret;
178 }
179
180 /*
181  * Recursively collects all stylesin a node (An array of style names).
182  *
183  * stylesCollection The set of styles from the json file (a json object of named styles)
184  * style The style array to begin the collection from
185  * styleList The style list to add nodes to apply
186  */
187 void CollectAllStyles( const TreeNode& stylesCollection, const TreeNode& style, TreeNodeList& styleList )
188 {
189   // style is an array of style names
190   if( TreeNode::ARRAY == style.GetType() )
191   {
192     for(TreeNode::ConstIterator iter = style.CBegin(); iter != style.CEnd(); ++iter)
193     {
194       if( OptionalString styleName = IsString( (*iter).second ) )
195       {
196         if( OptionalChild node = IsChild( stylesCollection, *styleName) )
197         {
198           styleList.push_back( &(*node) );
199
200           if( OptionalChild subStyle = IsChild( *node, KEYNAME_STYLES ) )
201           {
202             CollectAllStyles( stylesCollection, *subStyle, styleList );
203           }
204         }
205       }
206     }
207   }
208 }
209
210 } // namespace anon
211
212 /*
213  * Sets the handle properties found in the tree node
214  */
215 void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replacement& constant )
216 {
217   if( handle )
218   {
219     for( TreeNode::ConstIterator iter = node.CBegin(); iter != node.CEnd(); ++iter )
220     {
221       const TreeNode::KeyNodePair& keyChild = *iter;
222
223       std::string key( keyChild.first );
224
225       // ignore special fields; type,actors,signals
226       if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES)
227       {
228         continue;
229       }
230
231       // special field 'image' usually contains an json object description
232       // although sometimes refers to a framebuffer
233       if( 0 == keyChild.second.Size() )
234       {
235         if(key == "image")
236         {
237           ImageActor imageActor = ImageActor::DownCast(handle);
238           if(imageActor)
239           {
240             if( OptionalString s = constant.IsString( keyChild.second ) )
241             {
242               FrameBufferImage fb = GetFrameBufferImage(*s, constant);
243               if(fb)
244               {
245                 imageActor.SetImage( fb );
246               }
247             }
248           }
249         }
250       }
251
252       // special field 'effect' references the shader effect instances
253       if(key == "effect")
254       {
255         Actor actor = Actor::DownCast(handle);
256         OptionalString s = constant.IsString( keyChild.second );
257         if(actor && s)
258         {
259           ShaderEffect e = GetShaderEffect(*s, constant);
260           actor.SetShaderEffect(e);
261         }
262         else
263         {
264           DALI_SCRIPT_WARNING("Could not find or set shader effect\n");
265         }
266
267         continue;
268       }
269
270       Property::Index index = handle.GetPropertyIndex(key);
271
272       if( Property::INVALID_INDEX != index )
273       {
274         Property::Type type = handle.GetPropertyType(index);
275
276         Property::Value value;
277         if( !SetPropertyFromNode( keyChild.second, type, value, constant ) )
278         {
279           // verbose as this might not be a problem
280           // eg parent-origin can be a string which is picked up later
281           DALI_SCRIPT_VERBOSE("Could not convert property:%s\n", key.c_str());
282         }
283         else
284         {
285           DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() );
286
287           handle.SetProperty( index, value );
288         }
289       }
290       else
291       {
292         DALI_SCRIPT_VERBOSE("SetProperty INVALID '%s' Index=:%d\n", key.c_str(), index);
293       }
294
295     } // for property nodes
296   }
297   else
298   {
299     DALI_SCRIPT_WARNING("Style applied to empty handle\n");
300   }
301 }
302
303 // Set properties from node on handle.
304 void Builder::ApplyProperties( const TreeNode& root, const TreeNode& node,
305                                Dali::Handle& handle, const Replacement& constant )
306 {
307   if( Actor actor = Actor::DownCast(handle) )
308   {
309     SetProperties( node, actor, constant );
310
311     if( actor )
312     {
313       SetupActor( node, actor );
314
315       Control control  = Control::DownCast(actor);
316
317       if( control )
318       {
319         SetupControl( node, control );
320       }
321
322       // add signals
323       SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor );
324
325       SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor );
326    }
327   }
328   else
329   {
330     SetProperties( node, handle, constant );
331   }
332 }
333
334 // Appling by style helper
335 // use FindChildByName() to apply properties referenced in KEYNAME_ACTORS in the node
336 void Builder::ApplyStylesByActor(  const TreeNode& root, const TreeNode& node,
337                                    Dali::Handle& handle, const Replacement& constant )
338 {
339   if( Dali::Actor actor = Dali::Actor::DownCast( handle ) )
340   {
341     if( const TreeNode* actors = node.GetChild( KEYNAME_ACTORS ) )
342     {
343       // in a style the actor subtree properties referenced by actor name
344       for( TreeConstIter iter = actors->CBegin(); iter != actors->CEnd(); ++iter )
345       {
346         Dali::Actor foundActor;
347
348         if( (*iter).first )
349         {
350           foundActor = actor.FindChildByName( (*iter).first );
351         }
352
353         if( !foundActor )
354         {
355           // debug log cannot find searched for actor
356 #if defined(DEBUG_ENABLED)
357           DALI_SCRIPT_VERBOSE("Cannot find actor in style application '%s'\n", (*iter).first);
358 #endif
359         }
360         else
361         {
362 #if defined(DEBUG_ENABLED)
363           DALI_SCRIPT_VERBOSE("Styles applied to actor '%s'\n", (*iter).first);
364 #endif
365           ApplyProperties( root, (*iter).second, foundActor, constant );
366         }
367       }
368     }
369   }
370 }
371
372
373 void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node,
374                                        Dali::Handle& handle, const Replacement& constant )
375 {
376   OptionalChild styles = IsChild(root, KEYNAME_STYLES);
377   OptionalChild style  = IsChild(node, KEYNAME_STYLES);
378
379   if( styles && style )
380   {
381     TreeNodeList additionalStyles;
382
383     CollectAllStyles( *styles, *style, additionalStyles );
384
385 #if defined(DEBUG_ENABLED)
386     for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter)
387     {
388       if( OptionalString styleName = IsString( (*iter).second ) )
389       {
390         DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str());
391       }
392     }
393 #endif
394
395     // a style may have other styles, which has other styles etc so we apply in reverse by convention.
396     for(TreeNodeList::reverse_iterator iter = additionalStyles.rbegin(); iter != additionalStyles.rend(); ++iter)
397     {
398       ApplyProperties( root, *(*iter), handle, constant );
399
400       ApplyStylesByActor( root, *(*iter), handle, constant );
401     }
402   }
403
404   // applying given node last
405   ApplyProperties( root, node, handle, constant );
406
407   ApplyStylesByActor( root, node, handle, constant );
408
409 }
410
411
412 /*
413  * Create a dali type from a node.
414  * If parent given and an actor type was created then add it to the parent and
415  * recursively add nodes children.
416  */
417 BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node,
418                               Actor parent, const Replacement& replacements )
419 {
420   BaseHandle baseHandle;
421   TypeInfo typeInfo;
422   const TreeNode* templateNode = NULL;
423
424   if( OptionalString typeName = IsString(node, KEYNAME_TYPE) )
425   {
426     typeInfo = TypeRegistry::Get().GetTypeInfo( *typeName );
427
428     if( !typeInfo )
429     {
430       // a template name is also allowed inplace of the type name
431       OptionalChild templates = IsChild( root, KEYNAME_TEMPLATES);
432
433       if( templates )
434       {
435         if( OptionalChild isTemplate = IsChild( *templates, *typeName ) )
436         {
437           templateNode = &(*isTemplate);
438
439           if( OptionalString templateTypeName = IsString(*templateNode, KEYNAME_TYPE) )
440           {
441             typeInfo = TypeRegistry::Get().GetTypeInfo( *templateTypeName );
442           }
443         }
444       }
445     }
446   }
447
448   if(!typeInfo)
449   {
450     DALI_SCRIPT_WARNING("Cannot create Dali type from node '%s'\n", node.GetName());
451   }
452   else
453   {
454     baseHandle       = typeInfo.CreateInstance();
455     Handle handle    = Handle::DownCast(baseHandle);
456     Actor actor      = Actor::DownCast(handle);
457     Control control  = Control::DownCast(handle);
458
459     if(handle)
460     {
461
462       DALI_SCRIPT_VERBOSE("Create:%s\n", typeInfo.GetName().c_str());
463
464 #if defined(DEBUG_ENABLED)
465       if(handle)
466       {
467         DALI_SCRIPT_VERBOSE("  Is Handle Object=%d\n", (long*)handle.GetObjectPtr());
468         DALI_SCRIPT_VERBOSE("  Is Handle Property Count=%d\n", handle.GetPropertyCount());
469       }
470
471       if(actor)
472       {
473         DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetId());
474       }
475
476       if(control)
477       {
478         DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetId());
479       }
480 #endif // DEBUG_ENABLED
481
482       if( templateNode )
483       {
484         ApplyProperties( root, *templateNode, handle, replacements );
485
486         if( OptionalChild actors = IsChild( *templateNode, KEYNAME_ACTORS ) )
487         {
488           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
489           {
490             DoCreate( root, (*iter).second, actor, replacements );
491           }
492         }
493       }
494
495       ApplyProperties( root, node, handle, replacements );
496
497       if( actor)
498       {
499         // add children of all the styles
500         if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) )
501         {
502           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
503           {
504             DoCreate( root, (*iter).second, actor, replacements );
505           }
506         }
507
508         // apply style on top as they need the children to exist
509         ApplyAllStyleProperties( root, node, actor, replacements );
510
511         // then add to parent
512         if( parent )
513         {
514           parent.Add( actor );
515         }
516       }
517
518     }
519     else
520     {
521       DALI_SCRIPT_WARNING("Cannot create handle from type '%s'\n", typeInfo.GetName().c_str());
522     }
523   }
524
525   return baseHandle;
526 }
527
528
529 ActorContainer Builder::GetTopLevelActors() const
530 {
531   // deprecated function.
532   return ActorContainer();
533 }
534
535 Animation Builder::GetAnimation( const std::string &name ) const
536 {
537   // deprecated
538   return Animation();
539 }
540
541 void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replacement& constant )
542 {
543   const Stage& stage = Stage::GetCurrent();
544   Layer root  = stage.GetRootLayer();
545
546   if( OptionalString s = constant.IsString( IsChild(node, "source-actor") ) )
547   {
548     Actor actor = root.FindChildByName(*s);
549     if(actor)
550     {
551       task.SetSourceActor( actor );
552     }
553     else
554     {
555       DALI_SCRIPT_WARNING("Cannot find source actor on stage for render task called '%s'\n", (*s).c_str() );
556     }
557   }
558
559   if( OptionalString s = constant.IsString( IsChild(node, "camera-actor") ) )
560   {
561     CameraActor actor = CameraActor::DownCast( root.FindChildByName(*s) );
562     if(actor)
563     {
564       task.SetCameraActor( actor );
565     }
566     else
567     {
568       DALI_SCRIPT_WARNING("Cannot find camera actor on stage for render task called '%s'\n", (*s).c_str() );
569     }
570   }
571
572   if( OptionalString s = constant.IsString( IsChild(node, "target-frame-buffer") ) )
573   {
574     FrameBufferImage fb = GetFrameBufferImage( *s, constant );
575     if(fb)
576     {
577       task.SetTargetFrameBuffer( fb );
578     }
579     else
580     {
581       DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
582     }
583   }
584
585   if( OptionalString s = constant.IsString( IsChild(node, "screen-to-frame-buffer-function") ) )
586   {
587     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
588     {
589       task.SetScreenToFrameBufferFunction( RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION );
590     }
591     else if("FULLSCREEN_FRAMEBUFFER_FUNCTION" == *s)
592     {
593       task.SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
594     }
595     else
596     {
597       DALI_SCRIPT_WARNING("todo");
598     }
599   }
600
601   // other setup is via the property system
602   SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'?
603
604 }
605
606 void Builder::CreateRenderTask( const std::string &name )
607 {
608   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
609
610   Replacement constant(mReplacementMap);
611
612   const Stage& stage = Stage::GetCurrent();
613
614   OptionalChild tasks = IsChild(*mParser.GetRoot(), "render-tasks");
615
616   if(tasks)
617   {
618     //
619     // Create the tasks from the current task as generally we want
620     // to setup task zero and onwards. Although this does overwrite
621     // the properties of the current task.
622     //
623     if( OptionalChild renderTask = IsChild(*tasks, name ) )
624     {
625       RenderTaskList list = stage.GetRenderTaskList();
626       unsigned int start = list.GetTaskCount();
627
628       RenderTask task;
629       if(0 == start)
630       {
631         // zero should have already been created by the stage so really
632         // this case should never happen
633         task = list.CreateTask();
634         start++;
635       }
636
637       TreeNode::ConstIterator iter = (*renderTask).CBegin();
638       task = list.GetTask( start - 1 );
639
640       SetupTask( task, (*iter).second, constant  );
641
642       ++iter;
643
644       for(; iter != (*renderTask).CEnd(); ++iter )
645       {
646         task = list.CreateTask();
647         SetupTask( task, (*iter).second, constant );
648       }
649     }
650   }
651 }
652
653 ShaderEffect Builder::GetShaderEffect( const std::string &name)
654 {
655   Replacement constant( mReplacementMap );
656   return GetShaderEffect( name, constant );
657 }
658
659 ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant )
660 {
661   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
662
663   ShaderEffect ret;
664
665   ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) );
666   if( iter != mShaderEffectLut.end() )
667   {
668     ret = iter->second;
669   }
670   else
671   {
672     if( OptionalChild effects = IsChild( *mParser.GetRoot(), "shader-effects") )
673     {
674       if( OptionalChild effect = IsChild( *effects, name ) )
675       {
676         Dali::Property::Value propertyMap(Property::MAP);
677         if( SetPropertyFromNode( *effect, Property::MAP, propertyMap, constant ) )
678         {
679           ret = Dali::Scripting::NewShaderEffect( propertyMap );
680           mShaderEffectLut[ name ] = ret;
681         }
682       }
683     }
684   }
685
686   return ret;
687 }
688
689 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
690 {
691   Replacement constant( mReplacementMap );
692   return GetFrameBufferImage(name, constant);
693 }
694
695 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
696 {
697   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
698
699   FrameBufferImage ret;
700
701   ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
702   if( iter != mFrameBufferImageLut.end() )
703   {
704     ret = iter->second;
705   }
706   else
707   {
708     if( OptionalChild images = IsChild( *mParser.GetRoot(), "frame-buffer-images") )
709     {
710       if( OptionalChild image = IsChild( *images, name ) )
711       {
712         Dali::Property::Value propertyMap(Property::MAP);
713         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
714         {
715           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
716           ret = Dali::Scripting::NewImage( propertyMap );
717           mFrameBufferImageLut[ name ] = ret;
718         }
719       }
720     }
721   }
722
723   return ret;
724 }
725
726 Font Builder::GetFont( const std::string& name ) const
727 {
728   // deprecated function.
729   Font font;
730   return font;
731 }
732
733 TextStyle Builder::GetTextStyle( const std::string& name ) const
734 {
735   // deprecated
736   return TextStyle();
737 }
738
739 Image Builder::GetImage( const std::string& name) const
740 {
741   // deprecated function.
742   return Image();
743 }
744
745 Actor Builder::GetActor( const std::string &name ) const
746 {
747   // deprecated function.
748   return Actor();
749 }
750
751 void Builder::AddActors( Actor toActor )
752 {
753   // 'stage' is the default/by convention section to add from
754   AddActors( "stage", toActor );
755 }
756
757 void Builder::AddActors( const std::string &sectionName, Actor toActor )
758 {
759   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
760
761   PropertyValueMap overrideMap;
762   Replacement replacements(overrideMap, mReplacementMap);
763
764   OptionalChild add = IsChild(*mParser.GetRoot(), sectionName);
765
766   if( add )
767   {
768     for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter )
769     {
770       // empty actor adds directly to the stage
771       BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements );
772       Actor actor = Actor::DownCast(baseHandle);
773       if(actor)
774       {
775         toActor.Add( actor );
776       }
777     }
778
779     // if were adding the 'stage' section then also check for a render task called stage
780     // to add automatically
781     if( "stage" == sectionName )
782     {
783       if( OptionalChild renderTasks = IsChild(*mParser.GetRoot(), "render-tasks") )
784       {
785         if( OptionalChild tasks = IsChild(*renderTasks, "stage") )
786         {
787           CreateRenderTask( "stage" );
788         }
789       }
790     }
791   }
792 }
793
794 Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor )
795 {
796   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
797
798   Animation anim;
799
800   if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") )
801   {
802     if( OptionalChild animation = IsChild(*animations, animationName) )
803     {
804       anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor );
805     }
806     else
807     {
808       DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed\n", animationName.c_str() );
809     }
810   }
811   else
812   {
813     DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed (no animation section)\n", animationName.c_str() );
814   }
815
816   return anim;
817 }
818
819 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map, Dali::Actor sourceActor )
820 {
821   Replacement replacement(map, mReplacementMap);
822   return CreateAnimation( animationName, replacement, sourceActor);
823 }
824
825 Animation Builder::CreateAnimation( const std::string& animationName, const PropertyValueMap& map )
826 {
827   Replacement replacement(map, mReplacementMap);
828   return CreateAnimation( animationName, replacement, Stage::GetCurrent().GetRootLayer() );
829 }
830
831 Animation Builder::CreateAnimation( const std::string& animationName, Dali::Actor sourceActor )
832 {
833   Replacement replacement( mReplacementMap );
834
835   return CreateAnimation( animationName, replacement, sourceActor );
836 }
837
838 Animation Builder::CreateAnimation( const std::string& animationName )
839 {
840   Replacement replacement( mReplacementMap );
841
842   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
843 }
844
845 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
846 {
847   DALI_ASSERT_ALWAYS( format == Dali::Toolkit::Builder::JSON && "Currently only JSON is supported" );
848
849   // parser to get constants and includes only
850   Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New();
851
852   if( !parser.Parse( data ) )
853   {
854     DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
855                       parser.GetErrorLineNumber(),
856                       parser.GetErrorColumn(),
857                       parser.GetErrorDescription().c_str() );
858
859     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
860
861   }
862   else
863   {
864     // load constant map (allows the user to override the constants in the json after loading)
865     LoadConstants( *parser.GetRoot(), mReplacementMap );
866
867     // merge includes
868     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
869     {
870       Replacement replacer( mReplacementMap );
871
872       for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter)
873       {
874         OptionalString filename = replacer.IsString( (*iter).second );
875
876         if( filename )
877         {
878 #if defined(DEBUG_ENABLED)
879           DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str());
880 #endif
881           LoadFromString( GetFileContents(*filename) );
882         }
883       }
884     }
885
886     if( !mParser.Parse( data ) )
887     {
888       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
889                         mParser.GetErrorLineNumber(),
890                         mParser.GetErrorColumn(),
891                         mParser.GetErrorDescription().c_str() );
892
893       DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
894     }
895   }
896
897   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
898
899 }
900
901 void Builder::AddConstants( const PropertyValueMap& map )
902 {
903   for(PropertyValueMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
904   {
905     mReplacementMap[ (*iter).first ] = (*iter).second;
906   }
907 }
908
909 void Builder::AddConstant( const std::string& key, const Property::Value& value )
910 {
911   mReplacementMap[key] = value;
912 }
913
914 const PropertyValueMap& Builder::GetConstants() const
915 {
916   return mReplacementMap;
917 }
918
919 const Property::Value& Builder::GetConstant( const std::string& key ) const
920 {
921   PropertyValueMap::const_iterator iter = mReplacementMap.find( key );
922   if( iter  != mReplacementMap.end() )
923   {
924     return (*iter).second;
925   }
926   else
927   {
928     static Property::Value invalid;
929     return invalid;
930   }
931 }
932
933 void Builder::LoadConstants( const TreeNode& root, PropertyValueMap& intoMap )
934 {
935   Replacement replacer(intoMap);
936
937   if( OptionalChild constants = IsChild(root, "constants") )
938   {
939     for(TreeNode::ConstIterator iter = (*constants).CBegin();
940         iter != (*constants).CEnd(); ++iter)
941     {
942       Dali::Property::Value property;
943       if( (*iter).second.GetName() )
944       {
945 #if defined(DEBUG_ENABLED)
946         DALI_SCRIPT_VERBOSE("Constant set from json '%s'\n", (*iter).second.GetName());
947 #endif
948         if( SetPropertyFromNode( (*iter).second, property, replacer ) )
949         {
950           intoMap[ (*iter).second.GetName() ] = property;
951         }
952         else
953         {
954           DALI_SCRIPT_WARNING("Cannot convert property for constant %s\n",
955                               (*iter).second.GetName() == NULL ? "no name?" : (*iter).second.GetName());
956         }
957       }
958     }
959   }
960
961 #if defined(DEBUG_ENABLED)
962   PropertyValueMap::const_iterator iter = intoMap.find( "CONFIG_SCRIPT_LOG_LEVEL" );
963   if( iter != intoMap.end() && (*iter).second.GetType() == Property::STRING )
964   {
965     std::string logLevel( (*iter).second.Get< std::string >() );
966     if( logLevel == "NoLogging" )
967     {
968       gFilterScript->SetLogLevel( Integration::Log::NoLogging );
969     }
970     else if( logLevel == "Concise" )
971     {
972       gFilterScript->SetLogLevel( Integration::Log::Concise );
973     }
974     else if( logLevel == "General" )
975     {
976       gFilterScript->SetLogLevel( Integration::Log::General );
977     }
978     else if( logLevel == "Verbose" )
979     {
980       gFilterScript->SetLogLevel( Integration::Log::Verbose );
981     }
982   }
983 #endif
984
985 }
986
987 void Builder::ApplyStyle( const std::string& styleName, Handle& handle )
988 {
989   Replacement replacer( mReplacementMap );
990   ApplyStyle( styleName, handle, replacer );
991 }
992
993 void Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement )
994 {
995   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
996
997   OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES );
998   OptionalChild style  = IsChild( *styles, styleName );
999
1000   if( styles && style )
1001   {
1002     ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement );
1003   }
1004   else
1005   {
1006     DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str());
1007   }
1008
1009 }
1010
1011 BaseHandle Builder::Create( const std::string& templateName, const PropertyValueMap& map )
1012 {
1013   Replacement replacement( map, mReplacementMap );
1014   return Create( templateName, replacement );
1015 }
1016
1017 BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant )
1018 {
1019   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1020
1021   BaseHandle baseHandle;
1022
1023   OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES);
1024
1025   if( !templates )
1026   {
1027     DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n");
1028   }
1029   else
1030   {
1031     OptionalChild childTemplate = IsChild(*templates, templateName);
1032     if(!childTemplate)
1033     {
1034       DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str());
1035     }
1036     else
1037     {
1038       OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) );
1039
1040       if(!type)
1041       {
1042         DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str());
1043       }
1044       else
1045       {
1046         baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant );
1047       }
1048     }
1049   }
1050
1051   return baseHandle;
1052 }
1053
1054
1055 BaseHandle Builder::Create( const std::string& templateName )
1056 {
1057   Replacement replacement( mReplacementMap );
1058   return Create( templateName, replacement );
1059 }
1060
1061 Builder::Builder()
1062 : mSlotDelegate( this )
1063 {
1064   mParser = Dali::Toolkit::JsonParser::New();
1065 }
1066
1067 Builder::~Builder()
1068 {
1069 }
1070
1071 } // namespace Internal
1072
1073 } // namespace Toolkit
1074
1075 } // namespace Dali