(ImageView) Restore erroneously removed APIs & Fix SetImage behaviour
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / image-view / image-view-impl.cpp
index 7cfdb07..e47d1cd 100644 (file)
@@ -3,15 +3,17 @@
 // CLASS HEADER
 #include "image-view-impl.h"
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/image-view/image-view.h>
-
 // EXTERNAL INCLUDES
 #include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/object/type-registry-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
+#include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
+
 namespace Dali
 {
 
@@ -24,70 +26,6 @@ namespace Internal
 namespace
 {
 
-#define MAKE_SHADER(A)#A
-
-const char* VERTEX_SHADER = MAKE_SHADER(
-  attribute mediump vec2 aPosition;
-  attribute highp vec2 aTexCoord;
-  varying mediump vec2 vTexCoord;
-  uniform mediump mat4 uMvpMatrix;
-  uniform mediump vec3 uSize;
-
-  void main()
-  {
-    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
-    // TODO scale by the actor size when we are using RendererFactor generated renderers with a shared unit sized mesh: vertexPosition.xyz *= uSize;
-    vertexPosition = uMvpMatrix * vertexPosition;
-
-    vTexCoord = aTexCoord;
-    gl_Position = vertexPosition;
-  }
-);
-
-const char* FRAGMENT_SHADER = MAKE_SHADER(
-  varying mediump vec2 vTexCoord;
-  uniform sampler2D sTexture;
-  uniform lowp vec4 uColor;
-
-  void main()
-  {
-    gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
-  }
-);
-
-//TODO: remove when RendererFactory is implemented, so if there are multiple images that render as quads we only end up with one instance of geometry
-Geometry CreateGeometry( int width, int height )
-{
-  // Create vertices
-  const float halfWidth = width * .5f;
-  const float halfHeight = height * .5f;
-  struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; };
-    TexturedQuadVertex texturedQuadVertexData[4] = { { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f) },
-                                                     { Vector2( halfWidth, -halfHeight), Vector2(1.f, 0.f) },
-                                                     { Vector2(-halfWidth, halfHeight), Vector2(0.f, 1.f) },
-                                                     { Vector2( halfWidth, halfHeight), Vector2(1.f, 1.f) } };
-
-  Property::Map texturedQuadVertexFormat;
-  texturedQuadVertexFormat["aPosition"] = Property::VECTOR2;
-  texturedQuadVertexFormat["aTexCoord"] = Property::VECTOR2;
-  PropertyBuffer texturedQuadVertices = PropertyBuffer::New( texturedQuadVertexFormat, 4 );
-  texturedQuadVertices.SetData(texturedQuadVertexData);
-
-  // Create indices
-  unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 };
-  Property::Map indexFormat;
-  indexFormat["indices"] = Property::INTEGER;
-  PropertyBuffer indices = PropertyBuffer::New( indexFormat, 6 );
-  indices.SetData(indexData);
-
-  // Create the geometry object
-  Geometry texturedQuadGeometry = Geometry::New();
-  texturedQuadGeometry.AddVertexBuffer( texturedQuadVertices );
-  texturedQuadGeometry.SetIndexBuffer( indices );
-
-  return texturedQuadGeometry;
-}
-
 BaseHandle Create()
 {
   return Toolkit::ImageView::New();
@@ -95,7 +33,7 @@ BaseHandle Create()
 
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create );
-DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resource-url", STRING, RESOURCE_URL )
+DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE )
 DALI_TYPE_REGISTRATION_END()
 
 } // anonymous namespace
@@ -115,7 +53,7 @@ Toolkit::ImageView ImageView::New()
 {
   ImageView* impl = new ImageView();
 
-  Dali::Toolkit::ImageView handle = Dali::Toolkit::ImageView( *impl );
+  Toolkit::ImageView handle = Toolkit::ImageView( *impl );
 
   // Second-phase init of the implementation
   // This can only be done after the CustomActor connection has been made...
@@ -128,65 +66,100 @@ Toolkit::ImageView ImageView::New()
 
 void ImageView::SetImage( Image image )
 {
-  mImage = image;
+  if( ( mImage != image ) ||
+      ! mUrl.empty()      ||   // If we're changing from a URL type to an Image type
+      ! mPropertyMap.Empty() ) // If we're changing from a property map type to an Image type
+  {
+    mUrl.clear();
+    mPropertyMap.Clear();
+
+    mImage = image;
+
+    Actor self = Self();
+    Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, image );
+    mImageSize = image ? ImageDimensions( image.GetWidth(), image.GetHeight() ) : ImageDimensions( 0, 0 );
+
+    RelayoutRequest();
+  }
+}
+
+void ImageView::SetImage( Property::Map map )
+{
+  mUrl.clear();
+  mImage.Reset();
+  mPropertyMap = map;
+
+  Actor self = Self();
+  Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mPropertyMap );
 
-  ResourceImage resourceImage = ResourceImage::DownCast( mImage );
-  if( resourceImage )
+  int width = 0;
+  Property::Value* widthValue = mPropertyMap.Find( "width" );
+  if( widthValue )
   {
-    mImageUrl = resourceImage.GetUrl();
+    widthValue->Get( width );
   }
-  else
+
+  int height = 0;
+  Property::Value* heightValue = mPropertyMap.Find( "height" );
+  if( heightValue )
   {
-    mImageUrl.clear();
+    heightValue->Get( height );
   }
 
