2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/actors/image-actor-impl.h>
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/public-api/scripting/scripting.h>
24 #include <dali/internal/event/common/property-helper.h>
25 #include <dali/internal/event/images/image-connector.h>
26 #include <dali/internal/event/images/nine-patch-image-impl.h>
39 // Name Type writable animatable constraint-input enum for index-checking
40 DALI_PROPERTY_TABLE_BEGIN
41 DALI_PROPERTY( "pixel-area", RECTANGLE, true, false, true, Dali::ImageActor::Property::PIXEL_AREA )
42 DALI_PROPERTY( "style", STRING, true, false, true, Dali::ImageActor::Property::STYLE )
43 DALI_PROPERTY( "border", VECTOR4, true, false, true, Dali::ImageActor::Property::BORDER )
44 DALI_PROPERTY( "image", MAP, true, false, false, Dali::ImageActor::Property::IMAGE )
45 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
49 return Dali::ImageActor::New();
52 TypeRegistration mType( typeid( Dali::ImageActor ), typeid( Dali::RenderableActor ), Create );
54 ImageActor::Style StyleEnum(const std::string &s)
56 if(s == "STYLE_NINE_PATCH")
58 return Dali::ImageActor::STYLE_NINE_PATCH;
60 else if(s == "STYLE_NINE_PATCH_NO_CENTER")
62 return Dali::ImageActor::STYLE_NINE_PATCH_NO_CENTER;
64 else // if(s == "QUAD")
66 return Dali::ImageActor::STYLE_QUAD;
70 std::string StyleString(const ImageActor::Style style)
72 if(style == Dali::ImageActor::STYLE_NINE_PATCH)
74 return "STYLE_NINE_PATCH";
76 else if(style == Dali::ImageActor::STYLE_NINE_PATCH_NO_CENTER)
78 return "STYLE_NINE_PATCH_NO_CENTER";
80 else // if(s == "QUAD")
87 ImageActorPtr ImageActor::New()
89 ImageActorPtr actor( new ImageActor );
91 // Second-phase construction of base class
94 // Create the attachment
95 actor->mImageAttachment = ImageAttachment::New( actor->GetEventThreadServices(), *actor->mNode );
96 actor->Attach( *actor->mImageAttachment );
101 void ImageActor::OnInitialize()
103 SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
106 void ImageActor::SetImage( ImagePtr& image )
108 ImagePtr currentImage = mImageAttachment->GetImage();
109 // early exit if it's the same image as we already have
110 if ( currentImage == image )
115 // NOTE! image might be pointing to NULL, which is fine as in that case app wants to just remove the image
116 ImagePtr newImage( image );
117 // if image is not NULL, check for 9 patch
120 // Automatically convert nine-patch images to cropped bitmap
121 NinePatchImage* ninePatchImage = NinePatchImage::DownCast( image.Get() );
124 newImage = ninePatchImage->CreateCroppedBufferImage();
125 SetStyle( Dali::ImageActor::STYLE_NINE_PATCH );
126 SetNinePatchBorder( ninePatchImage->GetStretchBorders(), true );
129 // set the actual image (normal or 9 patch) and natural size based on that
130 mImageAttachment->SetImage( newImage );
134 ImagePtr ImageActor::GetImage()
136 return mImageAttachment->GetImage();
139 void ImageActor::SetToNaturalSize()
141 mUsingNaturalSize = true;
146 void ImageActor::SetPixelArea( const PixelArea& pixelArea )
148 mImageAttachment->SetPixelArea( pixelArea );
153 const ImageActor::PixelArea& ImageActor::GetPixelArea() const
155 return mImageAttachment->GetPixelArea();
158 bool ImageActor::IsPixelAreaSet() const
160 return mImageAttachment->IsPixelAreaSet();
163 void ImageActor::ClearPixelArea()
165 mImageAttachment->ClearPixelArea();
167 if( mUsingNaturalSize )
169 ImagePtr image = mImageAttachment->GetImage();
172 mInternalSetSize = true;
173 SetSize( image->GetNaturalSize() );
174 SetPreferredSize( GetTargetSize().GetVectorXY() );
175 mInternalSetSize = false;
180 void ImageActor::SetStyle( Style style )
182 mImageAttachment->SetStyle( style );
185 ImageActor::Style ImageActor::GetStyle() const
187 return mImageAttachment->GetStyle();
190 void ImageActor::SetNinePatchBorder( const Vector4& border, bool inPixels )
192 mImageAttachment->SetNinePatchBorder( border, inPixels );
195 Vector4 ImageActor::GetNinePatchBorder() const
197 return mImageAttachment->GetNinePatchBorder();
200 ImageAttachment& ImageActor::GetImageAttachment()
202 return *mImageAttachment;
205 RenderableAttachment& ImageActor::GetRenderableAttachment() const
207 DALI_ASSERT_DEBUG( mImageAttachment && "ImageAttachment missing from ImageActor" );
208 return *mImageAttachment;
211 ImageActor::ImageActor()
213 mUsingNaturalSize(true),
214 mInternalSetSize(false)
216 // Size negotiate disabled by default, so turn it on for this actor
217 SetRelayoutEnabled( true );
220 ImageActor::~ImageActor()
224 void ImageActor::SetNaturalSize()
226 if( mUsingNaturalSize )
228 mInternalSetSize = true;
229 SetSize( CalculateNaturalSize() );
230 SetPreferredSize( GetTargetSize().GetVectorXY() );
231 mInternalSetSize = false;
235 Vector3 ImageActor::GetNaturalSize() const
237 Vector2 naturalSize( CalculateNaturalSize() );
238 return Vector3( naturalSize.width, naturalSize.height, CalculateSizeZ( naturalSize ) );
241 Vector2 ImageActor::CalculateNaturalSize() const
243 // if no image then natural size is 0
244 Vector2 size( 0.0f, 0.0f );
246 ImagePtr image = mImageAttachment->GetImage();
249 if( IsPixelAreaSet() )
251 PixelArea area(GetPixelArea());
252 size.width = area.width;
253 size.height = area.height;
257 size = image->GetNaturalSize();
264 void ImageActor::OnSizeSet( const Vector3& targetSize )
266 if( !mInternalSetSize )
268 mUsingNaturalSize = false;
272 void ImageActor::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
274 mUsingNaturalSize = false;
277 void ImageActor::OnStageConnectionInternal()
281 void ImageActor::OnStageDisconnectionInternal()
285 unsigned int ImageActor::GetDefaultPropertyCount() const
287 return RenderableActor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
290 void ImageActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
292 RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
294 indices.reserve( indices.size() + DEFAULT_PROPERTY_COUNT );
296 int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
297 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
299 indices.push_back( index );
303 bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
305 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
307 return RenderableActor::IsDefaultPropertyWritable(index);
310 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
311 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
313 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
319 bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
321 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
323 return RenderableActor::IsDefaultPropertyAnimatable( index );
326 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
327 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
329 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
335 bool ImageActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
337 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
339 return RenderableActor::IsDefaultPropertyAConstraintInput( index );
342 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
343 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
345 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
351 Property::Type ImageActor::GetDefaultPropertyType( Property::Index index ) const
353 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
355 return RenderableActor::GetDefaultPropertyType( index );
358 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
359 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
361 return DEFAULT_PROPERTY_DETAILS[index].type;
364 // index out-of-bounds
365 return Property::NONE;
368 const char* ImageActor::GetDefaultPropertyName( Property::Index index ) const
370 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
372 return RenderableActor::GetDefaultPropertyName(index);
375 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
376 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
378 return DEFAULT_PROPERTY_DETAILS[index].name;
381 // index out-of-bounds
385 Property::Index ImageActor::GetDefaultPropertyIndex(const std::string& name) const
387 Property::Index index = Property::INVALID_INDEX;
389 // Look for name in default properties
390 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
392 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
393 if( 0 == strcmp( name.c_str(), property->name ) ) // Don't want to convert rhs to string
395 index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
400 // If not found, check in base class
401 if( Property::INVALID_INDEX == index )
403 index = RenderableActor::GetDefaultPropertyIndex( name );
408 void ImageActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
410 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
412 RenderableActor::SetDefaultProperty( index, propertyValue );
418 case Dali::ImageActor::Property::PIXEL_AREA:
420 SetPixelArea(propertyValue.Get<Rect<int> >());
423 case Dali::ImageActor::Property::STYLE:
425 SetStyle( StyleEnum( propertyValue.Get<std::string>() ) );
428 case Dali::ImageActor::Property::BORDER:
430 SetNinePatchBorder( propertyValue.Get<Vector4>(), true /*in pixels*/ );
433 case Dali::ImageActor::Property::IMAGE:
435 Dali::Image img = Scripting::NewImage( propertyValue );
438 ImagePtr image( &GetImplementation(img) );
443 DALI_LOG_WARNING("Cannot create image from property value\n");
449 DALI_LOG_WARNING("Unknown property (%d)\n", index);
457 Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
460 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
462 ret = RenderableActor::GetDefaultProperty( index );
468 case Dali::ImageActor::Property::PIXEL_AREA:
470 Rect<int> r = GetPixelArea();
474 case Dali::ImageActor::Property::STYLE:
476 ret = StyleString( GetStyle() );
479 case Dali::ImageActor::Property::BORDER:
481 ret = GetNinePatchBorder();
484 case Dali::ImageActor::Property::IMAGE:
487 Scripting::CreatePropertyMap( Dali::Image( mImageAttachment->GetImage().Get() ), map );
488 ret = Property::Value( map );
493 DALI_LOG_WARNING( "Unknown property (%d)\n", index );
502 } // namespace Internal