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