-  if( mImage )
+  mImageSize = ImageDimensions( width, height );
+
+  RelayoutRequest();
+}
+
+void ImageView::SetImage( const std::string& url, ImageDimensions size )
+{
+  if( ( mUrl != url ) ||
+      mImage          ||       // If we're changing from an Image type to a URL type
+      ! mPropertyMap.Empty() ) // If we're changing from a property map type to a URL type
   {
-    if( Self().OnStage() )
+    mImage.Reset();
+    mPropertyMap.Clear();
+
+    mUrl = url;
+
+    if( size.GetWidth() == 0u && size.GetHeight() == 0u )
     {
-      AttachImage();
+      mImageSize = ResourceImage::GetImageSize( mUrl );
     }
-    RelayoutRequest();
-  }
-  else
-  {
-    if( mRenderer )
+    else
     {
-      Self().RemoveRenderer( mRenderer );
+      mImageSize = size;
     }
-    mSampler.Reset();
-    mMaterial.Reset();
-    mMesh.Reset();
-    mRenderer.Reset();
-  }
-}
 
-Image ImageView::GetImage() const
-{
-  return mImage;
+    Actor self = Self();
+    Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mUrl, mImageSize );
+
+    RelayoutRequest();
+  }
 }
 
 Vector3 ImageView::GetNaturalSize()
 {
-  // if no image then use Control's natural size
   Vector3 size;
 
-  if( mImage )
+  size.x = mImageSize.GetWidth();
+  size.y = mImageSize.GetHeight();
+  size.z = std::min(size.x, size.y);
+
+  if( size.x > 0 && size.y > 0 )
   {
-    size.x = mImage.GetWidth();
-    size.y = mImage.GetHeight();
-    size.z = std::min(size.x, size.y);
+    return size;
   }
   else
   {
-    size = Control::GetNaturalSize();
+    // if no image then use Control's natural size
+    return Control::GetNaturalSize();
   }
-  return size;
 }
 
 float ImageView::GetHeightForWidth( float width )
 {
-  if( mImage )
+  if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
   {
     return GetHeightForWidthBase( width );
   }
@@ -198,7 +171,7 @@ float ImageView::GetHeightForWidth( float width )
 
 float ImageView::GetWidthForHeight( float height )
 {
-  if( mImage )
+  if( mImageSize.GetWidth() > 0 && mImageSize.GetHeight() > 0 )
   {
     return GetWidthForHeightBase( height );
   }
@@ -213,46 +186,29 @@ float ImageView::GetWidthForHeight( float height )
 // Private methods
 //
 
-void ImageView::AttachImage()
+void ImageView::OnStageConnection( int depth )
 {
-  if( !mRenderer )
-  {
-    Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
-    mMaterial = Material::New( shader );
+  Control::OnStageConnection( depth );
 
-    mSampler = Sampler::New( mImage, "sTexture" );
-    mMaterial.AddSampler( mSampler );
-
-    Vector3 size = Self().GetCurrentSize();
-    mMesh = CreateGeometry( size.width, size.height );
-    mRenderer = Renderer::New( mMesh, mMaterial );
-    Self().AddRenderer( mRenderer );
-  }
-  else
+  if( mRenderer )
   {
-    mSampler.SetImage( mImage );
+    CustomActor self = Self();
+    mRenderer.SetOnStage( self );
   }
 }
 
-void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container )
+void ImageView::OnStageDisconnection()
 {
-  Control::OnRelayout( size, container );
-
   if( mRenderer )
   {
-    mMesh = CreateGeometry( size.width, size.height );
-    mRenderer.SetGeometry( mMesh );
+    CustomActor self = Self();
+    mRenderer.SetOffStage( self );
   }
-}
 
-void ImageView::OnStageConnection( int depth )
-{
-  if( mImage )
-  {
-    AttachImage();
-  }
+  Control::OnStageDisconnection();
 }
 
+
 ///////////////////////////////////////////////////////////
 //
 // Properties
@@ -266,17 +222,23 @@ void ImageView::SetProperty( BaseObject* object, Property::Index index, const Pr
   {
     switch ( index )
     {
-      case Toolkit::ImageView::Property::RESOURCE_URL:
+      case Toolkit::ImageView::Property::IMAGE:
       {
         std::string imageUrl;
         if( value.Get( imageUrl ) )
         {
           ImageView& impl = GetImpl( imageView );
-          impl.mImageUrl = imageUrl;
+          impl.SetImage( imageUrl, ImageDimensions() );
+        }
 
-          Image image = ResourceImage::New( imageUrl );
-          impl.SetImage( image );
+        // if its not a string then get a Property::Map from the property if possible.
+        Property::Map map;
+        if( value.Get( map ) )
+        {
+          ImageView& impl = GetImpl( imageView );
+          impl.SetImage( map );
         }
+
         break;
       }
     }
@@ -293,9 +255,23 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop
   {
     switch ( propertyIndex )
     {
-      case Toolkit::ImageView::Property::RESOURCE_URL:
+      case Toolkit::ImageView::Property::IMAGE:
       {
-        value = GetImpl( imageview ).mImageUrl;
+        ImageView& impl = GetImpl( imageview );
+        if ( !impl.mUrl.empty() )
+        {
+          value = impl.mUrl;
+        }
+        else if( impl.mImage )
+        {
+          Property::Map map;
+          Scripting::CreatePropertyMap( impl.mImage, map );
+          value = map;
+        }
+        else if( !impl.mPropertyMap.Empty() )
+        {
+          value = impl.mPropertyMap;
+        }
         break;
       }
     }