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