ImageRenderer provides property to indicate async/sync resource loading
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / image-view / image-view-impl.cpp
1 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
2
3 // CLASS HEADER
4 #include "image-view-impl.h"
5
6 // EXTERNAL INCLUDES
7 #include <dali/public-api/images/resource-image.h>
8 #include <dali/public-api/object/type-registry.h>
9 #include <dali/public-api/object/type-registry-helper.h>
10 #include <dali/devel-api/scripting/scripting.h>
11
12 // INTERNAL INCLUDES
13 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
14 #include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
15
16 namespace Dali
17 {
18
19 namespace Toolkit
20 {
21
22 namespace Internal
23 {
24
25 namespace
26 {
27
28 BaseHandle Create()
29 {
30   return Toolkit::ImageView::New();
31 }
32
33 // Setup properties, signals and actions using the type-registry.
34 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create );
35 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resourceUrl", STRING, RESOURCE_URL )
36 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE )
37 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "preMultipliedAlpha", BOOLEAN, PRE_MULTIPLIED_ALPHA )
38
39 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA )
40 DALI_TYPE_REGISTRATION_END()
41
42 } // anonymous namespace
43
44 using namespace Dali;
45
46 ImageView::ImageView()
47 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
48 {
49 }
50
51 ImageView::~ImageView()
52 {
53 }
54
55 Toolkit::ImageView ImageView::New()
56 {
57   ImageView* impl = new ImageView();
58
59   Toolkit::ImageView handle = Toolkit::ImageView( *impl );
60
61   // Second-phase init of the implementation
62   // This can only be done after the CustomActor connection has been made...
63   impl->Initialize();
64
65   return handle;
66 }
67
68 /////////////////////////////////////////////////////////////
69
70 void ImageView::SetImage( Image image )
71 {
72   if( ( mImage != image ) ||
73       ! mUrl.empty()      ||   // If we're changing from a URL type to an Image type
74       ! mPropertyMap.Empty() ) // If we're changing from a property map type to an Image type
75   {
76     mUrl.clear();
77     mPropertyMap.Clear();
78
79     mImage = image;
80
81     Actor self = Self();
82     Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, image );
83     mImageSize = image ? ImageDimensions( image.GetWidth(), image.GetHeight() ) : ImageDimensions( 0, 0 );
84
85     RelayoutRequest();
86   }
87 }
88
89 void ImageView::SetImage( Property::Map map )
90 {
91   mUrl.clear();
92   mImage.Reset();
93   mPropertyMap = map;
94
95   Actor self = Self();
96   Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mPropertyMap );
97
98   Property::Value* widthValue = mPropertyMap.Find( "width" );
99   if( widthValue )
100   {
101     int width;
102     if( widthValue->Get( width ) )
103     {
104       mImageSize = ImageDimensions( width, mImageSize.GetHeight() );
105     }
106   }
107
108   Property::Value* heightValue = mPropertyMap.Find( "height" );
109   if( heightValue )
110   {
111     int height;
112     if( heightValue->Get( height ) )
113     {
114       mImageSize = ImageDimensions( mImageSize.GetWidth(), height );
115     }
116   }
117
118   RelayoutRequest();
119 }
120
121 void ImageView::SetImage( const std::string& url, ImageDimensions size )
122 {
123   if( ( mUrl != url ) ||
124       mImage          ||       // If we're changing from an Image type to a URL type
125       ! mPropertyMap.Empty() ) // If we're changing from a property map type to a URL type
126   {
127     mImage.Reset();
128     mPropertyMap.Clear();
129
130     mUrl = url;
131
132     if( size.GetWidth() != 0u && size.GetHeight() != 0u )
133     {
134       mImageSize = size;
135     }
136
137     Actor self = Self();
138     Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mUrl, size );
139
140     RelayoutRequest();
141   }
142 }
143
144 Image ImageView::GetImage() const
145 {
146   return mImage;
147 }
148
149 void ImageView::EnablePreMultipliedAlpha( bool preMultipled )
150 {
151   if( mRenderer )
152   {
153      GetImplementation( mRenderer ).EnablePreMultipliedAlpha( preMultipled );
154   }
155 }
156
157 bool ImageView::IsPreMultipliedAlphaEnabled() const
158 {
159   if( mRenderer )
160   {
161     return GetImplementation( mRenderer ).IsPreMultipliedAlphaEnabled();
162   }
163   return false;
164 }
165
166 void ImageView::SetDepthIndex( int depthIndex )
167 {
168   if( mRenderer )
169   {
170     mRenderer.SetDepthIndex( depthIndex );
171   }
172 }
173
174 Vector3 ImageView::GetNaturalSize()
175 {
176   if( mRenderer )
177   {
178     Vector2 rendererNaturalSize;
179     mRenderer.GetNaturalSize( rendererNaturalSize );
180     return Vector3( rendererNaturalSize );
181   }
182
183   Vector3 size;
184   size.x = mImageSize.GetWidth();
185   size.y = mImageSize.GetHeight();
186
187   if( size.x > 0 && size.y > 0 )
188   {
189     size.z = std::min(size.x, size.y);
190     return size;
191   }
192   else
193   {
194     // if no image then use Control's natural size
195     return Control::GetNaturalSize();
196   }
197 }
198
199 float ImageView::GetHeightForWidth( float width )
200 {
201   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
202   {
203     return GetHeightForWidthBase( width );
204   }
205   else
206   {
207     return Control::GetHeightForWidth( width );
208   }
209 }
210
211 float ImageView::GetWidthForHeight( float height )
212 {
213   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
214   {
215     return GetWidthForHeightBase( height );
216   }
217   else
218   {
219     return Control::GetWidthForHeight( height );
220   }
221 }
222
223
224 ///////////////////////////////////////////////////////////
225 //
226 // Private methods
227 //
228
229 void ImageView::OnStageConnection( int depth )
230 {
231   Control::OnStageConnection( depth );
232
233   if( mRenderer )
234   {
235     CustomActor self = Self();
236     mRenderer.SetOnStage( self );
237   }
238 }
239
240 void ImageView::OnStageDisconnection()
241 {
242   if( mRenderer )
243   {
244     CustomActor self = Self();
245     mRenderer.SetOffStage( self );
246   }
247
248   Control::OnStageDisconnection();
249 }
250
251 void ImageView::OnSizeSet( const Vector3& targetSize )
252 {
253   Control::OnSizeSet( targetSize );
254
255   if( mRenderer )
256   {
257     Vector2 size( targetSize );
258     mRenderer.SetSize( size );
259   }
260 }
261
262 ///////////////////////////////////////////////////////////
263 //
264 // Properties
265 //
266
267 void ImageView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
268 {
269   Toolkit::ImageView imageView = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
270
271   if ( imageView )
272   {
273     switch ( index )
274     {
275       case Toolkit::ImageView::Property::RESOURCE_URL:
276       {
277         std::string imageUrl;
278         if( value.Get( imageUrl ) )
279         {
280           GetImpl( imageView ).SetImage( imageUrl, ImageDimensions() );
281         }
282         break;
283       }
284
285       case Toolkit::ImageView::Property::IMAGE:
286       {
287         std::string imageUrl;
288         if( value.Get( imageUrl ) )
289         {
290           ImageView& impl = GetImpl( imageView );
291           impl.SetImage( imageUrl, ImageDimensions() );
292         }
293
294         // if its not a string then get a Property::Map from the property if possible.
295         Property::Map map;
296         if( value.Get( map ) )
297         {
298           ImageView& impl = GetImpl( imageView );
299           impl.SetImage( map );
300         }
301
302         break;
303       }
304
305       case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
306       {
307         bool isPre;
308         if( value.Get( isPre ) )
309         {
310           GetImpl(imageView).EnablePreMultipliedAlpha( isPre );
311         }
312         break;
313       }
314     }
315   }
316 }
317
318 Property::Value ImageView::GetProperty( BaseObject* object, Property::Index propertyIndex )
319 {
320   Property::Value value;
321
322   Toolkit::ImageView imageview = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
323
324   if ( imageview )
325   {
326     ImageView& impl = GetImpl( imageview );
327     switch ( propertyIndex )
328     {
329       case Toolkit::ImageView::Property::RESOURCE_URL:
330       {
331         if ( !impl.mUrl.empty() )
332         {
333           value = impl.mUrl;
334         }
335         break;
336       }
337
338       case Toolkit::ImageView::Property::IMAGE:
339       {
340         if ( !impl.mUrl.empty() )
341         {
342           value = impl.mUrl;
343         }
344         else if( impl.mImage )
345         {
346           Property::Map map;
347           Scripting::CreatePropertyMap( impl.mImage, map );
348           value = map;
349         }
350         else if( !impl.mPropertyMap.Empty() )
351         {
352           value = impl.mPropertyMap;
353         }
354         break;
355       }
356
357       case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
358       {
359         value = impl.IsPreMultipliedAlphaEnabled();
360         break;
361       }
362     }
363   }
364
365   return value;
366 }
367
368 } // namespace Internal
369 } // namespace Toolkit
370 } // namespace Dali