Merge "PixelArea support for ImageView" into devel/master
[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
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 = ResourceImage::GetImageSize( mUrl );
135     }
136     else
137     {
138       mImageSize = size;
139     }
140
141     Actor self = Self();
142     Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mUrl, mImageSize );
143
144     RelayoutRequest();
145   }
146 }
147
148 void ImageView::SetDepthIndex( int depthIndex )
149 {
150   if( mRenderer )
151   {
152     mRenderer.SetDepthIndex( depthIndex );
153   }
154 }
155
156 Vector3 ImageView::GetNaturalSize()
157 {
158   Vector3 size;
159
160   size.x = mImageSize.GetWidth();
161   size.y = mImageSize.GetHeight();
162
163   if( size.x > 0 && size.y > 0 )
164   {
165     size.z = std::min(size.x, size.y);
166     return size;
167   }
168   else
169   {
170     // if no image then use Control's natural size
171     return Control::GetNaturalSize();
172   }
173 }
174
175 float ImageView::GetHeightForWidth( float width )
176 {
177   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
178   {
179     return GetHeightForWidthBase( width );
180   }
181   else
182   {
183     return Control::GetHeightForWidth( width );
184   }
185 }
186
187 float ImageView::GetWidthForHeight( float height )
188 {
189   if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
190   {
191     return GetWidthForHeightBase( height );
192   }
193   else
194   {
195     return Control::GetWidthForHeight( height );
196   }
197 }
198
199
200 ///////////////////////////////////////////////////////////
201 //
202 // Private methods
203 //
204
205 void ImageView::OnStageConnection( int depth )
206 {
207   Control::OnStageConnection( depth );
208
209   if( mRenderer )
210   {
211     CustomActor self = Self();
212     mRenderer.SetOnStage( self );
213   }
214 }
215
216 void ImageView::OnStageDisconnection()
217 {
218   if( mRenderer )
219   {
220     CustomActor self = Self();
221     mRenderer.SetOffStage( self );
222   }
223
224   Control::OnStageDisconnection();
225 }
226
227 ///////////////////////////////////////////////////////////
228 //
229 // Properties
230 //
231
232 void ImageView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
233 {
234   Toolkit::ImageView imageView = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
235
236   if ( imageView )
237   {
238     switch ( index )
239     {
240       case Toolkit::ImageView::Property::RESOURCE_URL:
241       {
242         std::string imageUrl;
243         if( value.Get( imageUrl ) )
244         {
245           GetImpl( imageView ).SetImage( imageUrl, ImageDimensions() );
246         }
247         break;
248       }
249
250       case Toolkit::ImageView::Property::IMAGE:
251       {
252         std::string imageUrl;
253         if( value.Get( imageUrl ) )
254         {
255           ImageView& impl = GetImpl( imageView );
256           impl.SetImage( imageUrl, ImageDimensions() );
257         }
258
259         // if its not a string then get a Property::Map from the property if possible.
260         Property::Map map;
261         if( value.Get( map ) )
262         {
263           ImageView& impl = GetImpl( imageView );
264           impl.SetImage( map );
265         }
266
267         break;
268       }
269     }
270   }
271 }
272
273 Property::Value ImageView::GetProperty( BaseObject* object, Property::Index propertyIndex )
274 {
275   Property::Value value;
276
277   Toolkit::ImageView imageview = Toolkit::ImageView::DownCast( Dali::BaseHandle( object ) );
278
279   if ( imageview )
280   {
281     ImageView& impl = GetImpl( imageview );
282     switch ( propertyIndex )
283     {
284       case Toolkit::ImageView::Property::RESOURCE_URL:
285       {
286         if ( !impl.mUrl.empty() )
287         {
288           value = impl.mUrl;
289         }
290         break;
291       }
292
293       case Toolkit::ImageView::Property::IMAGE:
294       {
295         if ( !impl.mUrl.empty() )
296         {
297           value = impl.mUrl;
298         }
299         else if( impl.mImage )
300         {
301           Property::Map map;
302           Scripting::CreatePropertyMap( impl.mImage, map );
303           value = map;
304         }
305         else if( !impl.mPropertyMap.Empty() )
306         {
307           value = impl.mPropertyMap;
308         }
309         break;
310       }
311     }
312   }
313
314   return value;
315 }
316
317 } // namespace Internal
318 } // namespace Toolkit
319 } // namespace Dali