(Control Renderers) Removed Renderer suffix from rendererType & created programming...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / renderers / npatch / npatch-renderer.cpp
index 8e509a9..e423ad2 100644 (file)
@@ -41,11 +41,11 @@ namespace Internal
 
 namespace
 {
-const char * const RENDERER_TYPE("renderer-type");
-const char * const RENDERER_TYPE_VALUE("n-patch-renderer");
+const char * const RENDERER_TYPE("rendererType");
+const char * const RENDERER_TYPE_VALUE("nPatch");
 
-const char * const IMAGE_URL_NAME("image-url");
-const char * const BORDER_ONLY("border-only");
+const char * const IMAGE_URL_NAME("imageUrl");
+const char * const BORDER_ONLY("borderOnly");
 
 std::string TEXTURE_UNIFORM_NAME = "sTexture";
 
@@ -217,12 +217,12 @@ NPatchRenderer::~NPatchRenderer()
 {
 }
 
-void NPatchRenderer::DoInitialize( const Property::Map& propertyMap )
+void NPatchRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
   Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
   if( imageURLValue )
   {
-    //Read the border-only property first since InitialiseFromImage relies on mBorderOnly to be properly set
+    //Read the borderOnly property first since InitialiseFromImage relies on mBorderOnly to be properly set
     Property::Value* borderOnlyValue = propertyMap.Find( BORDER_ONLY );
     if( borderOnlyValue )
     {
@@ -272,10 +272,9 @@ void NPatchRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
-void NPatchRenderer::InitializeRenderer( Renderer& renderer )
+Geometry NPatchRenderer::CreateGeometry()
 {
   Geometry geometry;
-  Shader shader;
   if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
   {
     if( !mBorderOnly )
@@ -296,48 +295,85 @@ void NPatchRenderer::InitializeRenderer( Renderer& renderer )
         mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry );
       }
     }
-
-    shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
-    if( !shader )
-    {
-      shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
-      mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
-    }
   }
   else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
   {
     Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1,  2 * mStretchPixelsY.Size() + 1 );
     geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize );
+  }
 
-    std::stringstream vertexShader;
-    vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
-                 << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
-                 << VERTEX_SHADER;
+  return geometry;
+}
 
-    shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
-  }
-  else
+Shader NPatchRenderer::CreateShader()
+{
+  Shader shader;
+  if( !mImpl->mCustomShader )
   {
-    DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() );
-    InitializeFromBrokenImage();
-  }
+    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+    {
+      shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
+      if( !shader )
+      {
+        shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
+        mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
+      }
+    }
+    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    {
+      std::stringstream vertexShader;
+      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+                   << VERTEX_SHADER;
 
-  if( !renderer )
-  {
-    Material material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
+      shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
+    }
   }
   else
   {
-    mImpl->mRenderer.SetGeometry( geometry );
-    Material material = mImpl->mRenderer.GetMaterial();
-    if( material )
+    const char* fragmentShader = FRAGMENT_SHADER;
+    Dali::Shader::ShaderHints hints = Dali::Shader::HINT_NONE;
+
+    if( !mImpl->mCustomShader->mFragmentShader.empty() )
+    {
+      fragmentShader = mImpl->mCustomShader->mFragmentShader.c_str();
+    }
+    hints = mImpl->mCustomShader->mHints;
+
+    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
     {
-      material.SetShader( shader );
+      shader = Shader::New( VERTEX_SHADER_3X3, fragmentShader, hints );
+    }
+    else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+    {
+      std::stringstream vertexShader;
+      vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
+                   << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+                   << VERTEX_SHADER;
+
+      shader = Shader::New( vertexShader.str(), fragmentShader, hints );
     }
   }
+
+  return shader;
+}
+
+void NPatchRenderer::InitializeRenderer()
+{
+  Geometry geometry = CreateGeometry();
+  Shader shader = CreateShader();
+
+  if( !geometry || !shader )
+  {
+    DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() );
+    InitializeFromBrokenImage();
+  }
+
+  Material material = Material::New( shader );
+  mImpl->mRenderer = Renderer::New( geometry, material );
 }
 
+
 void NPatchRenderer::DoSetOnStage( Actor& actor )
 {
   if( !mCroppedImage )
@@ -351,10 +387,11 @@ void NPatchRenderer::DoSetOnStage( Actor& actor )
     {
       InitializeFromImage( mImage );
     }
-
-    InitializeRenderer( mImpl->mRenderer );
   }
 
+  //initialize the renderer after initializing from the image since we need to know the grid size from the image before creating the geometry
+  InitializeRenderer();
+
   if( mCroppedImage )
   {
     ApplyImageToSampler();
@@ -364,6 +401,8 @@ void NPatchRenderer::DoSetOnStage( Actor& actor )
 void NPatchRenderer::DoSetOffStage( Actor& actor )
 {
   mCroppedImage.Reset();
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
 }
 
 void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const
@@ -381,8 +420,52 @@ void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( BORDER_ONLY, mBorderOnly );
 }
 
+void NPatchRenderer::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY )
+{
+  //check to see if the border style has changed
+
+  bool borderOnlyChanged = oldBorderOnly != mBorderOnly;
+  bool gridChanged = oldGridX != mStretchPixelsX.Size() || oldGridY != mStretchPixelsY.Size();
+
+  if( borderOnlyChanged || gridChanged )
+  {
+    Geometry geometry = CreateGeometry();
+    if( geometry )
+    {
+      mImpl->mRenderer.SetGeometry( geometry );
+    }
+    else
+    {
+      InitializeFromBrokenImage();
+    }
+  }
+
+  if( gridChanged )
+  {
+    Shader shader = CreateShader();
+    Material material;
+    if( shader )
+    {
+      material = mImpl->mRenderer.GetMaterial();
+      if( material )
+      {
+        material.SetShader( shader );
+      }
+    }
+
+    if( !material )
+    {
+      InitializeFromBrokenImage();
+    }
+  }
+}
+
 void NPatchRenderer::SetImage( const std::string& imageUrl, bool borderOnly )
 {
+  bool oldBorderOnly = mBorderOnly;
+  size_t oldGridX = mStretchPixelsX.Size();
+  size_t oldGridY = mStretchPixelsY.Size();
+
   mBorderOnly = borderOnly;
   mImage.Reset();
   if( mImageUrl == imageUrl )
@@ -391,17 +474,26 @@ void NPatchRenderer::SetImage( const std::string& imageUrl, bool borderOnly )
   }
 
   mImageUrl = imageUrl;
-  NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
-  InitializeFromImage( nPatch );
-
-  if( mCroppedImage && mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
-    ApplyImageToSampler();
+    NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
+    InitializeFromImage( nPatch );
+
+    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
+
+    if( mCroppedImage )
+    {
+      ApplyImageToSampler();
+    }
   }
 }
 
 void NPatchRenderer::SetImage( NinePatchImage image, bool borderOnly )
 {
+  bool oldBorderOnly = mBorderOnly;
+  size_t oldGridX = mStretchPixelsX.Size();
+  size_t oldGridY = mStretchPixelsY.Size();
+
   mBorderOnly = borderOnly;
   mImageUrl.empty();
   if( mImage == image )
@@ -410,11 +502,15 @@ void NPatchRenderer::SetImage( NinePatchImage image, bool borderOnly )
   }
 
   mImage = image;
-  InitializeFromImage( mImage );
-
-  if( mCroppedImage && mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
-    ApplyImageToSampler();
+    InitializeFromImage( mImage );
+    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
+
+    if( mCroppedImage )
+    {
+      ApplyImageToSampler();
+    }
   }
 }