e98f539edff9b82e36f4f30c2fd45d87174de186
[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/devel-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 #include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
16
17 namespace Dali
18 {
19
20 namespace Toolkit
21 {
22
23 namespace Internal
24 {
25
26 namespace
27 {
28
29 BaseHandle Create()
30 {
31   return Toolkit::ImageView::New();
32 }
33
34 // Setup properties, signals and actions using the type-registry.
35 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create );
36 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resourceUrl", STRING, RESOURCE_URL )
37 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE )
38 DALI_TYPE_REGISTRATION_END()
39
40 } // anonymous namespace
41
42 using namespace Dali;
43
44 ImageView::ImageView()
45 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
46 {
47 }
48
49 ImageView::~ImageView()
50 {
51 }
52
53 Toolkit::ImageView ImageView::New()
54 {
55   ImageView* impl = new ImageView();
56
57   Toolkit::ImageView handle = Toolkit::ImageView( *impl );
58
59   // Second-phase init of the implementation
60   // This can only be done after the CustomActor connection has been made...
61   impl->Initialize();
62
63   return handle;
64 }
65
66 /////////////////////////////////////////////////////////////
67
68 void ImageView::SetImage( Image image )
69 {
70   if( ( mImage != image ) ||
71       ! mUrl.empty()      ||   // If we're changing from a URL type to an Image type
72       ! mPropertyMap.Empty() ) // If we're changing from a property map type to an Image type
73   {
74     mUrl.clear();
75     mPropertyMap.Clear();
76
77     mImage = image;
78
79     Actor self = Self();
80     Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, image );
81     mImageSize = image ? ImageDimensions( image.GetWidth(), image.GetHeight() ) : ImageDimensions( 0, 0 );
82
83     RelayoutRequest();
84   }
85 }
86
87 void ImageView::SetImage( Property::Map map )
88 {
89   mUrl.clear();
90   mImage.Reset();
91   mPropertyMap = map;
92
93   Actor self = Self();
94   Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mPropertyMap );
95
96   Property::Value* widthValue = mPropertyMap.Find( "width" );
97   if( widthValue )
98   {
99     int width;
100     if( widthValue->Get( width ) )
101     {
102       mImageSize = ImageDimensions( width, mImageSize.GetHeight() );
103     }
104   }
105
106   Property::Value* heightValue = mPropertyMap.Find( "height" );
107   if( heightValue )
108   {
109     int height;
110     if( heightValue->Get( height ) )
111     {
112       mImageSize = ImageDimensions( mImageSize.GetWidth(), height );
113     }
114   }
115
116   RelayoutRequest();
117 }
118
119 void ImageView::SetImage( const std::string& url, ImageDimensions size )
120 {
121   if( ( mUrl != url ) ||
122       mImage          ||       // If we're changing from an Image type to a URL type
123       ! mPropertyMap.Empty() ) // If we're changing from a property map type to a URL type
124   {
125     mImage.Reset();
126     mPropertyMap.Clear();
127
128     mUrl = url;
129
130     if( size.GetWidth() == 0u && size.GetHeight() == 0u )
131     {
132       mImageSize = ResourceImage::GetImageSize( mUrl );
133     }
134     else
135     {
136       mImageSize = size;
137     }
138
139     Actor self = Self();
140     Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mUrl, mImageSize );
141
142     RelayoutRequest();
143   }
144 }
145
146 void ImageView::SetDepthIndex( int depthIndex )
147 {
148   mRenderer.SetDepthIndex( depthIndex );
149 }
150
151 Vector3 ImageView::GetNaturalSize()
152 {
153   Vector3 size;
154
155   size.x = mImageSize.GetWidth();
156   size.y = mImageSize.GetHeight();
157   size.z = std::min(size.x, size.y);
158
159   if( size.x > 0 && size.y > 0 )
160   {
161     return size;
162   }
163   else
164   {
165     // if no image then use Control's natural size
166     return Control::GetNaturalSize();
167   }
168 }
169
170 float ImageView::GetHeightForWidth( float width )
171 {
172   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
173   {
174     return GetHeightForWidthBase( width );
175   }
176   else
177   {
178     return Control::GetHeightForWidth( width );
179   }
180 }
181
182 float ImageView::GetWidthForHeight( float height )
183 {
184   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
185   {
186     return GetWidthForHeightBase( height );
187   }
188   else
189   {
190     return Control::GetWidthForHeight( height );
191   }
192 }
193
194 ///////////////////////////////////////////////////////////
195 //
196 // Private methods
197 //
198
199 void ImageView::OnStageConnection( int depth )
200 {
201   Control::OnStageConnection( depth );
202
203   if( mRenderer )
204   {
205     CustomActor self = Self();
206     mRenderer.SetOnStage( self );
207   }
208 }
209
210 void ImageView::OnStageDisconnection()
211 {
212   if( mRenderer )
213   {
214     CustomActor self = Self();
215     mRenderer.SetOffStage( self );
216   }
217
218   Control::OnStageDisconnection();
219 }
220
221
222 ///////////////////////////////////////////////////////////
223 //
224 // Properties
225 //
226
227 void ImageView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
228 {
229   Toolkit::ImageView imageView = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
230
231   if ( imageView )
232   {
233     switch ( index )
234     {
235       case Toolkit::ImageView::Property::RESOURCE_URL:
236       {
237         std::string imageUrl;
238         if( value.Get( imageUrl ) )
239         {
240           GetImpl( imageView ).SetImage( imageUrl, ImageDimensions() );
241         }
242         break;
243       }
244
245       case Toolkit::ImageView::Property::IMAGE:
246       {
247         std::string imageUrl;
248         if( value.Get( imageUrl ) )
249         {
250           ImageView& impl = GetImpl( imageView );
251           impl.SetImage( imageUrl, ImageDimensions() );
252         }
253
254         // if its not a string then get a Property::Map from the property if possible.
255         Property::Map map;
256         if( value.Get( map ) )
257         {
258           ImageView& impl = GetImpl( imageView );
259           impl.SetImage( map );
260         }
261
262         break;
263       }
264     }
265   }
266 }
267
268 Property::Value ImageView::GetProperty( BaseObject* object, Property::Index propertyIndex )
269 {
270   Property::Value value;
271
272   Toolkit::ImageView imageview = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
273
274   if ( imageview )
275   {
276     switch ( propertyIndex )
277     {
278       case Toolkit::ImageView::Property::RESOURCE_URL:
279       {
280         ImageView& impl = GetImpl( imageview );
281         if ( !impl.mUrl.empty() )
282         {
283           value = impl.mUrl;
284         }
285         break;
286       }
287
288       case Toolkit::ImageView::Property::IMAGE:
289       {
290         ImageView& impl = GetImpl( imageview );
291         if ( !impl.mUrl.empty() )
292         {
293           value = impl.mUrl;
294         }
295         else if( impl.mImage )
296         {
297           Property::Map map;
298           Scripting::CreatePropertyMap( impl.mImage, map );
299           value = map;
300         }
301         else if( !impl.mPropertyMap.Empty() )
302         {
303           value = impl.mPropertyMap;
304         }
305         break;
306       }
307     }
308   }
309
310   return value;
311 }
312
313 } // namespace Internal
314 } // namespace Toolkit
315 } // namespace Dali