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/internal/event/images/nine-patch-image-impl.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/internal/event/common/property-index-ranges.h>
25 #include <dali/internal/event/images/image-connector.h>
26 #include <dali/public-api/scripting/scripting.h>
31 const Property::Index ImageActor::PIXEL_AREA = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
32 const Property::Index ImageActor::STYLE = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 1;
33 const Property::Index ImageActor::BORDER = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 2;
34 const Property::Index ImageActor::IMAGE = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 3;
38 bool ImageActor::mFirstInstance = true;
39 Actor::DefaultPropertyLookup* ImageActor::mDefaultImageActorPropertyLookup = NULL;
46 return Dali::ImageActor::New();
49 TypeRegistration mType( typeid(Dali::ImageActor), typeid(Dali::RenderableActor), Create );
51 const std::string DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[] =
58 const int DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT = sizeof( DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES ) / sizeof( std::string );
60 const Property::Type DEFAULT_IMAGE_ACTOR_PROPERTY_TYPES[DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT] =
62 Property::RECTANGLE, // "pixel-area",
63 Property::STRING, // "style",
64 Property::VECTOR4, // "border",
65 Property::MAP, // "image",
68 ImageActor::Style StyleEnum(const std::string &s)
70 if(s == "STYLE_NINE_PATCH")
72 return Dali::ImageActor::STYLE_NINE_PATCH;
74 else // if(s == "QUAD")
76 return Dali::ImageActor::STYLE_QUAD;
80 std::string StyleString(const ImageActor::Style style)
82 if(style == Dali::ImageActor::STYLE_NINE_PATCH)
84 return "STYLE_NINE_PATCH";
86 else // if(s == "QUAD")
93 ImageActorPtr ImageActor::New()
95 ImageActorPtr actor( new ImageActor );
97 // Second-phase construction of base class
100 // Create the attachment
101 actor->mImageAttachment = ImageAttachment::New( *actor->mNode );
102 actor->Attach( *actor->mImageAttachment );
107 void ImageActor::OnInitialize()
109 if(ImageActor::mFirstInstance)
111 mDefaultImageActorPropertyLookup = new DefaultPropertyLookup();
112 const int start = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
113 for ( int i = 0; i < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT; ++i )
115 (*mDefaultImageActorPropertyLookup)[DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[i]] = i + start;
117 ImageActor::mFirstInstance = false;
121 void ImageActor::SetImage( ImagePtr& image )
123 ImagePtr currentImage = mImageAttachment->GetImage();
124 // early exit if it's the same image as we already have
125 if ( currentImage == image )
130 // NOTE! image might be pointing to NULL, which is fine as in that case app wants to just remove the image
131 ImagePtr newImage( image );
132 // if image is not NULL, check for 9 patch
135 // Automatically convert nine-patch images to cropped bitmap
136 NinePatchImage* ninePatchImage = NinePatchImage::DownCast( image.Get() );
139 newImage = ninePatchImage->CreateCroppedBitmapImage();
140 SetStyle( Dali::ImageActor::STYLE_NINE_PATCH );
141 SetNinePatchBorder( ninePatchImage->GetStretchBorders(), true );
144 // set the actual image (normal or 9 patch) and natural size based on that
145 mImageAttachment->SetImage( newImage );
149 ImagePtr ImageActor::GetImage()
151 return mImageAttachment->GetImage();
154 void ImageActor::SetToNaturalSize()
156 mUsingNaturalSize = true;
161 void ImageActor::SetPixelArea( const PixelArea& pixelArea )
163 mImageAttachment->SetPixelArea( pixelArea );
168 const ImageActor::PixelArea& ImageActor::GetPixelArea() const
170 return mImageAttachment->GetPixelArea();
173 bool ImageActor::IsPixelAreaSet() const
175 return mImageAttachment->IsPixelAreaSet();
178 void ImageActor::ClearPixelArea()
180 mImageAttachment->ClearPixelArea();
182 if( mUsingNaturalSize )
184 ImagePtr image = mImageAttachment->GetImage();
187 mInternalSetSize = true;
188 SetSize( image->GetNaturalSize() );
189 mInternalSetSize = false;
194 void ImageActor::SetStyle( Style style )
196 mImageAttachment->SetStyle( style );
199 ImageActor::Style ImageActor::GetStyle() const
201 return mImageAttachment->GetStyle();
204 void ImageActor::SetNinePatchBorder( const Vector4& border, bool inPixels )
206 mImageAttachment->SetNinePatchBorder( border, inPixels );
209 Vector4 ImageActor::GetNinePatchBorder() const
211 return mImageAttachment->GetNinePatchBorder();
214 ImageAttachment& ImageActor::GetImageAttachment()
216 return *mImageAttachment;
219 RenderableAttachment& ImageActor::GetRenderableAttachment() const
221 DALI_ASSERT_DEBUG( mImageAttachment && "ImageAttachment missing from ImageActor" );
222 return *mImageAttachment;
225 ImageActor::ImageActor()
227 mUsingNaturalSize(true),
228 mInternalSetSize(false)
232 ImageActor::~ImageActor()
236 void ImageActor::SetNaturalSize()
238 if( mUsingNaturalSize )
240 mInternalSetSize = true;
241 SetSize( CalculateNaturalSize() );
242 mInternalSetSize = false;
246 Vector3 ImageActor::GetNaturalSize() const
248 Vector2 naturalSize( CalculateNaturalSize() );
249 return Vector3( naturalSize.width, naturalSize.height, CalculateSizeZ( naturalSize ) );
252 Vector2 ImageActor::CalculateNaturalSize() const
254 // if no image then natural size is 0
255 Vector2 size( 0.0f, 0.0f );
257 ImagePtr image = mImageAttachment->GetImage();
260 if( IsPixelAreaSet() )
262 PixelArea area(GetPixelArea());
263 size.width = area.width;
264 size.height = area.height;
268 size = image->GetNaturalSize();
275 void ImageActor::OnSizeSet( const Vector3& targetSize )
277 if( !mInternalSetSize )
279 mUsingNaturalSize = false;
283 void ImageActor::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
285 mUsingNaturalSize = false;
288 void ImageActor::OnStageConnectionInternal()
292 void ImageActor::OnStageDisconnectionInternal()
296 unsigned int ImageActor::GetDefaultPropertyCount() const
298 return RenderableActor::GetDefaultPropertyCount() + DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT;
301 void ImageActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
303 RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
305 indices.reserve( indices.size() + DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT );
307 int index = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
308 for ( int i = 0; i < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT; ++i, ++index )
310 indices.push_back( index );
314 bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
316 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
318 return RenderableActor::IsDefaultPropertyWritable(index);
326 bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
328 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
330 return RenderableActor::IsDefaultPropertyAnimatable(index);
338 bool ImageActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
340 if( index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT )
342 return RenderableActor::IsDefaultPropertyAConstraintInput(index);
344 return true; // Our properties can be used as input to constraints.
347 Property::Type ImageActor::GetDefaultPropertyType( Property::Index index ) const
349 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
351 return RenderableActor::GetDefaultPropertyType(index);
355 index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
357 if ( ( index >= 0 ) && ( index < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT ) )
359 return DEFAULT_IMAGE_ACTOR_PROPERTY_TYPES[index];
363 // index out-of-bounds
364 return Property::NONE;
369 const std::string& ImageActor::GetDefaultPropertyName( Property::Index index ) const
371 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
373 return RenderableActor::GetDefaultPropertyName(index);
377 index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
379 if ( ( index >= 0 ) && ( index < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT ) )
381 return DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[index];
385 // index out-of-bounds
386 static const std::string INVALID_PROPERTY_NAME;
387 return INVALID_PROPERTY_NAME;
392 Property::Index ImageActor::GetDefaultPropertyIndex(const std::string& name) const
394 Property::Index index = Property::INVALID_INDEX;
396 DALI_ASSERT_DEBUG( NULL != mDefaultImageActorPropertyLookup );
398 // Look for name in current class' default properties
399 DefaultPropertyLookup::const_iterator result = mDefaultImageActorPropertyLookup->find( name );
400 if ( mDefaultImageActorPropertyLookup->end() != result )
402 index = result->second;
406 // If not found, check in base class
407 index = RenderableActor::GetDefaultPropertyIndex( name );
413 void ImageActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
415 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
417 RenderableActor::SetDefaultProperty(index, propertyValue);
423 case Dali::ImageActor::PIXEL_AREA:
425 SetPixelArea(propertyValue.Get<Rect<int> >());
428 case Dali::ImageActor::STYLE:
430 SetStyle(StyleEnum(propertyValue.Get<std::string>()));
433 case Dali::ImageActor::BORDER:
435 SetNinePatchBorder( propertyValue.Get<Vector4>(), true /*in pixels*/ );
438 case Dali::ImageActor::IMAGE:
440 Dali::Image img = Scripting::NewImage( propertyValue );
443 ImagePtr image( &GetImplementation(img) );
448 DALI_LOG_WARNING("Cannot create image from property value\n");
454 DALI_LOG_WARNING("Unknown property (%d)\n", index);
462 Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
465 if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
467 ret = RenderableActor::GetDefaultProperty(index);
473 case Dali::ImageActor::PIXEL_AREA:
475 Rect<int> r = GetPixelArea();
479 case Dali::ImageActor::STYLE:
481 ret = StyleString(GetStyle());
484 case Dali::ImageActor::BORDER:
486 ret = GetNinePatchBorder();
489 case Dali::ImageActor::IMAGE:
492 Scripting::CreatePropertyMap( Dali::Image( mImageAttachment->GetImage().Get() ), map );
493 ret = Property::Value( map );
498 DALI_LOG_WARNING("Unknown property (%d)\n", index);
507 } // namespace Internal