Merge "Refactorying code related to broken image" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-factory-impl.cpp
1 /*
2  * Copyright (c) 2021 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)
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         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
221       }
222       break;
223     }
224
225     case Toolkit::Visual::SVG:
226     {
227       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
228       std::string      imageUrl;
229       if(imageURLValue && imageURLValue->Get(imageUrl))
230       {
231         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
232       }
233       break;
234     }
235
236     case Toolkit::Visual::ANIMATED_IMAGE:
237     {
238       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
239       std::string      imageUrl;
240       if(imageURLValue)
241       {
242         if(imageURLValue->Get(imageUrl))
243         {
244           visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
245         }
246         else
247         {
248           Property::Array* array = imageURLValue->GetArray();
249           if(array)
250           {
251             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
252           }
253         }
254       }
255       break;
256     }
257
258     case Toolkit::DevelVisual::ANIMATED_GRADIENT:
259     {
260       visualPtr = AnimatedGradientVisual::New(GetFactoryCache(), propertyMap);
261       break;
262     }
263
264     case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
265     {
266       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
267       std::string      imageUrl;
268       if(imageURLValue && imageURLValue->Get(imageUrl))
269       {
270         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
271       }
272       break;
273     }
274
275     case Toolkit::DevelVisual::ARC:
276     {
277       visualPtr = ArcVisual::New(GetFactoryCache(), propertyMap);
278       break;
279     }
280   }
281
282   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) ? (([&]() {
283                   // Return URL if present in PropertyMap else return "not found message"
284                   Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
285                   return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
286                 })())
287                                                                                                                                                                                                                                                                                                                             : "");
288
289   if(!visualPtr)
290   {
291     DALI_LOG_ERROR("VisualType unknown\n");
292   }
293
294   if(mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME)
295   {
296     //Create a WireframeVisual if we have debug enabled
297     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr, propertyMap);
298   }
299
300   return Toolkit::Visual::Base(visualPtr.Get());
301 }
302
303 Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageDimensions size)
304 {
305   Visual::BasePtr visualPtr;
306
307   if(!url.empty())
308   {
309     // first resolve url type to know which visual to create
310     VisualUrl visualUrl(url);
311     switch(visualUrl.GetType())
312     {
313       case VisualUrl::N_PATCH:
314       {
315         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
316         break;
317       }
318       case VisualUrl::TVG:
319       case VisualUrl::SVG:
320       {
321         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
322         break;
323       }
324       case VisualUrl::GIF:
325       case VisualUrl::WEBP:
326       {
327         visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
328         break;
329       }
330       case VisualUrl::JSON:
331       {
332         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
333         break;
334       }
335       case VisualUrl::REGULAR_IMAGE:
336       {
337         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
338         break;
339       }
340     }
341   }
342
343   if(mDebugEnabled)
344   {
345     //Create a WireframeVisual if we have debug enabled
346     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr);
347   }
348
349   return Toolkit::Visual::Base(visualPtr.Get());
350 }
351
352 void VisualFactory::SetPreMultiplyOnLoad(bool preMultiply)
353 {
354   if(mPreMultiplyOnLoad != preMultiply)
355   {
356     GetFactoryCache().SetPreMultiplyOnLoad(preMultiply);
357   }
358   mPreMultiplyOnLoad = preMultiply;
359 }
360
361 bool VisualFactory::GetPreMultiplyOnLoad() const
362 {
363   return mPreMultiplyOnLoad;
364 }
365
366 Internal::TextureManager& VisualFactory::GetTextureManager()
367 {
368   return GetFactoryCache().GetTextureManager();
369 }
370
371 void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager)
372 {
373   const std::string imageDirPath   = AssetManager::GetDaliImagePath();
374   std::string       brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
375   std::vector<std::string> customBrokenImageUrlList;
376
377   if(styleManager)
378   {
379     customBrokenImageUrlList = Toolkit::DevelStyleManager::GetBrokenImageUrlList(styleManager);
380     Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
381     config["brokenImageUrl"].Get(brokenImageUrl);
382   }
383
384   // Add default image
385   mFactoryCache->SetBrokenImageUrl(brokenImageUrl, customBrokenImageUrlList);
386 }
387
388 Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
389 {
390   if(!mFactoryCache)
391   {
392     mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
393     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
394     if(styleManager)
395     {
396       styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
397       Toolkit::DevelStyleManager::BrokenImageChangedSignal(styleManager).Connect(mSlotDelegate, &VisualFactory::OnBrokenImageChangedSignal);
398     }
399     SetBrokenImageUrl(styleManager);
400   }
401   return *mFactoryCache;
402 }
403
404 ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory()
405 {
406   if(!mImageVisualShaderFactory)
407   {
408     mImageVisualShaderFactory = std::unique_ptr<ImageVisualShaderFactory>(new ImageVisualShaderFactory());
409   }
410   return *mImageVisualShaderFactory;
411 }
412
413 } // namespace Internal
414
415 } // namespace Toolkit
416
417 } // namespace Dali