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