049b3cec2a452a41efd14a8dd9e4bdfcb50a1d42
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / builder-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_BUILDER_H
2 #define DALI_TOOLKIT_INTERNAL_BUILDER_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <string>
23 #include <list>
24 #include <map>
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/actors/actor.h>
27 #include <dali/public-api/object/base-object.h>
28 #include <dali/public-api/object/property-map.h>
29 #include <dali/public-api/render-tasks/render-task.h>
30 #include <dali/integration-api/debug.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/devel-api/builder/json-parser.h>
34 #include <dali-toolkit/devel-api/builder/builder.h>
35 #include <dali-toolkit/internal/builder/builder-declarations.h>
36 #include <dali-toolkit/internal/builder/style.h>
37
38 // Warning messages usually displayed
39 #define DALI_SCRIPT_WARNING(format, ...) \
40   DALI_LOG_WARNING("Script:" format, ## __VA_ARGS__)
41
42 // Info messages are usually debug build
43 #define DALI_SCRIPT_INFO(format, ...) \
44   DALI_LOG_INFO(Dali::Toolkit::Internal::gFilterScript, Debug::General, "Script:" format, ## __VA_ARGS__)
45
46 // Info Verbose need to be swiched on in gFilterScript filter constructor (by default set to General)
47 #define DALI_SCRIPT_VERBOSE(format, ...) \
48   DALI_LOG_INFO(Dali::Toolkit::Internal::gFilterScript, Debug::Verbose, "Script:" format, ## __VA_ARGS__)
49
50 namespace Dali
51 {
52
53 namespace Toolkit
54 {
55   class TreeNode;
56 }
57
58 namespace Toolkit
59 {
60
61 namespace Internal
62 {
63
64 #if defined(DEBUG_ENABLED)
65 extern Dali::Integration::Log::Filter* gFilterScript;
66 #endif
67
68 class Builder;
69 class Replacement;
70
71 /**
72  * @copydoc Toolkit::Builder
73  */
74 class Builder : public Dali::BaseObject
75 {
76 public:
77
78   Builder();
79
80   /**
81    * @copydoc Toolkit::Builder::LoadFromString
82    */
83   void LoadFromString( const std::string &data,
84                        Dali::Toolkit::Builder::UIFormat rep = Dali::Toolkit::Builder::JSON );
85
86   /**
87    * @copydoc Toolkit::Builder::AddConstants
88    */
89   void AddConstants( const Property::Map& map );
90
91   /**
92    * @copydoc Toolkit::Builder::AddConstant
93    */
94   void AddConstant( const std::string& key, const Property::Value& value );
95
96   /**
97    * @copydoc Toolkit::Builder::GetConfigurations
98    */
99   const Property::Map& GetConfigurations() const;
100
101   /**
102    * @copydoc Toolkit::Builder::GetConstants
103    */
104   const Property::Map& GetConstants() const;
105
106   /**
107    * @copydoc Toolkit::Builder::GetConstant
108    */
109   const Property::Value& GetConstant( const std::string& key ) const;
110
111   /**
112    * @copydoc Toolkit::Builder::CreateAnimation( const std::string& animationName );
113    */
114   Animation CreateAnimation( const std::string& animationName );
115
116   /**
117    * @copydoc Toolkit::Builder::CreateAnimation( const std::string& animationName, const Property::Map& map );
118    */
119   Animation CreateAnimation( const std::string& animationName, const Property::Map& map );
120
121   /**
122    * @copydoc Toolkit::Builder::CreateAnimation( const std::string&,Dali::Actor);
123    */
124   Animation CreateAnimation( const std::string& animationName, Dali::Actor sourceActor );
125
126   /**
127    * @copydoc Toolkit::Builder::CreateAnimation( const std::string&,const Property::Map&, Dali::Actor);
128    */
129   Animation CreateAnimation( const std::string& animationName, const Property::Map& map, Dali::Actor sourceActor );
130
131   /**
132    * @copydoc Toolkit::Builder::Create( const std::string& templateName );
133    */
134   BaseHandle Create( const std::string& templateName );
135
136   /**
137    * @copydoc Toolkit::Builder::Create( const std::string& templateName, const Property::Map& map );
138    */
139   BaseHandle Create( const std::string& templateName, const Property::Map& map );
140
141   /**
142    * @copydoc Toolkit::Builder::CreateFromJson( const std::string& json );
143    */
144   BaseHandle CreateFromJson( const std::string& json );
145
146   /**
147    * @copydoc Toolkit::Builder::ApplyFromJson( Handle& handle, const std::string& json );
148    */
149   bool ApplyFromJson(  Handle& handle, const std::string& json );
150
151   /**
152    * @copydoc Toolkit::Builder::ApplyStyle
153    */
154   bool ApplyStyle( const std::string& styleName, Handle& handle );
155
156   /**
157    * Lookup the stylename in builder. If it's found in the parse tree,
158    * then return true.
159    * @param[in] styleName The style name to search for
160    * @return true if the stylename exists
161    */
162   bool LookupStyleName( const std::string& styleName );
163
164   /**
165    * Lookup the stylename in the recorded Styles - if it exists,
166    * performs a shallow copy to the passed in style and returns true.
167    * Otherwise it returns false.
168
169    * @param[in] styleName The stylename to search for
170    * @return A const pointer to the style object
171    */
172   const StylePtr GetStyle( const std::string& styleName );
173
174   /**
175    * @copydoc Toolkit::Builder::AddActors
176    */
177   void AddActors( Actor toActor );
178
179   /**
180    * @copydoc Toolkit::Builder::AddActors
181    */
182   void AddActors( const std::string &sectionName, Actor toActor );
183
184   /**
185    * @copydoc Toolkit::Builder::CreateRenderTask
186    */
187   void CreateRenderTask( const std::string &name );
188
189   /**
190    * @copydoc Toolkit::Builder::GetPath
191    */
192   Path GetPath( const std::string &name );
193
194   /**
195    * @copydoc Toolkit::Builder::GetPathConstrainer
196    */
197   Dali::PathConstrainer GetPathConstrainer( const std::string& name );
198
199   /*
200    * Check if a given constrainer is of type PathConstrainer
201    * @param[in] name The name of the constrainer
202    * @return True if constainer is of type PathConstrainer, False otherwise
203    *
204    */
205   bool IsPathConstrainer( const std::string& name );
206
207   /**
208    * @copydoc Toolkit::Builder::GetLinearConstrainer
209    */
210   Dali::LinearConstrainer GetLinearConstrainer( const std::string& name );
211
212   /*
213    * Check if a given constrainer is of type LinearConstrainer
214    * @param[in] name The name of the constrainer
215    * @return True if constainer is of type LinearConstrainer, False otherwise
216    *
217    */
218   bool IsLinearConstrainer( const std::string& name );
219
220   /**
221    * @copydoc Toolkit::Builder::QuitSignal
222    */
223   Toolkit::Builder::BuilderSignalType& QuitSignal();
224
225   /**
226    * Emits the quit signal
227    */
228   void EmitQuitSignal();
229
230
231 protected:
232
233   ~Builder() override;
234
235 private:
236   typedef std::vector<const char*> KeyStack;
237   typedef std::vector< TreeNode::KeyNodePair > MappingsLut;
238   typedef struct{ std::string name; Dali::LinearConstrainer linearConstrainer; } LinearConstrainerEntry;
239   typedef std::vector<LinearConstrainerEntry> LinearConstrainerLut;
240   typedef struct{ std::string name; Dali::PathConstrainer pathConstrainer; } PathConstrainerEntry;
241   typedef std::vector<PathConstrainerEntry> PathConstrainerLut;
242   typedef std::map<const std::string, Path> PathLut;
243
244 private:
245   // Undefined
246   Builder(const Builder&);
247
248   // Undefined
249   Builder& operator=(const Builder& rhs);
250
251   void LoadConstants( const TreeNode& root, Property::Map& intoMap );
252
253   void LoadConfiguration( const TreeNode& root, Property::Map& intoMap );
254
255   Animation CreateAnimation( const std::string& animationName,
256                              const Replacement& replacement,
257                              Dali::Actor        sourceActor );
258
259   BaseHandle Create( const std::string& templateName,
260                      const Replacement& constant );
261
262   BaseHandle DoCreate( const TreeNode&    root,
263                        const TreeNode&    node,
264                        Actor              parent,
265                        const Replacement& replacements );
266
267   void SetupTask( RenderTask&              task,
268                   const Toolkit::TreeNode& node,
269                   const Replacement&       replacement );
270
271   bool ApplyStyle( const std::string& styleName,
272                    Handle&            handle,
273                    const Replacement& replacement);
274
275   void ApplyAllStyleProperties( const TreeNode&    root,
276                                 const TreeNode&    node,
277                                 Dali::Handle&      handle,
278                                 const Replacement& constant );
279
280   void RecordStyles( const char*        styleName,
281                      const TreeNode&    node,
282                      Dali::Handle&      handle,
283                      const Replacement& replacements );
284
285   void RecordStyle( StylePtr           style,
286                     const TreeNode&    node,
287                     Dali::Handle&      handle,
288                     const Replacement& replacements );
289
290   void RecordTransitions( const TreeNode::KeyNodePair& keyValue,
291                           Property::Array& transitions,
292                           const Replacement& replacements );
293
294   void RecordTransitionData( const TreeNode::KeyNodePair& keyNode,
295                              Toolkit::TransitionData& transitionData,
296                              const Replacement& replacements );
297
298   void ApplyProperties( const TreeNode&    root,
299                         const TreeNode&    node,
300                         Dali::Handle&      handle,
301                         const Replacement& constant );
302
303   void ApplySignals( const TreeNode& root,
304                      const TreeNode& node,
305                      Dali::Handle& handle );
306
307   void ApplyStylesByActor( const TreeNode&    root,
308                            const TreeNode&    node,
309                            Dali::Handle&      handle,
310                            const Replacement& constant );
311
312   void SetProperties( const TreeNode&    node,
313                       Handle&            handle,
314                       const Replacement& constant );
315
316   bool MapToTargetProperty( Handle&            propertyObject,
317                             const std::string& key,
318                             const TreeNode&    node,
319                             const Replacement& constant,
320                             Property::Index&   index,
321                             Property::Value&   value );
322
323   /**
324    * Find the key in the mapping table, if it's present, then generate
325    * a property value for it (of the given type if available),
326    * recursing as necessary, and stopping if any cycles are detected.
327    *
328    * @param[in] mappingRoot The JSON node containing the mappings
329    * @param[in] theKey The key to search for
330    * @param[in] propertyType The property type if known, or NONE
331    * @param[in,out] value The string value to test and write back to.
332    */
333   bool GetPropertyMap( const TreeNode&  mappingRoot,
334                        const char*      theKey,
335                        Property::Type   propertyType,
336                        Property::Value& value );
337
338   void SetCustomProperties( const TreeNode&      node,
339                             Handle&              handle,
340                             const Replacement&   constant,
341                             const std::string&   childName,
342                             Property::AccessMode accessMode );
343
344   /**
345    * Find the key in the mapping table, if it's present, then generate
346    * a property value for it (of the given type if available),
347    * recursing as necessary, and stopping if any cycles are detected.
348    *
349    * @param[in] mappingRoot The JSON node containing the mappings
350    * @param[in] theKey The key to search for
351    * @param[in,out] keyStack the stack of visited keys
352    * @param[in] propertyType The property type if known, or NONE
353    * @param[in,out] value The string value to test and write back to.
354    */
355   bool RecursePropertyMap( const TreeNode&  mappingRoot,
356                            KeyStack&        keyStack,
357                            const char*      theKey,
358                            Property::Type   propertyType,
359                            Property::Value& value );
360
361
362   /**
363    * Tests if the value is a string delimited by <>. If it is, then it attempts to
364    * change the value to the mapping from a matching key in the mappings table.
365    * @param[in] mappingRoot The JSON node containing the mappings
366    * @param[in,out] keyStack the stack of visited keys
367    * @param[in,out] value The string value to test and write back to.
368    * @return true if the value was converted, false otherwise.
369    */
370   bool ConvertChildValue( const TreeNode& mappingRoot,
371                           KeyStack& keyStack,
372                           Property::Value& value );
373
374 private:
375   Toolkit::JsonParser                 mParser;
376   PathLut                             mPathLut;
377   PathConstrainerLut                  mPathConstrainerLut;
378   LinearConstrainerLut                mLinearConstrainerLut;
379   SlotDelegate<Builder>               mSlotDelegate;
380   Property::Map                       mReplacementMap;
381   Property::Map                       mConfigurationMap;
382   MappingsLut                         mCompleteMappings;
383   Dictionary<StylePtr>                mStyles; // State based styles
384   Toolkit::Builder::BuilderSignalType mQuitSignal;
385 };
386
387 } // namespace Internal
388
389 inline Internal::Builder& GetImpl(Dali::Toolkit::Builder& obj)
390 {
391   DALI_ASSERT_ALWAYS(obj);
392
393   Dali::BaseObject& handle = obj.GetBaseObject();
394
395   return static_cast<Internal::Builder&>(handle);
396 }
397
398 inline const Internal::Builder& GetImpl(const Dali::Toolkit::Builder& obj)
399 {
400   DALI_ASSERT_ALWAYS(obj);
401
402   const Dali::BaseObject& handle = obj.GetBaseObject();
403
404   return static_cast<const Internal::Builder&>(handle);
405 }
406
407 } // namespace Toolkit
408
409 } // namespace Dali
410
411 #endif // DALI_TOOLKIT_INTERNAL_BUILDER_H