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 <cstring> // for strcmp
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/scripting/scripting.h>
27 #include <dali/internal/event/common/property-helper.h>
28 #include <dali/internal/event/images/image-connector.h>
29 #include <dali/internal/event/images/nine-patch-image-impl.h>
42 // Name Type writable animatable constraint-input enum for index-checking
43 DALI_PROPERTY_TABLE_BEGIN
44 DALI_PROPERTY( "pixel-area", RECTANGLE, true, false, true, Dali::ImageActor::Property::PIXEL_AREA )
45 DALI_PROPERTY( "style", STRING, true, false, true, Dali::ImageActor::Property::STYLE )
46 DALI_PROPERTY( "border", VECTOR4, true, false, true, Dali::ImageActor::Property::BORDER )
47 DALI_PROPERTY( "image", MAP, true, false, false, Dali::ImageActor::Property::IMAGE )
48 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
52 return Dali::ImageActor::New();
55 TypeRegistration mType( typeid( Dali::ImageActor ), typeid( Dali::RenderableActor ), Create );
57 ImageActor::Style StyleEnum(const std::string &s)
59 if(s == "STYLE_NINE_PATCH")
61 return Dali::ImageActor::STYLE_NINE_PATCH;
63 else if(s == "STYLE_NINE_PATCH_NO_CENTER")
65 return Dali::ImageActor::STYLE_NINE_PATCH_NO_CENTER;
67 else // if(s == "QUAD")
69 return Dali::ImageActor::STYLE_QUAD;
73 std::string StyleString(const ImageActor::Style style)
75 if(style == Dali::ImageActor::STYLE_NINE_PATCH)
77 return "STYLE_NINE_PATCH";
79 else if(style == Dali::ImageActor::STYLE_NINE_PATCH_NO_CENTER)
81 return "STYLE_NINE_PATCH_NO_CENTER";
83 else // if(s == "QUAD")
90 ImageActorPtr ImageActor::New()
92 ImageActorPtr actor( new ImageActor );
94 // Second-phase construction of base class
97 // Create the attachment
98 actor->mImageAttachment = ImageAttachment::New( actor->GetEventThreadServices(), *actor->mNode );
99 actor->Attach( *actor->mImageAttachment );
104 void ImageActor::OnInitialize()
106 SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
109 void ImageActor::SetImage( ImagePtr& image )
111 ImagePtr currentImage = mImageAttachment->GetImage();
112 // early exit if it's the same image as we already have
113 if ( currentImage == image )
118 // NOTE! image might be pointing to NULL, which is fine as in that case app wants to just remove the image
119 ImagePtr newImage( image );
120 // if image is not NULL, check for 9 patch
123 // Automatically convert nine-patch images to cropped bitmap
124 NinePatchImage* ninePatchImage = NinePatchImage::DownCast( image.Get() );
127 newImage = ninePatchImage->CreateCroppedBufferImage();
128 SetStyle( Dali::ImageActor::STYLE_NINE_PATCH );
129 SetNinePatchBorder( ninePatchImage->GetStretchBorders(), true );
132 // set the actual image (normal or 9 patch) and natural size based on that
133 mImageAttachment->SetImage( newImage );
138 ImagePtr ImageActor::GetImage()
140 return mImageAttachment->GetImage();
143 void ImageActor::SetPixelArea( const PixelArea& pixelArea )
145 mImageAttachment->SetPixelArea( pixelArea );
150 const ImageActor::PixelArea& ImageActor::GetPixelArea() const
152 return mImageAttachment->GetPixelArea();
155 bool ImageActor::IsPixelAreaSet() const
157 return mImageAttachment->IsPixelAreaSet();
160 void ImageActor::ClearPixelArea()
162 mImageAttachment->ClearPixelArea();
167 void ImageActor::SetStyle( Style style )
169 mImageAttachment->SetStyle( style );
172 ImageActor::Style ImageActor::GetStyle() const
174 return mImageAttachment->GetStyle();
177 void ImageActor::SetNinePatchBorder( const Vector4& border, bool inPixels )
179 mImageAttachment->SetNinePatchBorder( border, inPixels );
182 Vector4 ImageActor::GetNinePatchBorder() const
184 return mImageAttachment->GetNinePatchBorder();
187 ImageAttachment& ImageActor::GetImageAttachment()
189 return *mImageAttachment;
192 RenderableAttachment& ImageActor::GetRenderableAttachment() const
194 DALI_ASSERT_DEBUG( mImageAttachment && "ImageAttachment missing from ImageActor" );
195 return *mImageAttachment;
198 ImageActor::ImageActor()
203 ImageActor::~ImageActor()
207 Vector3 ImageActor::GetNaturalSize() const
209 Vector2 naturalSize( CalculateNaturalSize() );
210 return Vector3( naturalSize.width, naturalSize.height, CalculateSizeZ( naturalSize ) );
213 Vector2 ImageActor::CalculateNaturalSize() const
215 // if no image then natural size is 0
216 Vector2 size( 0.0f, 0.0f );
218 ImagePtr image = mImageAttachment->GetImage();
221 if( IsPixelAreaSet() )
223 PixelArea area(GetPixelArea());
224 size.width = area.width;
225 size.height = area.height;
229 size = image->GetNaturalSize();
236 void ImageActor::OnStageConnectionInternal()
240 void ImageActor::OnStageDisconnectionInternal()
244 unsigned int ImageActor::GetDefaultPropertyCount() const
246 return RenderableActor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
249 void ImageActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
251 RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
253 indices.Reserve( indices.Size() + DEFAULT_PROPERTY_COUNT );
255 int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
256 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
258 indices.PushBack( index );
262 bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
264 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
266 return RenderableActor::IsDefaultPropertyWritable(index);
269 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
270 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
272 return DEFAULT_PROPERTY_DETAILS[ index ].writable;
278 bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
280 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
282 return RenderableActor::IsDefaultPropertyAnimatable( index );
285 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
286 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
288 return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
294 bool ImageActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
296 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
298 return RenderableActor::IsDefaultPropertyAConstraintInput( index );
301 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
302 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
304 return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
310 Property::Type ImageActor::GetDefaultPropertyType( Property::Index index ) const
312 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
314 return RenderableActor::GetDefaultPropertyType( index );
317 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
318 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
320 return DEFAULT_PROPERTY_DETAILS[index].type;
323 // index out-of-bounds
324 return Property::NONE;
327 const char* ImageActor::GetDefaultPropertyName( Property::Index index ) const
329 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
331 return RenderableActor::GetDefaultPropertyName(index);
334 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
335 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
337 return DEFAULT_PROPERTY_DETAILS[index].name;
340 // index out-of-bounds
344 Property::Index ImageActor::GetDefaultPropertyIndex(const std::string& name) const
346 Property::Index index = Property::INVALID_INDEX;
348 // Look for name in default properties
349 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
351 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
352 if( 0 == strcmp( name.c_str(), property->name ) ) // Don't want to convert rhs to string
354 index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
359 // If not found, check in base class
360 if( Property::INVALID_INDEX == index )
362 index = RenderableActor::GetDefaultPropertyIndex( name );
367 void ImageActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
369 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
371 RenderableActor::SetDefaultProperty( index, propertyValue );
377 case Dali::ImageActor::Property::PIXEL_AREA:
379 SetPixelArea(propertyValue.Get<Rect<int> >());
382 case Dali::ImageActor::Property::STYLE:
384 SetStyle( StyleEnum( propertyValue.Get<std::string>() ) );
387 case Dali::ImageActor::Property::BORDER:
389 SetNinePatchBorder( propertyValue.Get<Vector4>(), true /*in pixels*/ );
392 case Dali::ImageActor::Property::IMAGE:
394 Dali::Image img = Scripting::NewImage( propertyValue );
397 ImagePtr image( &GetImplementation(img) );
402 DALI_LOG_WARNING("Cannot create image from property value\n");
408 DALI_LOG_WARNING("Unknown property (%d)\n", index);
416 Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
419 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
421 ret = RenderableActor::GetDefaultProperty( index );
427 case Dali::ImageActor::Property::PIXEL_AREA:
429 Rect<int> r = GetPixelArea();
433 case Dali::ImageActor::Property::STYLE:
435 ret = StyleString( GetStyle() );
438 case Dali::ImageActor::Property::BORDER:
440 ret = GetNinePatchBorder();
443 case Dali::ImageActor::Property::IMAGE:
446 Scripting::CreatePropertyMap( Dali::Image( mImageAttachment->GetImage().Get() ), map );
447 ret = Property::Value( map );
452 DALI_LOG_WARNING( "Unknown property (%d)\n", index );
461 } // namespace Internal