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