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