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