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