Merge "Add deviceName to GetNextFocusableView() in CustomFocusAlgorithm." into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-factory-impl.cpp
1 /*
2  * Copyright (c) 2022 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 // CLASS HEADER
18 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/scripting/scripting.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/object/property-array.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/object/type-registry.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
29 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
30 #include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
31 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
32 #include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
33 #include <dali-toolkit/internal/visuals/arc/arc-visual.h>
34 #include <dali-toolkit/internal/visuals/border/border-visual.h>
35 #include <dali-toolkit/internal/visuals/color/color-visual.h>
36 #include <dali-toolkit/internal/visuals/gradient/gradient-visual.h>
37 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
38 #include <dali-toolkit/internal/visuals/image/image-visual.h>
39 #include <dali-toolkit/internal/visuals/mesh/mesh-visual.h>
40 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
41 #include <dali-toolkit/internal/visuals/primitive/primitive-visual.h>
42 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
43 #include <dali-toolkit/internal/visuals/text/text-visual.h>
44 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
45 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
46 #include <dali-toolkit/internal/visuals/visual-url.h>
47 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
48 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
49 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
50 #include <dali-toolkit/public-api/visuals/visual-properties.h>
51
52 namespace Dali
53 {
54 namespace Toolkit
55 {
56 namespace Internal
57 {
58 namespace
59 {
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
62 #endif
63
64 BaseHandle Create()
65 {
66   BaseHandle handle = Toolkit::VisualFactory::Get();
67
68   return handle;
69 }
70
71 DALI_TYPE_REGISTRATION_BEGIN_CREATE(Toolkit::VisualFactory, Dali::BaseHandle, Create, true)
72 DALI_TYPE_REGISTRATION_END()
73 const char* const BROKEN_IMAGE_FILE_NAME = "broken.png"; ///< The file name of the broken image.
74
75 } // namespace
76
77 VisualFactory::VisualFactory(bool debugEnabled)
78 : mFactoryCache(),
79   mImageVisualShaderFactory(),
80   mSlotDelegate(this),
81   mDebugEnabled(debugEnabled),
82   mPreMultiplyOnLoad(true)
83 {
84 }
85
86 VisualFactory::~VisualFactory()
87 {
88 }
89
90 void VisualFactory::OnStyleChangedSignal(Toolkit::StyleManager styleManager, StyleChange::Type type)
91 {
92   if(type == StyleChange::THEME_CHANGE)
93   {
94     SetBrokenImageUrl(styleManager);
95   }
96 }
97
98 void VisualFactory::OnBrokenImageChangedSignal(Toolkit::StyleManager styleManager)
99 {
100   SetBrokenImageUrl(styleManager);
101 }
102
103 Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyMap)
104 {
105   Visual::BasePtr visualPtr;
106
107   Property::Value*           typeValue  = propertyMap.Find(Toolkit::Visual::Property::TYPE, VISUAL_TYPE);
108   Toolkit::DevelVisual::Type visualType = Toolkit::DevelVisual::IMAGE; // Default to IMAGE type.
109   if(typeValue)
110   {
111     Scripting::GetEnumerationProperty(*typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType);
112   }
113
114   switch(visualType)
115   {
116     case Toolkit::Visual::BORDER:
117     {
118       visualPtr = BorderVisual::New(GetFactoryCache(), propertyMap);
119       break;
120     }
121
122     case Toolkit::Visual::COLOR:
123     {
124       visualPtr = ColorVisual::New(GetFactoryCache(), propertyMap);
125       break;
126     }
127
128     case Toolkit::Visual::GRADIENT:
129     {
130       visualPtr = GradientVisual::New(GetFactoryCache(), propertyMap);
131       break;
132     }
133
134     case Toolkit::Visual::IMAGE:
135     {
136       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
137       std::string      imageUrl;
138       if(imageURLValue)
139       {
140         if(imageURLValue->Get(imageUrl))
141         {
142           if(!imageUrl.empty())
143           {
144             VisualUrl visualUrl(imageUrl);
145
146             switch(visualUrl.GetType())
147             {
148               case VisualUrl::N_PATCH:
149               {
150                 visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
151                 break;
152               }
153               case VisualUrl::TVG:
154               case VisualUrl::SVG:
155               {
156                 visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
157                 break;
158               }
159               case VisualUrl::GIF:
160               case VisualUrl::WEBP:
161               {
162                 visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
163                 break;
164               }
165               case VisualUrl::JSON:
166               {
167                 visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
168                 break;
169               }
170               case VisualUrl::REGULAR_IMAGE:
171               {
172                 visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
173                 break;
174               }
175             }
176           }
177         }
178         else
179         {
180           Property::Array* array = imageURLValue->GetArray();
181           if(array && array->Count() > 0)
182           {
183             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
184           }
185         }
186       }
187       break;
188     }
189
190     case Toolkit::Visual::MESH:
191     {
192       visualPtr = MeshVisual::New(GetFactoryCache(), propertyMap);
193       break;
194     }
195
196     case Toolkit::Visual::PRIMITIVE:
197     {
198       visualPtr = PrimitiveVisual::New(GetFactoryCache(), propertyMap);
199       break;
200     }
201
202     case Toolkit::Visual::WIREFRAME:
203     {
204       visualPtr = WireframeVisual::New(GetFactoryCache(), propertyMap);
205       break;
206     }
207
208     case Toolkit::Visual::TEXT:
209     {
210       visualPtr = TextVisual::New(GetFactoryCache(), propertyMap);
211       break;
212     }
213
214     case Toolkit::Visual::N_PATCH:
215     {
216       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
217       std::string      imageUrl;
218       if(imageURLValue && imageURLValue->Get(imageUrl))
219       {
220         if(!imageUrl.empty())
221         {
222           visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
223         }
224       }
225       break;
226     }
227
228     case Toolkit::Visual::SVG:
229     {
230       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
231       std::string      imageUrl;
232       if(imageURLValue && imageURLValue->Get(imageUrl))
233       {
234         if(!imageUrl.empty())
235         {
236           visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
237         }
238       }
239       break;
240     }
241
242     case Toolkit::Visual::ANIMATED_IMAGE:
243     {
244       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
245       std::string      imageUrl;
246       if(imageURLValue)
247       {
248         if(imageURLValue->Get(imageUrl))
249         {
250           if(!imageUrl.empty())
251           {
252             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
253           }
254         }
255         else
256         {
257           Property::Array* array = imageURLValue->GetArray();
258           if(array && array->Count() > 0)
259           {
260             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
261           }
262         }
263       }
264       break;
265     }
266
267     case Toolkit::DevelVisual::ANIMATED_GRADIENT:
268     {
269       visualPtr = AnimatedGradientVisual::New(GetFactoryCache(), propertyMap);
270       break;
271     }
272
273     case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
274     {
275       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
276       std::string      imageUrl;
277       if(imageURLValue && imageURLValue->Get(imageUrl))
278       {
279         if(!imageUrl.empty())
280         {
281           visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
282         }
283       }
284       break;
285     }
286
287     case Toolkit::DevelVisual::ARC:
288     {
289       visualPtr = ArcVisual::New(GetFactoryCache(), propertyMap);
290       break;
291     }
292   }
293
294   DALI_LOG_INFO(gLogFilter, Debug::Concise, "VisualFactory::CreateVisual( VisualType:%s %s%s)\n", Scripting::GetEnumerationName<Toolkit::DevelVisual::Type>(visualType, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT), (visualType == Toolkit::DevelVisual::IMAGE) ? "url:" : "", (visualType == Toolkit::DevelVisual::IMAGE) ? (([&]() {
295                   // Return URL if present in PropertyMap else return "not found message"
296                   Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
297                   return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
298                 })())
299                                                                                                                                                                                                                                                                                                                             : "");
300
301   if(!visualPtr)
302   {
303     DALI_LOG_ERROR("VisualType unknown\n");
304   }
305
306   if(mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME)
307   {
308     //Create a WireframeVisual if we have debug enabled
309     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr, propertyMap);
310   }
311
312   return Toolkit::Visual::Base(visualPtr.Get());
313 }
314
315 Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageDimensions size)
316 {
317   Visual::BasePtr visualPtr;
318
319   if(!url.empty())
320   {
321     // first resolve url type to know which visual to create
322     VisualUrl visualUrl(url);
323     switch(visualUrl.GetType())
324     {
325       case VisualUrl::N_PATCH:
326       {
327         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
328         break;
329       }
330       case VisualUrl::TVG:
331       case VisualUrl::SVG:
332       {
333         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
334         break;
335       }
336       case VisualUrl::GIF:
337       case VisualUrl::WEBP:
338       {
339         visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
340         break;
341       }
342       case VisualUrl::JSON:
343       {
344         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
345         break;
346       }
347       case VisualUrl::REGULAR_IMAGE:
348       {
349         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
350         break;
351       }
352     }
353   }
354
355   if(mDebugEnabled)
356   {
357     //Create a WireframeVisual if we have debug enabled
358     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr);
359   }
360
361   return Toolkit::Visual::Base(visualPtr.Get());
362 }
363
364 void VisualFactory::SetPreMultiplyOnLoad(bool preMultiply)
365 {
366   if(mPreMultiplyOnLoad != preMultiply)
367   {
368     GetFactoryCache().SetPreMultiplyOnLoad(preMultiply);
369   }
370   mPreMultiplyOnLoad = preMultiply;
371 }
372
373 bool VisualFactory::GetPreMultiplyOnLoad() const
374 {
375   return mPreMultiplyOnLoad;
376 }
377
378 Internal::TextureManager& VisualFactory::GetTextureManager()
379 {
380   return GetFactoryCache().GetTextureManager();
381 }
382
383 void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager)
384 {
385   const std::string        imageDirPath   = AssetManager::GetDaliImagePath();
386   std::string              brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
387   std::vector<std::string> customBrokenImageUrlList;
388
389   if(styleManager)
390   {
391     customBrokenImageUrlList = Toolkit::DevelStyleManager::GetBrokenImageUrlList(styleManager);
392     Property::Map config     = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
393     config["brokenImageUrl"].Get(brokenImageUrl);
394   }
395
396   // Add default image
397   mFactoryCache->SetBrokenImageUrl(brokenImageUrl, customBrokenImageUrlList);
398 }
399
400 Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
401 {
402   if(!mFactoryCache)
403   {
404     mFactoryCache                      = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
405     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
406     if(styleManager)
407     {
408       styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
409       Toolkit::DevelStyleManager::BrokenImageChangedSignal(styleManager).Connect(mSlotDelegate, &VisualFactory::OnBrokenImageChangedSignal);
410     }
411     SetBrokenImageUrl(styleManager);
412   }
413   return *mFactoryCache;
414 }
415
416 ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory()
417 {
418   if(!mImageVisualShaderFactory)
419   {
420     mImageVisualShaderFactory = std::unique_ptr<ImageVisualShaderFactory>(new ImageVisualShaderFactory());
421   }
422   return *mImageVisualShaderFactory;
423 }
424
425 } // namespace Internal
426
427 } // namespace Toolkit
428
429 } // namespace Dali