Merge "Fix the cursor position when retrieving the selected text." into devel/master
authorPaul Wisbey <p.wisbey@samsung.com>
Fri, 2 Oct 2015 10:47:18 +0000 (03:47 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 2 Oct 2015 10:47:18 +0000 (03:47 -0700)
33 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp
dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp
dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h
dali-toolkit/devel-api/shader-effects/dissolve-effect.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/renderers/border/border-renderer.cpp
dali-toolkit/internal/controls/renderers/border/border-renderer.h
dali-toolkit/internal/controls/renderers/color/color-renderer.cpp
dali-toolkit/internal/controls/renderers/color/color-renderer.h
dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h
dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp
dali-toolkit/internal/controls/renderers/control-renderer-impl.h
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
dali-toolkit/internal/controls/renderers/image/image-renderer.h
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h
dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp
dali-toolkit/internal/controls/renderers/renderer-factory-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/control.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index f77f903..4bfc808 100644 (file)
@@ -382,7 +382,20 @@ int UtcDaliControlBackgroundColor(void)
   DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
 
   control.SetBackgroundColor( Color::RED );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION );
+
+  Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
+  Property::Map* resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get<std::string>() == "color-renderer" );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" ) );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get<Vector4>() == Color::RED );
+
+  control.SetBackgroundColor( Color::YELLOW );
+
+  propValue = control.GetProperty( Control::Property::BACKGROUND );
+  resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" ) );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get<Vector4>() == Color::YELLOW );
 
   END_TEST;
 }
@@ -396,21 +409,21 @@ int UtcDaliControlBackgroundImage(void)
 
   Image image = ResourceImage::New("TestImage");
   control.SetBackgroundImage( image );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
-
-  control.SetBackgroundColor( Color::GREEN );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::GREEN, TEST_LOCATION );
-
-  control.SetBackgroundColor( Color::RED );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION );
 
-  control.ClearBackground();
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
+  Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
+  Property::Map* resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get<std::string>() == "image-renderer" );
+  DALI_TEST_CHECK( resultMap->Find( "image-url" ) );
+  DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get<std::string>() == "TestImage" );
 
-  control.SetBackgroundColor( Color::YELLOW );
+  image = ResourceImage::New("TestImage2");
   control.SetBackgroundImage( image );
-  // The background can be either an image or a color, not both
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
+
+  propValue = control.GetProperty( Control::Property::BACKGROUND );
+  resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( "image-url" ) );
+  DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get<std::string>() == "TestImage2" );
 
   END_TEST;
 }
@@ -420,34 +433,42 @@ int UtcDaliControlBackgroundProperties(void)
   ToolkitTestApplication application;
   Control control = Control::New();
 
-  DALI_TEST_CHECK( control.GetChildCount() == 0 );
   DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
   DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() );
 
   Property::Map colorMap;
   colorMap["color"] = Color::RED;
   control.SetProperty( Control::Property::BACKGROUND, colorMap );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION );
-  DALI_TEST_CHECK( control.GetChildCount() > 0 );
   Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
   Property::Map* resultMap = propValue.GetMap();
-  DALI_TEST_CHECK( resultMap->Find( "color" ) );
-  DALI_TEST_CHECK( resultMap->Find( "color" )->Get<Vector4>() == Color::RED );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get<std::string>() == "color-renderer" );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" ) );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get<Vector4>() == Color::RED );
 
   Property::Map imageMap;
   imageMap[ "filename" ] = "TestImage";
   control.SetProperty( Control::Property::BACKGROUND, imageMap );
-  DALI_TEST_CHECK( control.GetChildCount() > 0 );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
   propValue = control.GetProperty( Control::Property::BACKGROUND );
   resultMap = propValue.GetMap();
-  DALI_TEST_CHECK( resultMap->Find( "filename" ) );
-  DALI_TEST_CHECK( resultMap->Find( "filename" )->Get< std::string>() == "TestImage" );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get<std::string>() == "image-renderer" );
+  DALI_TEST_CHECK( resultMap->Find( "image-url" ) );
+  DALI_TEST_CHECK( resultMap->Find( "image-url" )->Get<std::string>() == "TestImage" );
+
+  Property::Map rendererMap;
+  rendererMap["renderer-type"] = "color-renderer";
+  rendererMap["blend-color"] = Color::CYAN;
+  control.SetProperty( Control::Property::BACKGROUND, rendererMap );
+  propValue = control.GetProperty( Control::Property::BACKGROUND );
+  resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" ) );
+  DALI_TEST_CHECK( resultMap->Find( "renderer-type" )->Get<std::string>() == "color-renderer" );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" ) );
+  DALI_TEST_CHECK( resultMap->Find( "blend-color" )->Get<Vector4>() == Color::CYAN );
 
   Property::Map emptyMap;
   control.SetProperty( Control::Property::BACKGROUND, emptyMap );
-  DALI_TEST_CHECK( control.GetChildCount() == 0 );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
   DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() );
 
   END_TEST;
index abe2fb6..e0b50d1 100644 (file)
@@ -74,7 +74,7 @@ int UtcDaliControlRendererCopyAndAssignment(void)
   END_TEST;
 }
 
-int UtcDaliControlRendererSetDepthIndex(void)
+int UtcDaliControlRendererSetGetDepthIndex(void)
 {
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliControlRendererSetDepthIndex" );
@@ -93,9 +93,75 @@ int UtcDaliControlRendererSetDepthIndex(void)
   controlRenderer.SetOnStage( actor );
 
   DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), 1.f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controlRenderer.GetDepthIndex(), 1.f, TEST_LOCATION );
 
   controlRenderer.SetDepthIndex( -1.f );
   DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), -1.f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controlRenderer.GetDepthIndex(), -1.f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlRendererSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliControlRendererGetNaturalSize" );
+
+  RendererFactory factory = RendererFactory::Get();
+  Vector2 rendererSize( 20.f, 30.f );
+  Vector2 naturalSize;
+
+  // color renderer
+  ControlRenderer colorRenderer = factory.GetControlRenderer( Color::MAGENTA );
+  colorRenderer.SetSize( rendererSize );
+  DALI_TEST_EQUALS( colorRenderer.GetSize(), rendererSize, TEST_LOCATION );
+  colorRenderer.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION );
+
+  // image renderer
+  Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
+  ControlRenderer imageRenderer = factory.GetControlRenderer( image );
+  imageRenderer.SetSize( rendererSize );
+  DALI_TEST_EQUALS( imageRenderer.GetSize(), rendererSize, TEST_LOCATION );
+  imageRenderer.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 200.f), TEST_LOCATION );
+
+  // n patch renderer
+  TestPlatformAbstraction& platform = application.GetPlatform();
+  Vector2 testSize(80.f, 160.f);
+  platform.SetClosestImageSize(testSize);
+  image = ResourceImage::New(TEST_NPATCH_FILE_NAME);
+  ControlRenderer nPatchRenderer = factory.GetControlRenderer( image );
+  nPatchRenderer.SetSize( rendererSize );
+  DALI_TEST_EQUALS( nPatchRenderer.GetSize(), rendererSize, TEST_LOCATION );
+  nPatchRenderer.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, testSize, TEST_LOCATION );
+
+  // border renderer
+  float borderSize = 5.f;
+  ControlRenderer borderRenderer = factory.GetControlRenderer( borderSize, Color::RED );
+  borderRenderer.SetSize( rendererSize );
+  DALI_TEST_EQUALS( borderRenderer.GetSize(), rendererSize, TEST_LOCATION );
+  borderRenderer.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION );
+
+  // gradient renderer
+  Property::Map propertyMap;
+  propertyMap.Insert("renderer-type", "gradient-renderer");
+  Vector2 start(-1.f, -1.f);
+  Vector2 end(1.f, 1.f);
+  propertyMap.Insert("gradient-start-position", start);
+  propertyMap.Insert("gradient-end-position", end);
+  propertyMap.Insert("gradient-stop-offset", Vector2(0.f, 1.f));
+  Property::Array stopColors;
+  stopColors.PushBack( Color::RED );
+  stopColors.PushBack( Color::GREEN );
+  propertyMap.Insert("gradient-stop-color", stopColors);
+  ControlRenderer gradientRenderer = factory.GetControlRenderer(propertyMap);
+  gradientRenderer.SetSize( rendererSize );
+  DALI_TEST_EQUALS( gradientRenderer.GetSize(), rendererSize, TEST_LOCATION );
+  gradientRenderer.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION );
 
   END_TEST;
 }
@@ -132,6 +198,47 @@ int UtcDaliControlRendererSetOnOffStage(void)
   END_TEST;
 }
 
+int UtcDaliControlRendererRemoveAndReset(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "intUtcDaliControlRendererRemoveAndReset" );
+
+  RendererFactory factory = RendererFactory::Get();
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+
+  ControlRenderer imageRenderer;
+  // test calling RemoveAndReset with an empty handle
+  try
+  {
+    imageRenderer.RemoveAndReset( actor );
+    tet_result(TET_PASS);
+  }
+  catch (DaliException& exception)
+  {
+    tet_result(TET_FAIL);
+  }
+
+  Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
+  imageRenderer = factory.GetControlRenderer(image);
+  DALI_TEST_CHECK( imageRenderer );
+
+  imageRenderer.SetOnStage( actor );
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  imageRenderer.RemoveAndReset( actor );
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); // renderer is removed from actor
+  DALI_TEST_CHECK( !imageRenderer ); // control renderer is reset
+
+  END_TEST;
+}
+
 int UtcDaliControlRendererGetPropertyMap1(void)
 {
   ToolkitTestApplication application;
index cc5195d..33dfee4 100644 (file)
@@ -123,24 +123,69 @@ int UtcDaliCreateDisplacementEffectFixed(void)
   END_TEST;
 }
 
-int UtcDaliCreateDissolveEffect(void)
+int UtcDaliCreateDissolveEffect( bool highPrecision )
 {
   ToolkitTestApplication application;
 
-  ShaderEffect effect = Toolkit::CreateDissolveEffect();
-  DALI_TEST_CHECK( effect );
+  Property::Map effect = Toolkit::CreateDissolveEffect( highPrecision );
+  DALI_TEST_CHECK( !effect.Empty() );
+
+  Property::Value* customShaderValue = effect.Find( "shader" );
+  DALI_TEST_CHECK( customShaderValue );
+
+  Property::Map customShader;
+  DALI_TEST_CHECK( customShaderValue->Get( customShader ) );
+
+  Property::Value* vertexShaderValue = customShader.Find( "vertex-shader" );
+  DALI_TEST_CHECK( vertexShaderValue );
+
+  std::string vertexShader;
+  DALI_TEST_CHECK( vertexShaderValue->Get( vertexShader ) );
+  DALI_TEST_CHECK( !vertexShader.empty() );
+
+  Property::Value* fragmentShaderValue = customShader.Find( "fragment-shader" );
+  DALI_TEST_CHECK( fragmentShaderValue );
+
+  std::string fragmentShader;
+  DALI_TEST_CHECK( fragmentShaderValue->Get( fragmentShader ) );
+  DALI_TEST_CHECK( !fragmentShader.empty() );
+
+  Property::Value* gridXValue = customShader.Find( "subdivide-grid-x" );
+  DALI_TEST_CHECK( gridXValue );
+
+  int gridX = 0;
+  DALI_TEST_CHECK( gridXValue->Get( gridX ) );
+  DALI_TEST_CHECK( gridX > 1 );
+
+  Property::Value* gridYValue = customShader.Find( "subdivide-grid-y" );
+  DALI_TEST_CHECK( gridYValue );
+
+  int gridY = 0;
+  DALI_TEST_CHECK( gridYValue->Get( gridY ) );
+  DALI_TEST_CHECK( gridY > 1 );
+
+  Property::Value* hintsValue = customShader.Find( "hints" );
+  DALI_TEST_CHECK( hintsValue );
+
+  std::string hints;
+  DALI_TEST_CHECK( hintsValue->Get( hints ) );
+  DALI_TEST_CHECK( hints == "output-is-transparent" );
+
+  Actor actor = Actor::New();
+  Toolkit::DissolveEffectSetCentralLine( actor, Vector2::ONE, Vector2::ONE, 0.0f );
+  DALI_TEST_CHECK( actor.GetPropertyIndex( "uPercentage" ) != Property::INVALID_INDEX );
 
   END_TEST;
 }
 
-int UtcDaliCreateDissolveEffectMediumPrecision(void)
+int UtcDaliCreateDissolveEffectHighPrecision(void)
 {
-  ToolkitTestApplication application;
-
-  ShaderEffect effect = Toolkit::CreateDissolveEffect(false);
-  DALI_TEST_CHECK( effect );
+  return UtcDaliCreateDissolveEffect(true);
+}
 
-  END_TEST;
+int UtcDaliCreateDissolveEffectMediumPrecision(void)
+{
+  return UtcDaliCreateDissolveEffect(false);
 }
 
 int UtcDaliCreateDissolveLocalEffect(void)
index 30e8b58..c036334 100644 (file)
@@ -56,11 +56,26 @@ void ControlRenderer::SetSize( const Vector2& size )
   GetImplementation( *this ).SetSize(size);
 }
 
+const Vector2& ControlRenderer::GetSize() const
+{
+  return GetImplementation( *this ).GetSize();
+}
+
+void ControlRenderer::GetNaturalSize(Vector2& naturalSize ) const
+{
+  GetImplementation( *this ).GetNaturalSize( naturalSize );
+}
+
 void ControlRenderer::SetDepthIndex( float index )
 {
   GetImplementation( *this ).SetDepthIndex(index);
 }
 
+float ControlRenderer::GetDepthIndex() const
+{
+  return GetImplementation( *this ).GetDepthIndex();
+}
+
 void ControlRenderer::SetOnStage( Actor& actor )
 {
   GetImplementation( *this ).SetOnStage(actor);
@@ -71,6 +86,15 @@ void ControlRenderer::SetOffStage( Actor& actor )
   GetImplementation( *this ).SetOffStage(actor);
 }
 
+void ControlRenderer::RemoveAndReset( Actor& actor )
+{
+  if( actor && *this )
+  {
+    SetOffStage( actor );
+  }
+  Reset();
+}
+
 void ControlRenderer::CreatePropertyMap( Property::Map& map ) const
 {
   GetImplementation( *this ).CreatePropertyMap( map );
index 3a44603..fe26fab 100644 (file)
@@ -78,6 +78,22 @@ public:
   void SetSize( const Vector2& size );
 
   /**
+   * @brief Get the size of the painting area.
+   *
+   * @return The size of the renderer's painting area.
+   */
+  const Vector2& GetSize() const;
+
+  /**
+   * @brief Return the natural size of the renderer.
+   *
+   * Deriving classes stipulate the natural size and by default a renderer has a ZERO natural size.
+   *
+   * @param[out] naturalSize The renderer's natural size
+   */
+  void GetNaturalSize( Vector2& naturalSize ) const;
+
+  /**
    * @brief Set the depth index of this renderer.
    *
    * Depth-index controls draw-order for overlapping renderers.
@@ -88,6 +104,13 @@ public:
   void SetDepthIndex( float index );
 
   /**
+   * @brief Get the depth index of this renderer
+   *
+   * @return The depth index of this renderer.
+   */
+  float GetDepthIndex() const;
+
+  /**
    * @brief Renderer only exists when control is on stage.
    *
    * This function should be called when the control put on stage.
@@ -106,6 +129,15 @@ public:
   void SetOffStage( Actor& actor );
 
   /**
+   * @brief Remove the renderer from actor and reset the control renderer self.
+   *
+   * This function can be called with an empty handle. If the control renderer is empty, do nothing.
+   *
+   * @param[in] actor The actor to be set off stage.
+   */
+  void RemoveAndReset( Actor& actor );
+
+  /**
    * @brief Create the property map representing this renderer.
    *
    * @param[out] map The renderer property map.
index ce70893..3f7ef6c 100644 (file)
@@ -122,6 +122,11 @@ bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const std::strin
   return GetImplementation( *this ).ResetRenderer( renderer, url );
 }
 
+bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap )
+{
+  return GetImplementation( *this ).ResetRenderer( renderer, propertyMap );
+}
+
 } // namespace Toolkit
 
 } // namespace Dali
index c4ac6a4..13242f4 100644 (file)
@@ -163,6 +163,19 @@ public:
    */
   bool ResetRenderer( ControlRenderer& renderer, const std::string& url );
 
+
+  /**
+   * @brief Request the current control renderer from the property map, merging the property map with the renderer
+   *
+   * if the current renderer is capable of merging with the property map the reset the renderer with the merged properties
+   * else the renderer would be a handle to a newly created internal renderer.
+   *
+   * @param[in] propertyMap The map contains the properties required by the control renderer
+   *            Depends on the content of the map, different kind of renderer would be returned.
+   * @return Whether a new internal control renderer is created.
+   */
+  bool ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap );
+
 private:
 
   explicit DALI_INTERNAL RendererFactory(Internal::RendererFactory *impl);
index 4aee8cc..95cccc8 100644 (file)
  */
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/shader-effects/shader-effect.h>
+#include <string.h>
+#include <dali/devel-api/rendering/shader.h>
+
+namespace
+{
+  template < typename T>
+  void SafeSetCustomProperty( Dali::Actor& actor, const std::string& name, const T& value )
+  {
+    Dali::Property::Index index = actor.GetPropertyIndex( name );
+    if ( Dali::Property::INVALID_INDEX == index )
+    {
+      index = actor.RegisterProperty( name, value );
+    }
+    else
+    {
+      actor.SetProperty( index, value );
+    }
+  }
+
+  template < typename T>
+  void SafeSetCustomProperty( Dali::Actor& actor, const std::string& name, const T& value, Dali::Property::AccessMode accessMode )
+  {
+    Dali::Property::Index index = actor.GetPropertyIndex( name );
+    if ( Dali::Property::INVALID_INDEX == index )
+    {
+      index = actor.RegisterProperty( name, value, accessMode );
+    }
+    else
+    {
+      actor.SetProperty( index, value );
+    }
+  }
+
+};
 
 namespace Dali
 {
@@ -34,11 +67,11 @@ namespace Toolkit
  * As we use the texture coordinate as pixel position to calculate random offset,
  * the line should passing through rectangle {(0,0),(0,1),(1,0),(1,1)},
  * so make the position parameter with two component values between 0.0 to 1.0
- * @param[in] dissolveEffect The shader effect
  * @param[in] position The point ( locates within rectangle {(0,0),(0,1),(1,0),(1,1)} ) passed through by the central line
  * @param[in] displacement The direction of the central line
+ * @param[in] initialProgress, the normalised initial progress of the shader
  */
-inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Vector2& position, const Vector2& displacement )
+inline void DissolveEffectSetCentralLine( Actor& actor, const Vector2& position, const Vector2& displacement, float initialProgress )
 {
   // the line passes through 'position' and has the direction of 'displacement'
     float coefA, coefB, coefC; //line equation: Ax+By+C=0;
@@ -102,10 +135,11 @@ inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Ve
     rotation = Vector2(-displacement.x, displacement.y);
     rotation.Normalize();
 
-    dissolveEffect.SetUniform( "uSaddleParam", saddleParam );
-    dissolveEffect.SetUniform( "uTranslation", translation );
-    dissolveEffect.SetUniform( "uRotation", rotation );
-    dissolveEffect.SetUniform( "uToNext", toNext );
+    SafeSetCustomProperty( actor, "uSaddleParam", saddleParam );
+    SafeSetCustomProperty( actor, "uTranslation", translation );
+    SafeSetCustomProperty( actor, "uRotation", rotation );
+    SafeSetCustomProperty( actor, "uToNext", toNext );
+    SafeSetCustomProperty( actor, "uPercentage", initialProgress, Dali::Property::ANIMATABLE );
 }
 /**
  * @brief Create a new Dissolve effect
@@ -119,69 +153,108 @@ inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Ve
  *  @return A handle to a newly allocated ShaderEffect
  */
 
-inline ShaderEffect CreateDissolveEffect(bool useHighPrecision = true)
+inline Property::Map CreateDissolveEffect( bool useHighPrecision = true )
 {
-  std::string prefixHighPrecision( "precision highp float;\n");
-    std::string prefixMediumPrecision( "precision mediump float;\n" );
-    std::string vertexShader(
-      "uniform float uPercentage;\n"
-      "uniform vec3 uSaddleParam;\n"
-      "uniform vec2 uTranslation;\n"
-      "uniform vec2 uRotation; \n"
-      "uniform float uToNext;\n"
-      "varying float vPercentage;\n"
-      "void main()\n"
-      "{\n"
-        "gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n"
-        "vTexCoord = aTexCoord;\n"
-        //Calculate the distortion value given the dissolve central line
-        "vec2 texCoor = vec2( (aTexCoord.s - sTextureRect.s ) / (sTextureRect.p - sTextureRect.s), (aTexCoord.t- sTextureRect.t)/(sTextureRect.q - sTextureRect.t) ); \n"
-        "vec2 value = texCoor + uTranslation; \n"
-        "mat2 rotateMatrix = mat2( uRotation.s, uRotation.t, -uRotation.t, uRotation.s ); \n"
-        "value = rotateMatrix * value; \n"
-        "if(uToNext == 1.0)  \n"
-        "  value.s = uSaddleParam[2] + value.s; \n"
-        "float delay = value.t*value.t / uSaddleParam[0] - value.s*value.s/uSaddleParam[1];\n"
-        "vPercentage = clamp( uPercentage*2.0 - 0.5*sin(delay*1.571) - 0.5, 0.0, 1.0 ); \n"
-      "}\n");
-    std::string fragmentShader(
-      "varying float vPercentage;\n"
-      "float rand(vec2 co) \n"
-      "{\n"
-      "  return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n"
-      "}\n"
-      "void main()\n"
-      "{\n"
-        //Calculate the randomness
-        "float offsetS = rand( vTexCoord * vPercentage ) * (sTextureRect.p - sTextureRect.s) - vTexCoord.s  + sTextureRect.s; \n"
-        "float offsetT = rand( vec2(vTexCoord.t*vPercentage, vTexCoord.s * vPercentage) ) * (sTextureRect.q - sTextureRect.t) - vTexCoord.t + sTextureRect.t; \n"
-        "vec2 lookupCoord = vTexCoord + vec2(offsetS, offsetT) * vPercentage; \n"
-        "gl_FragColor = texture2D( sTexture, lookupCoord ) * uColor; \n"
-        "gl_FragColor.a *= 1.0 - vPercentage; \n"
-      "}" );
-
-    // Create the implementation, temporarily owned on stack,
-    Dali::ShaderEffect shaderEffect;
-    if( useHighPrecision )
-    {
-      shaderEffect =  Dali::ShaderEffect::New(
-          prefixHighPrecision+vertexShader, prefixHighPrecision + fragmentShader,
-          ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_BLENDING ) );
-    }
-    else
-    {
-      shaderEffect =  Dali::ShaderEffect::New(
-          prefixMediumPrecision+vertexShader, prefixMediumPrecision + fragmentShader,
-          ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_BLENDING ) );
-    }
+  const char* prefixHighPrecision( "precision highp float;\n");
+  const char* prefixMediumPrecision( "precision mediump float;\n" );
+
+  const char* vertexShader( DALI_COMPOSE_SHADER(
+    attribute mediump vec2 aPosition;\n
+    \n
+    uniform mediump mat4 uMvpMatrix;\n
+    uniform vec3 uSize;\n
+    uniform vec4 uTextureRect;
+    \n
+    uniform float uPercentage;\n
+    uniform vec3 uSaddleParam;\n
+    uniform vec2 uTranslation;\n
+    uniform vec2 uRotation; \n
+    uniform float uToNext;\n
+    \n
+    varying float vPercentage;\n
+    varying vec2 vTexCoord;\n
+
+    void main()\n
+    {\n
+      mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+      vertexPosition.xyz *= uSize;\n
+      vertexPosition = uMvpMatrix * vertexPosition;\n
+      gl_Position = vertexPosition;\n
+
+      vec2 texCoord = aPosition + vec2(0.5);
+      vTexCoord = texCoord;\n
+      //Calculate the distortion value given the dissolve central line
+      vec2 value = texCoord + uTranslation; \n
+      mat2 rotateMatrix = mat2( uRotation.s, uRotation.t, -uRotation.t, uRotation.s ); \n
+      value = rotateMatrix * value; \n
+      if(uToNext == 1.0)  \n
+        value.s = uSaddleParam[2] + value.s; \n
+      float delay = value.t*value.t / uSaddleParam[0] - value.s*value.s/uSaddleParam[1];\n
+      vPercentage = clamp( uPercentage*2.0 - 0.5*sin(delay*1.571) - 0.5, 0.0, 1.0 ); \n
+    })
+  );
+
+  const char* fragmentShader( DALI_COMPOSE_SHADER(
+    varying float vPercentage;\n
+    varying mediump vec2 vTexCoord;\n
+    \n
+    uniform sampler2D sTexture;\n
+    uniform lowp vec4 uColor;\n
+    uniform vec4 uTextureRect;
+    \n
+    float rand(vec2 co) \n
+    {\n
+      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n
+    }\n
+    \n
+    void main()\n
+    {\n
+
+      //Calculate the randomness
+      float offsetS = rand( vTexCoord * vPercentage ) - vTexCoord.s; \n
+      float offsetT = rand( vec2(vTexCoord.t*vPercentage, vTexCoord.s * vPercentage) ) - vTexCoord.t; \n
+      vec2 lookupCoord = vTexCoord + vec2(offsetS, offsetT) * vPercentage; \n
+      gl_FragColor = texture2D( sTexture, lookupCoord ) * uColor; \n
+      gl_FragColor.a *= 1.0 - vPercentage; \n
+    } )
+  );
+
+  Property::Map map;
+
+  Property::Map customShader;
+
+  std::string vertexShaderString;
+  std::string fragmentShaderString;
+  if( useHighPrecision )
+  {
+    vertexShaderString.reserve(strlen( prefixHighPrecision ) + strlen( vertexShader ));
+    vertexShaderString.append( prefixHighPrecision );
+
+    fragmentShaderString.reserve(strlen( prefixHighPrecision ) + strlen( fragmentShader ));
+    fragmentShaderString.append( prefixHighPrecision );
+  }
+  else
+  {
+    vertexShaderString.reserve(strlen( prefixMediumPrecision ) + strlen( vertexShader ));
+    vertexShaderString.append( prefixMediumPrecision );
+
+    fragmentShaderString.reserve(strlen( prefixMediumPrecision ) + strlen( fragmentShader ));
+    fragmentShaderString.append( prefixMediumPrecision );
+  }
+
+  vertexShaderString.append( vertexShader );
+  fragmentShaderString.append( fragmentShader );
 
-    shaderEffect.SetUniform( "uPercentage", 0.0f );
-    shaderEffect.SetProperty( ShaderEffect::Property::GRID_DENSITY, Dali::Property::Value(50.0f) );
+  customShader[ "vertex-shader" ] = vertexShaderString;
+  customShader[ "fragment-shader" ] = fragmentShaderString;
 
-    DissolveEffectSetCentralLine( shaderEffect, Vector2(1.0f,0.5f), Vector2(-1.0f, 0.0f) );
+  customShader[ "subdivide-grid-x" ] = 20;
+  customShader[ "subdivide-grid-y" ] = 20;
 
-    return shaderEffect;
+  customShader[ "hints" ] = "output-is-transparent";
 
+  map[ "shader" ] = customShader;
+  return map;
 }
 
 } // namespace Toolkit
index 76493a6..554469b 100644 (file)
@@ -97,16 +97,23 @@ void ImageView::SetImage( Image image )
 
 void ImageView::SetImage( Property::Map map )
 {
-  mImage.Reset();
-  mUrl.clear();
   mPropertyMap = map;
 
-  mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mPropertyMap );
+  bool newRendererCreated = false;
+  if( mRenderer )
+  {
+    newRendererCreated = Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, mPropertyMap );
+  }
+  else
+  {
+    mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mPropertyMap );
+    newRendererCreated = true;
+  }
 
   //we need to inform any newly created renderers if it is on stage
-  if( Self().OnStage() )
+  CustomActor self = Self();
+  if( newRendererCreated && self.OnStage() )
   {
-    CustomActor self = Self();
     mRenderer.SetOnStage( self );
   }
 
index 423afc2..6542a2c 100644 (file)
@@ -88,7 +88,7 @@ BorderRenderer::~BorderRenderer()
 {
 }
 
-void BorderRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void BorderRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
 {
   Initialize( factoryCache );
 
@@ -122,7 +122,7 @@ void BorderRenderer::DoSetOnStage( Actor& actor )
   mBorderSizeIndex = (mImpl->mRenderer).RegisterProperty( SIZE_UNIFORM_NAME, mBorderSize );
 }
 
-void BorderRenderer::CreatePropertyMap( Property::Map& map ) const
+void BorderRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
index c05ea1c..9c53935 100644 (file)
@@ -60,9 +60,9 @@ public:
 public:  // from ControlRenderer
 
   /**
-   * @copydoc ControlRenderer::Initialize
+   * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::SetClipRect
@@ -78,7 +78,7 @@ protected:
   /**
    * @copydoc ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const;
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 public:
 
index 0da8112..68164ea 100644 (file)
@@ -77,7 +77,7 @@ ColorRenderer::~ColorRenderer()
 {
 }
 
-void ColorRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void ColorRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
 {
   Initialize( factoryCache );
 
@@ -107,7 +107,7 @@ void ColorRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
-void ColorRenderer::CreatePropertyMap( Property::Map& map ) const
+void ColorRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
index cec5b3a..ae5ccca 100644 (file)
@@ -56,9 +56,9 @@ public:
 public:  // from ControlRenderer
 
   /**
-   * @copydoc ControlRenderer::Initialize
+   * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::SetSize
@@ -78,7 +78,7 @@ public:  // from ControlRenderer
   /**
    * @copydoc ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const;
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp
new file mode 100644 (file)
index 0000000..6a58cfb
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "control-renderer-data-impl.h"
+
+// EXTERNAL HEADER
+#include <dali/public-api/common/dali-common.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/property-array.h>
+
+// EXTERNAL HEADER
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+//custom shader
+const char * const CUSTOM_SHADER( "shader" );
+const char * const CUSTOM_VERTEX_SHADER( "vertex-shader" );
+const char * const CUSTOM_FRAGMENT_SHADER( "fragment-shader" );
+const char * const CUSTOM_SUBDIVIDE_GRID_X( "subdivide-grid-x" );
+const char * const CUSTOM_SUBDIVIDE_GRID_Y( "subdivide-grid-y" );
+const char * const CUSTOM_SHADER_HINTS( "hints" ); ///< type STRING for a hint from the below hint strings or an ARRAY of of hint strings
+
+/**
+ * where hints should be contain strings of the following shader hints:
+ *   "none"                       | corresponds to HINT_NONE
+ *   "requires-self-depth-test"   | corresponds to HINT_REQUIRES_SELF_DEPTH_TEST
+ *   "output-is-transparent"      | corresponds to HINT_OUTPUT_IS_TRANSPARENT
+ *   "output-is-opaque"           | corresponds to HINT_OUTPUT_IS_OPAQUE
+ *   "modifies-geometry"          | corresponds to HINT_MODIFIES_GEOMETRY
+ */
+
+Shader::ShaderHints HintFromString( std::string hintString )
+{
+  if( hintString == "none" )
+  {
+    return Shader::HINT_NONE;
+  }
+  else if( hintString == "requires-self-depth-test" )
+  {
+    return Shader::HINT_REQUIRES_SELF_DEPTH_TEST;
+  }
+  else if( hintString == "output-is-transparent" )
+  {
+    return Shader::HINT_OUTPUT_IS_TRANSPARENT;
+  }
+  else if( hintString == "output-is-opaque" )
+  {
+    return Shader::HINT_OUTPUT_IS_OPAQUE;
+  }
+  else if( hintString == "modifies-geometry" )
+  {
+    return Shader::HINT_MODIFIES_GEOMETRY;
+  }
+  else
+  {
+    DALI_LOG_ERROR( "'%s' hint string is not recognised", hintString.c_str() );
+  }
+
+  return Shader::HINT_NONE;
+}
+
+}// unnamed namespace
+
+Internal::ControlRenderer::Impl::Impl()
+: mCustomShader(NULL),
+  mDepthIndex( 0.0f ),
+  mIsOnStage( false )
+{
+}
+
+Internal::ControlRenderer::Impl::~Impl()
+{
+  delete mCustomShader;
+}
+
+Internal::ControlRenderer::Impl::CustomShader::CustomShader( const Property::Map& map )
+: mGridSize( 1, 1 ),
+  mHints( Shader::HINT_NONE )
+{
+  SetPropertyMap( map );
+}
+
+void Internal::ControlRenderer::Impl::CustomShader::SetPropertyMap( const Property::Map& propertyMap )
+{
+  Property::Value* shaderValue = propertyMap.Find( CUSTOM_SHADER );
+  if( shaderValue )
+  {
+    mVertexShader.clear();
+    mFragmentShader.clear();
+    mGridSize = ImageDimensions( 1, 1 );
+    mHints = Shader::HINT_NONE;
+
+    Property::Map shaderMap;
+    if( shaderValue->Get( shaderMap ) )
+    {
+      Property::Value* vertexShaderValue = shaderMap.Find( CUSTOM_VERTEX_SHADER );
+      if( vertexShaderValue )
+      {
+        if( !vertexShaderValue->Get( mVertexShader ) )
+        {
+          DALI_LOG_ERROR( "'%s' parameter does not correctly specify a string", CUSTOM_VERTEX_SHADER );
+        }
+      }
+
+      Property::Value* fragmentShaderValue = shaderMap.Find( CUSTOM_FRAGMENT_SHADER );
+      if( fragmentShaderValue )
+      {
+        if( !fragmentShaderValue->Get( mFragmentShader ) )
+        {
+          DALI_LOG_ERROR( "'%s' parameter does not correctly specify a string", CUSTOM_FRAGMENT_SHADER );
+        }
+      }
+
+      Property::Value* subdivideXValue = shaderMap.Find( CUSTOM_SUBDIVIDE_GRID_X );
+      if( subdivideXValue )
+      {
+        int subdivideX;
+        if( !subdivideXValue->Get( subdivideX ) || subdivideX < 1 )
+        {
+          DALI_LOG_ERROR( "'%s' parameter does not correctly specify a value greater than 1", CUSTOM_SUBDIVIDE_GRID_X );
+        }
+        else
+        {
+          mGridSize = ImageDimensions( subdivideX, mGridSize.GetY() );
+        }
+      }
+
+      Property::Value* subdivideYValue = shaderMap.Find( CUSTOM_SUBDIVIDE_GRID_Y );
+      if( subdivideYValue )
+      {
+        int subdivideY;
+        if( !subdivideYValue->Get( subdivideY ) || subdivideY < 1 )
+        {
+          DALI_LOG_ERROR( "'%s' parameter does not correctly specify a value greater than 1", CUSTOM_SUBDIVIDE_GRID_Y );
+        }
+        else
+        {
+          mGridSize = ImageDimensions( mGridSize.GetX(), subdivideY );
+        }
+      }
+
+      Property::Value* hintsValue = shaderMap.Find( CUSTOM_SHADER_HINTS );
+      if( hintsValue )
+      {
+        std::string hintString;
+        Property::Array hintsArray;
+
+        if( hintsValue->Get( hintString ) )
+        {
+          mHints = HintFromString( hintString );
+        }
+        else if( hintsValue->Get( hintsArray ) )
+        {
+          int hints = Shader::HINT_NONE;
+          for( Property::Array::SizeType i = 0; i < hintsArray.Count(); ++i)
+          {
+            Property::Value hintValue = hintsArray[ i ];
+            if( hintValue.Get( hintString ) )
+            {
+              hints |= static_cast< int >( HintFromString( hintString ) );
+            }
+            else
+            {
+              DALI_LOG_ERROR( "'%s' parameter does not correctly specify an hint string at index %d", CUSTOM_SHADER_HINTS, i );
+            }
+
+            mHints = static_cast< Shader::ShaderHints >( hints );
+          }
+        }
+        else
+        {
+          DALI_LOG_ERROR( "'%s' parameter does not correctly specify a hint string or an array of hint strings", CUSTOM_SHADER_HINTS );
+        }
+      }
+    }
+    else
+    {
+      //use value with no type to mean reseting the shader back to default
+      if( shaderValue->GetType() != Dali::Property::NONE )
+      {
+        DALI_LOG_ERROR( "'%s' parameter does not correctly specify a property map", CUSTOM_SHADER );
+      }
+    }
+  }
+}
+
+void Internal::ControlRenderer::Impl::CustomShader::CreatePropertyMap( Property::Map& map ) const
+{
+  if( !mVertexShader.empty() || !mFragmentShader.empty() )
+  {
+    Property::Map customShader;
+    if( !mVertexShader.empty() )
+    {
+      customShader.Insert(CUSTOM_VERTEX_SHADER, mVertexShader );
+    }
+    if( !mFragmentShader.empty() )
+    {
+      customShader.Insert(CUSTOM_FRAGMENT_SHADER, mFragmentShader );
+    }
+
+    if( mGridSize.GetWidth() != 1 )
+    {
+      customShader.Insert(CUSTOM_SUBDIVIDE_GRID_X, mGridSize.GetWidth() );
+    }
+    if( mGridSize.GetHeight() != 1 )
+    {
+      customShader.Insert(CUSTOM_SUBDIVIDE_GRID_Y, mGridSize.GetHeight() );
+    }
+
+    if( mHints != Dali::Shader::HINT_NONE )
+    {
+      customShader.Insert(CUSTOM_SHADER_HINTS, static_cast< int >(mHints) );
+    }
+
+    map.Insert( CUSTOM_SHADER, customShader );
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
index e865a0e..47095c9 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
+// EXTERNAL INCLUDES
 #include <dali/public-api/math/vector2.h>
 #include <dali/devel-api/rendering/renderer.h>
 
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+
 namespace Dali
 {
 
@@ -33,15 +35,32 @@ namespace Internal
 
 struct Internal::ControlRenderer::Impl
 {
+  struct CustomShader
+  {
+    std::string mVertexShader;
+    std::string mFragmentShader;
+    Dali::ImageDimensions mGridSize;
+    Dali::Shader::ShaderHints mHints; //(bitfield) values from enum Shader::Hints
+
+    CustomShader( const Property::Map& map );
+    void SetPropertyMap( const Property::Map& map );
+    void CreatePropertyMap( Property::Map& map ) const;
+  };
+
   Geometry mGeometry;
   Shader   mShader;
   Renderer mRenderer;
 
+  CustomShader* mCustomShader;
+
   Vector2   mSize;
   Vector2   mOffset;
   Rect<int> mClipRect;
   float     mDepthIndex;
   bool      mIsOnStage;
+
+  Impl();
+  ~Impl();
 };
 
 } // namespace Internal
index acc3ead..91343a4 100644 (file)
 
 // EXTERNAL HEADER
 #include <dali/public-api/common/dali-common.h>
+#include <dali/integration-api/debug.h>
 
 //INTERNAL HEARDER
 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
 
+namespace
+{
+//custom shader
+const char * const CUSTOM_SHADER( "shader" );
+const char * const CUSTOM_VERTEX_SHADER( "vertex-shader" );
+const char * const CUSTOM_FRAGMENT_SHADER( "fragment-shader" );
+const char * const CUSTOM_SUBDIVIDE_GRID_X( "subdivide-grid-x" );
+const char * const CUSTOM_SUBDIVIDE_GRID_Y( "subdivide-grid-y" );
+const char * const CUSTOM_SHADER_HINTS( "hints" ); ///< type INTEGER; (bitfield) values from enum Shader::Hints
+}
+
 namespace Dali
 {
 
@@ -36,7 +48,6 @@ namespace Internal
 ControlRenderer::ControlRenderer()
 : mImpl( new Impl() )
 {
-  mImpl->mIsOnStage = false;
 }
 
 ControlRenderer::~ControlRenderer()
@@ -44,11 +55,42 @@ ControlRenderer::~ControlRenderer()
   delete mImpl;
 }
 
+void ControlRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+{
+  if( mImpl->mCustomShader )
+  {
+    mImpl->mCustomShader->SetPropertyMap( propertyMap );
+  }
+  else
+  {
+    Property::Value* customShaderValue = propertyMap.Find( CUSTOM_SHADER );
+    if( customShaderValue )
+    {
+      Property::Map customShader;
+      if( customShaderValue->Get( customShader ) )
+      {
+        mImpl->mCustomShader = new Impl::CustomShader( propertyMap );
+      }
+    }
+  }
+  DoInitialize( factoryCache, propertyMap );
+}
+
 void ControlRenderer::SetSize( const Vector2& size )
 {
   mImpl->mSize = size;
 }
 
+const Vector2& ControlRenderer::GetSize() const
+{
+  return mImpl->mSize;
+}
+
+void ControlRenderer::GetNaturalSize( Vector2& naturalSize ) const
+{
+  naturalSize = Vector2::ZERO;
+}
+
 void ControlRenderer::SetClipRect( const Rect<int>& clipRect )
 {
   mImpl->mClipRect = clipRect;
@@ -68,6 +110,11 @@ void ControlRenderer::SetDepthIndex( float index )
   }
 }
 
+float ControlRenderer::GetDepthIndex() const
+{
+  return mImpl->mDepthIndex;
+}
+
 void ControlRenderer::SetOnStage( Actor& actor )
 {
   Material material = Material::New( mImpl->mShader );
@@ -81,12 +128,15 @@ void ControlRenderer::SetOnStage( Actor& actor )
 
 void ControlRenderer::SetOffStage( Actor& actor )
 {
-  DoSetOffStage( actor );
+  if( mImpl->mIsOnStage )
+  {
+    DoSetOffStage( actor );
 
-  actor.RemoveRenderer( mImpl->mRenderer );
-  mImpl->mRenderer.Reset();
+    actor.RemoveRenderer( mImpl->mRenderer );
+    mImpl->mRenderer.Reset();
 
-  mImpl->mIsOnStage = false;
+    mImpl->mIsOnStage = false;
+  }
 }
 
 void ControlRenderer::DoSetOnStage( Actor& actor )
@@ -97,6 +147,15 @@ void ControlRenderer::DoSetOffStage( Actor& actor )
 {
 }
 
+void ControlRenderer::CreatePropertyMap( Property::Map& map ) const
+{
+  if( mImpl->mCustomShader )
+  {
+    mImpl->mCustomShader->CreatePropertyMap( map );
+  }
+  DoCreatePropertyMap( map );
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 86620f8..4dea2d9 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-object.h>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/devel-api/rendering/shader.h>
 
+// INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
 #include <dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h>
 
@@ -40,6 +43,21 @@ class RendererFactoryCache;
  * Base class for all Control rendering logic. A control may have multiple control renderers.
  *
  * Note: The control renderer responds to the the Actor::COLOR by blending it with the 'Multiply' operator.
+ *
+ * The following properties are optional
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | custom-shader             | MAP              |
+ *
+ * where custom-shader is a map with the following properties:
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | vertex-shader             | STRING           |
+ * | fragment-shader           | STRING           |
+ * | subdivide-grid-x          | INT              |
+ * | subdivide-grid-y          | INT              |
+ * | shader-hints              | INT              |
  */
 class ControlRenderer : public BaseObject
 {
@@ -53,7 +71,7 @@ public:
    * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
    * @param[in] propertyMap The properties for the requested ControlRenderer object.
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) = 0;
+  void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
 
   /**
    * @copydoc Toolkit::ControlRenderer::SetSize
@@ -61,6 +79,16 @@ public:
   virtual void SetSize( const Vector2& size );
 
   /**
+   * @copydoc Toolkit::ControlRenderer::GetSize
+   */
+  const Vector2& GetSize() const;
+
+  /**
+   * @copydoc Toolkit::ControlRenderer::GetNaturalSize
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+
+  /**
    * ToDo: Add this function to Toolkit::ControlRenderer when it is fully implemented.
    *
    * Set the clip rectangular of this renderer.
@@ -85,6 +113,11 @@ public:
   void SetDepthIndex( float index );
 
   /**
+   * @copydoc Toolkit::ControlRenderer::GetDepthIndex
+   */
+  float GetDepthIndex() const;
+
+  /**
    * @copydoc Toolkit::ControlRenderer::SetOnStage
    * @pre Impl->mGeometry must be created before this method is called
    */
@@ -98,7 +131,7 @@ public:
   /**
    * @copydoc Toolkit::ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const = 0;
+  void CreatePropertyMap( Property::Map& map ) const;
 
 protected:
 
@@ -113,16 +146,32 @@ protected:
   virtual ~ControlRenderer();
 
 protected:
+  /**
+   * @brief Called by CreatePropertyMap() allowing sub classes to respond to the CreatePropertyMap event
+   *
+   * @param[out] map The renderer property map.
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const = 0;
+
+  /**
+   * @brief Called by Initialize() allowing sub classes to respond to the Initialize event
+   *
+   * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
+   * @param[in] propertyMap The properties for the requested ControlRenderer object.
+   */
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) = 0;
+
+protected:
 
   /**
-   * Called by SetOnStage() allowing sub classes to respond to the SetOnStage event
+   * @brief Called by SetOnStage() allowing sub classes to respond to the SetOnStage event
    *
    * @param[in] actor The actor applying this renderer.
    */
   virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * Called by SetOffStage() allowing sub classes to respond to the SetOffStage event
+   * @brief Called by SetOffStage() allowing sub classes to respond to the SetOffStage event
    *
    * @param[in] actor The actor applying this renderer.
    */
@@ -137,7 +186,6 @@ private:
   ControlRenderer& operator=( const ControlRenderer& renderer );
 
 protected:
-
   struct Impl;
   Impl* mImpl;
 };
index 396ded3..0e502da 100644 (file)
@@ -143,7 +143,7 @@ GradientRenderer::~GradientRenderer()
 {
 }
 
-void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void GradientRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
 {
   mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
   if( !(mImpl->mGeometry) )
@@ -214,7 +214,7 @@ void GradientRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
-void GradientRenderer::CreatePropertyMap( Property::Map& map ) const
+void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
index e35b5db..1ee3f36 100644 (file)
@@ -84,9 +84,9 @@ public:
 public:  // from ControlRenderer
 
   /**
-   * @copydoc ControlRenderer::Initialize
+   * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::SetSize
@@ -106,7 +106,7 @@ public:  // from ControlRenderer
   /**
    * @copydoc ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const;
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
index 93c5c9a..4770960 100644 (file)
 // CLASS HEADER
 #include "image-renderer.h"
 
+// EXTERNAL HEADER
+#include <dali/public-api/images/resource-image.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADER
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
-#include <dali/public-api/images/resource-image.h>
 
 namespace Dali
 {
@@ -39,11 +43,11 @@ const char * const RENDERER_TYPE("renderer-type");
 const char * const RENDERER_TYPE_VALUE("image-renderer");
 
 // property names
-const char * const IMAGE_URL_NAME("image-url");
-const char * const IMAGE_FITTING_MODE("image-fitting-mode");
-const char * const IMAGE_SAMPLING_MODE("image-sampling-mode");
-const char * const IMAGE_DESIRED_WIDTH("image-desired-width");
-const char * const IMAGE_DESIRED_HEIGHT("image-desired-height");
+const char * const IMAGE_URL_NAME( "image-url" );
+const char * const IMAGE_FITTING_MODE( "image-fitting-mode" );
+const char * const IMAGE_SAMPLING_MODE( "image-sampling-mode" );
+const char * const IMAGE_DESIRED_WIDTH( "image-desired-width" );
+const char * const IMAGE_DESIRED_HEIGHT( "image-desired-height" );
 
 // fitting modes
 const char * const SHRINK_TO_FIT("shrink-to-fit");
@@ -91,6 +95,93 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
+void AddQuadIndices( Vector< unsigned int >& indices, unsigned int rowIdx, unsigned int nextRowIdx )
+{
+  indices.PushBack( rowIdx );
+  indices.PushBack( nextRowIdx + 1 );
+  indices.PushBack( rowIdx + 1 );
+
+  indices.PushBack( rowIdx );
+  indices.PushBack( nextRowIdx );
+  indices.PushBack( nextRowIdx + 1 );
+}
+
+Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices )
+{
+  Property::Map vertexFormat;
+  vertexFormat[ "aPosition" ] = Property::VECTOR2;
+  PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat, vertices.Size() );
+  if( vertices.Size() > 0 )
+  {
+    vertexPropertyBuffer.SetData( &vertices[ 0 ] );
+  }
+
+  Property::Map indexFormat;
+  indexFormat[ "indices" ] = Property::INTEGER;
+  PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat, indices.Size() );
+  if( indices.Size() > 0 )
+  {
+    indexPropertyBuffer.SetData( &indices[ 0 ] );
+  }
+
+  // Create the geometry object
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer( vertexPropertyBuffer );
+  geometry.SetIndexBuffer( indexPropertyBuffer );
+
+  return geometry;
+}
+
+Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gridSize )
+{
+  Geometry geometry;
+
+  if( gridSize == ImageDimensions( 1, 1 ) )
+  {
+    geometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
+    if( !geometry )
+    {
+      geometry =  factoryCache.CreateQuadGeometry();
+      factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry );
+    }
+  }
+  else
+  {
+    uint16_t gridWidth = gridSize.GetWidth();
+    uint16_t gridHeight = gridSize.GetHeight();
+
+    // Create vertices
+    Vector< Vector2 > vertices;
+    vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) );
+
+    for( int y = 0; y < gridHeight + 1; ++y )
+    {
+      for( int x = 0; x < gridWidth + 1; ++x )
+      {
+        vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight  - 0.5f) );
+      }
+    }
+
+    // Create indices
+    Vector< unsigned int > indices;
+    indices.Reserve( gridWidth * gridHeight * 6 );
+
+    unsigned int rowIdx     = 0;
+    unsigned int nextRowIdx = gridWidth + 1;
+    for( int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx )
+    {
+      for( int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx )
+      {
+        AddQuadIndices( indices, rowIdx, nextRowIdx );
+      }
+    }
+
+    return GenerateGeometry( vertices, indices );
+  }
+
+  return geometry;
+}
+
 } //unnamed namespace
 
 ImageRenderer::ImageRenderer()
@@ -105,7 +196,7 @@ ImageRenderer::~ImageRenderer()
 {
 }
 
-void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void ImageRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
 {
   Initialize(factoryCache);
 
@@ -113,6 +204,10 @@ void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Proper
   if( imageURLValue )
   {
     imageURLValue->Get( mImageUrl );
+    if( !mImageUrl.empty() )
+    {
+      mImage.Reset();
+    }
 
     Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE );
     if( fittingValue )
@@ -208,25 +303,45 @@ void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Proper
 
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
   }
-
-  mImage.Reset();
 }
 
 void ImageRenderer::SetSize( const Vector2& size )
 {
   ControlRenderer::SetSize( size );
-  // ToDo: renderer responds to the size change
+}
+
+void ImageRenderer::GetNaturalSize( Vector2& naturalSize ) const
+{
+  if(mImage)
+  {
+    naturalSize.x = mImage.GetWidth();
+    naturalSize.y = mImage.GetHeight();
+    return;
+  }
+  else if( mDesiredSize.GetWidth()>0 && mDesiredSize.GetHeight()>0)
+  {
+    naturalSize.x = mDesiredSize.GetWidth();
+    naturalSize.y = mDesiredSize.GetHeight();
+    return;
+  }
+  else if( !mImageUrl.empty() )
+  {
+    ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl );
+    naturalSize.x = dimentions.GetWidth();
+    naturalSize.y = dimentions.GetHeight();
+    return;
+  }
+
+  naturalSize = Vector2::ZERO;
 }
 
 void ImageRenderer::SetClipRect( const Rect<int>& clipRect )
 {
   ControlRenderer::SetClipRect( clipRect );
-  //ToDo: renderer responds to the clipRect change
 }
 
 void ImageRenderer::SetOffset( const Vector2& offset )
 {
-  //ToDo: renderer applies the offset
 }
 
 void ImageRenderer::DoSetOnStage( Actor& actor )
@@ -248,7 +363,7 @@ void ImageRenderer::DoSetOffStage( Actor& actor )
   }
 }
 
-void ImageRenderer::CreatePropertyMap( Property::Map& map ) const
+void ImageRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
@@ -346,24 +461,49 @@ void ImageRenderer::CreatePropertyMap( Property::Map& map ) const
 
 void ImageRenderer::Initialize( RendererFactoryCache& factoryCache )
 {
-  mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
-  if( !(mImpl->mGeometry) )
+  if( !mImpl->mCustomShader )
   {
-    mImpl->mGeometry =  factoryCache.CreateQuadGeometry();
-    factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
-  }
+    mImpl->mGeometry = CreateGeometry( factoryCache, ImageDimensions( 1, 1 ) );
+
+    mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
 
-  mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
-  if( !mImpl->mShader )
+    if( !mImpl->mShader )
+    {
+      mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+      factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
+    }
+  }
+  else
   {
-    mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
-    factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
+    mImpl->mGeometry = CreateGeometry( factoryCache, mImpl->mCustomShader->mGridSize );
+
+    if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() )
+    {
+      mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
+
+      if( !mImpl->mShader )
+      {
+        mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+        factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
+      }
+    }
+    else
+    {
+      mImpl->mShader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader,
+                                    mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader,
+                                    mImpl->mCustomShader->mHints );
+    }
   }
 
-  mDesiredSize = ImageDimensions();
-  mFittingMode = FittingMode::DEFAULT;
-  mSamplingMode = SamplingMode::DEFAULT;
-  mImageUrl.clear();
+  if( mImpl->mRenderer )
+  {
+    mImpl->mRenderer.SetGeometry( mImpl->mGeometry );
+    Material material = mImpl->mRenderer.GetMaterial();
+    if( material )
+    {
+      material.SetShader( mImpl->mShader );
+    }
+  }
 }
 
 void ImageRenderer::SetImage( const std::string& imageUrl )
index bbaa139..367ae31 100644 (file)
@@ -85,9 +85,9 @@ public:
 public:  // from ControlRenderer
 
   /**
-   * @copydoc ControlRenderer::Initialize
+   * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::SetSize
@@ -95,6 +95,11 @@ public:  // from ControlRenderer
   virtual void SetSize( const Vector2& size );
 
   /**
+   * @copydoc ControlRenderer::GetNaturalSize
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+
+  /**
    * @copydoc ControlRenderer::SetClipRect
    */
   virtual void SetClipRect( const Rect<int>& clipRect );
@@ -107,7 +112,7 @@ public:  // from ControlRenderer
   /**
    * @copydoc ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const;
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
index d49f3d3..842a099 100644 (file)
@@ -160,7 +160,7 @@ NPatchRenderer::~NPatchRenderer()
 {
 }
 
-void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void NPatchRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
 {
   Initialize(factoryCache);
 
@@ -187,6 +187,25 @@ void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Prope
   }
 }
 
+void NPatchRenderer::GetNaturalSize( Vector2& naturalSize ) const
+{
+  if( mImage )
+  {
+    naturalSize.x = mImage.GetWidth();
+    naturalSize.y = mImage.GetHeight();
+    return;
+  }
+  else if( !mImageUrl.empty() )
+  {
+    ImageDimensions dimentions = ResourceImage::GetImageSize( mImageUrl );
+    naturalSize.x = dimentions.GetWidth();
+    naturalSize.y = dimentions.GetHeight();
+    return;
+  }
+
+  naturalSize = Vector2::ZERO;
+}
+
 void NPatchRenderer::SetClipRect( const Rect<int>& clipRect )
 {
   ControlRenderer::SetClipRect( clipRect );
@@ -224,7 +243,7 @@ void NPatchRenderer::DoSetOffStage( Actor& actor )
   mCroppedImage.Reset();
 }
 
-void NPatchRenderer::CreatePropertyMap( Property::Map& map ) const
+void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
index 6bdb696..6e5bd5d 100644 (file)
@@ -66,9 +66,14 @@ public:
 public:  // from ControlRenderer
 
   /**
-   * @copydoc ControlRenderer::Initialize
+   * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+  virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc ControlRenderer::GetNaturalSize
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) const;
 
   /**
    * @copydoc ControlRenderer::SetClipRect
@@ -83,7 +88,7 @@ public:  // from ControlRenderer
   /**
    * @copydoc ControlRenderer::CreatePropertyMap
    */
-  virtual void CreatePropertyMap( Property::Map& map ) const;
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
 protected:
   /**
index 92fd3bf..afcc452 100644 (file)
@@ -274,6 +274,48 @@ bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const s
   }
 }
 
+bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap )
+{
+  Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
+  std::string typeValue ;
+  if( type && type->Get( typeValue ))
+  {
+    //If there's been a renderer type change then we have to return a new shader
+    if( typeValue ==  COLOR_RENDERER && typeid( renderer ) != typeid( ColorRenderer ) )
+    {
+      renderer = GetControlRenderer( propertyMap );
+      return true;
+    }
+    else if( typeValue ==  GRADIENT_RENDERER && typeid( renderer ) != typeid( GradientRenderer ) )
+    {
+      renderer = GetControlRenderer( propertyMap );
+      return true;
+    }
+    else if( typeValue ==  IMAGE_RENDERER && typeid( renderer ) != typeid( ImageRenderer ) )
+    {
+      renderer = GetControlRenderer( propertyMap );
+      return true;
+    }
+    else if( typeValue ==  N_PATCH_RENDERER && typeid( renderer ) != typeid( NPatchRenderer ) )
+    {
+      renderer = GetControlRenderer( propertyMap );
+      return true;
+    }
+    else if( typeValue ==  BORDER_RENDERER && typeid( renderer ) != typeid( BorderRenderer ) )
+    {
+      renderer = GetControlRenderer( propertyMap );
+      return true;
+    }
+  }
+
+  if( !mFactoryCache )
+  {
+    mFactoryCache = new RendererFactoryCache();
+  }
+  GetImplementation( renderer ).Initialize( *( mFactoryCache.Get() ), propertyMap );
+  return false;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 4ed7e7f..99ef2b8 100644 (file)
@@ -52,7 +52,12 @@ public:
   /**
    * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Property::Map& )
    */
-  Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap  );
+  Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap );
+
+  /**
+   * @copydoc Toolkit::RenderFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap )
+   */
+  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap );
 
   /**
    * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Vector4& )
index 6c8c9b7..9ecd378 100644 (file)
@@ -13,6 +13,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \
    $(toolkit_src_dir)/builder/replacement.cpp \
    $(toolkit_src_dir)/controls/renderers/control-renderer-impl.cpp \
+   $(toolkit_src_dir)/controls/renderers/control-renderer-data-impl.cpp \
    $(toolkit_src_dir)/controls/renderers/renderer-factory-cache.cpp \
    $(toolkit_src_dir)/controls/renderers/renderer-factory-impl.cpp \
    $(toolkit_src_dir)/controls/renderers/border/border-renderer.cpp \
index c94129f..6541b77 100644 (file)
@@ -273,6 +273,7 @@ struct Decorator::Impl : public ConnectionTracker
     mScrollDistance( SCROLL_DISTANCE ),
     mTextDepth( 0u ),
     mActiveCopyPastePopup( false ),
+    mPopupSetNewPosition( true ),
     mCursorBlinkStatus( true ),
     mDelayCursorBlink( false ),
     mPrimaryCursorVisible( false ),
@@ -422,6 +423,7 @@ struct Decorator::Impl : public ConnectionTracker
       if( mCopyPastePopup.actor )
       {
         mCopyPastePopup.actor.HidePopup();
+        mPopupSetNewPosition = true;
       }
     }
   }
@@ -459,19 +461,22 @@ struct Decorator::Impl : public ConnectionTracker
       return;
     }
 
-    if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+    if( mPopupSetNewPosition )
     {
-      float minHandleXPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
-      float maxHandleXPosition = std::max (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+      if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+      {
+        float minHandleXPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+        float maxHandleXPosition = std::max (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
 
-      float minHandleYPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
+        float minHandleYPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
 
-      mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
-      mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
-    }
-    else
-    {
-      mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+        mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
+        mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
+      }
+      else
+      {
+        mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+      }
     }
 
     Vector3 popupSize = Vector3( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
@@ -481,6 +486,7 @@ struct Decorator::Impl : public ConnectionTracker
     SetUpPopupPositionNotifications();
 
     mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+    mPopupSetNewPosition = false;
   }
 
   void PopupRelayoutComplete( Actor actor )
@@ -1405,6 +1411,7 @@ struct Decorator::Impl : public ConnectionTracker
   int                 mTextDepth;               ///< The depth used to render the text.
 
   bool                mActiveCopyPastePopup              : 1;
+  bool                mPopupSetNewPosition               : 1;
   bool                mCursorBlinkStatus                 : 1; ///< Flag to switch between blink on and blink off.
   bool                mDelayCursorBlink                  : 1; ///< Used to avoid cursor blinking when entering text.
   bool                mPrimaryCursorVisible              : 1; ///< Whether the primary cursor is visible.
@@ -1677,19 +1684,19 @@ bool Decorator::IsPopupActive() const
 
 void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask )
 {
-   mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
+  mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
 
-   if ( !mImpl->mCopyPastePopup.actor )
-   {
-     mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
+  if ( !mImpl->mCopyPastePopup.actor )
+  {
+    mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
 #ifdef DECORATOR_DEBUG
-     mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
+    mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
 #endif
-     mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
-     mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
-   }
+    mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+    mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
+  }
 
-   mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
+  mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
 }
 
 TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()
index b655772..7c629fd 100644 (file)
@@ -358,6 +358,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     // Now remove references for the old text
     RemoveText();
     mTextCache.Swap( newTextCache );
+    RemoveAllShadowRenderTasks();
 
     if( thereAreUnderlinedGlyphs )
     {
@@ -759,36 +760,33 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     subActor.SetSize( actorSize );
     subActor.SetColor( shadowColor );
 
-    // Discard redundant render-tasks
-    RemoveShadowRenderTask();
-
     // Create a render task to render the effect
-    mShadowTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
-    mShadowTask.SetTargetFrameBuffer( meshRecord.mBuffer );
-    mShadowTask.SetSourceActor( subActor );
-    mShadowTask.SetClearEnabled( true );
-    mShadowTask.SetClearColor( Vector4::ZERO );
-    mShadowTask.SetExclusive( true );
-    mShadowTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
-    mShadowTask.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
+    RenderTask shadowTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
+    shadowTask.SetTargetFrameBuffer( meshRecord.mBuffer );
+    shadowTask.SetSourceActor( subActor );
+    shadowTask.SetClearEnabled( true );
+    shadowTask.SetClearColor( Vector4::ZERO );
+    shadowTask.SetExclusive( true );
+    shadowTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
+    shadowTask.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
+    mShadowTasks.push_back( shadowTask );
     actor.Add( subActor );
 
     return actor;
   }
 
-  void RemoveShadowRenderTask()
+  void RemoveShadowRenderTask( RenderTask renderTask )
   {
-    if( mShadowTask )
+    if( renderTask )
     {
-      mShadowTask.FinishedSignal().Disconnect( this, &AtlasRenderer::Impl::RenderComplete );
+      renderTask.FinishedSignal().Disconnect( this, &AtlasRenderer::Impl::RenderComplete );
 
       // Guard to prevent accessing Stage after dali-core destruction
       if( Stage::IsInstalled() )
       {
-        Stage::GetCurrent().GetRenderTaskList().RemoveTask( mShadowTask );
+        Stage::GetCurrent().GetRenderTaskList().RemoveTask( renderTask );
       }
-
-      mShadowTask.Reset();
+      renderTask.Reset();
     }
   }
 
@@ -805,12 +803,21 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       }
     }
 
-    RemoveShadowRenderTask();
+    RemoveShadowRenderTask( renderTask );
+  }
+
+  void RemoveAllShadowRenderTasks()
+  {
+    for ( std::vector< RenderTask >::iterator shadowIterator = mShadowTasks.begin();
+          shadowIterator != mShadowTasks.end(); ++shadowIterator )
+    {
+      RemoveShadowRenderTask( *shadowIterator );
+    }
   }
 
   Actor mActor;                                       ///< The actor parent which renders the text
   AtlasGlyphManager mGlyphManager;                    ///< Glyph Manager to handle upload and caching
-  RenderTask mShadowTask;                             ///< Used to render shadows
+  std::vector< RenderTask > mShadowTasks;             ///< Used to render shadows
   TextAbstraction::FontClient mFontClient;            ///> The font client used to supply glyph information
   std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
   std::vector< uint32_t > mFace;                      ///> Face indices for a quad
@@ -865,7 +872,7 @@ AtlasRenderer::AtlasRenderer()
 
 AtlasRenderer::~AtlasRenderer()
 {
-  mImpl->RemoveShadowRenderTask();
+  mImpl->RemoveAllShadowRenderTasks();
 
   mImpl->RemoveText();
   delete mImpl;
index af2f4ca..c3ca785 100644 (file)
@@ -164,98 +164,8 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do
 
 DALI_TYPE_REGISTRATION_END()
 
-
 const char * const BACKGROUND_COLOR_NAME("color");
 
-/**
- * Structure which holds information about the background of a control
- */
-struct Background
-{
-  //ToDo: remove this actor and apply the Renderer on the Control
-  //      when the implementation of Actor::RemoveRenderer(Renderer&) is in place.
-  Actor actor;                      ///< Background actor
-  ControlRenderer controlRenderer;  ///< The control renderer to render the background
-  // The background can either be an image or a solid color.
-  Image image;                      ///< The background image
-  Vector4 color;                    ///< The background color
-
-  /**
-   * Constructor
-   */
-  Background()
-  : actor(),
-    controlRenderer(),
-    image(),
-    color( Color::TRANSPARENT )
-  {
-  }
-};
-
-//ToDo: skip this actor creation and apply the Renderer on the Control
-//      when the implementation of Actor::RemoveRenderer(Renderer&) is in place.
-Actor CreateBackgroundActor()
-{
-  // Create the actor
-  Actor actor = Actor::New();
-  actor.SetSize( Vector3::ONE );
-  actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
-  actor.SetColorMode( USE_PARENT_COLOR );
-
-  //Constraint scale of the background actor to the size of the control
-  Constraint constraint = Constraint::New<Vector3>( actor,
-                                                    Actor::Property::SCALE,
-                                                    EqualToConstraint() );
-  constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
-  constraint.Apply();
-
-  return actor;
-}
-
-/**
- * @brief Create the background actor for the control.
- *
- * @param[in] actor The parent actor of the background
- * @param[in] color The background color
- */
-void CreateBackground( Background& background, const Vector4& color )
-{
-  background.actor = CreateBackgroundActor();
-
-  background.image.Reset();
-  background.color = color;
-
- // Create the control renderer
-  RendererFactory rendererFactory = Toolkit::RendererFactory::Get();
-  background.controlRenderer = rendererFactory.GetControlRenderer(color);
-
-  // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection;
-  //       Currently Actor::RemoveRenderer doesnot work yet.
-  background.controlRenderer.SetOnStage( background.actor );
-}
-
-/**
- * @brief Create the background actor for the control.
- *
- * @param[in] actor The parent actor of the background
- * @param[in] image The background image
- */
-void CreateBackground( Background& background, const Image& image )
-{
-  background.actor = CreateBackgroundActor();
-
-  background.color = Color::TRANSPARENT;
-  background.image = image;
-
-  // Create the control renderer
-  RendererFactory rendererFactory = Toolkit::RendererFactory::Get();
-  background.controlRenderer = rendererFactory.GetControlRenderer(image);
-
-  // ToDo: Call SetOnStage at Control::OnStageConnection and call SetOffStage at Control::OnStageDisconnection;
-  //       Currently Actor::RemoveRenderer doesnot work yet.
-  background.controlRenderer.SetOnStage( background.actor );
-}
-
 } // unnamed namespace
 
 namespace Internal
@@ -269,7 +179,7 @@ public:
   Impl(Control& controlImpl)
 : mControlImpl( controlImpl ),
   mStyleName(""),
-  mBackground( NULL ),
+  mBackgroundRenderer(),
   mStartingPinchScale( NULL ),
   mKeyEventSignal(),
   mPinchGestureDetector(),
@@ -286,7 +196,6 @@ public:
   ~Impl()
   {
     // All gesture detectors will be destroyed so no need to disconnect.
-    delete mBackground;
     delete mStartingPinchScale;
   }
 
@@ -312,21 +221,6 @@ public:
     mControlImpl.OnLongPress(longPress);
   }
 
-  // Background Methods
-
-  /**
-   * Only creates an instance of the background if we actually use it.
-   * @return A reference to the Background structure.
-   */
-  Background& GetBackground()
-  {
-    if ( !mBackground )
-    {
-      mBackground = new Background;
-    }
-    return *mBackground;
-  }
-
   // Properties
 
   /**
@@ -361,16 +255,11 @@ public:
           const Property::Map* map = value.GetMap();
           if( map )
           {
-            const Property::Value* colorValue = map->Find( BACKGROUND_COLOR_NAME );
-            Vector4 color;
-            if( colorValue && colorValue->Get(color))
-            {
-              controlImpl.SetBackgroundColor( color );
-              break;
-            }
+            controlImpl.SetBackground( *map );
+            break;
           }
 
-          // The background is neither an valid image nor a valid color, so it is no longer required
+          // The background is neither a valid image nor a property map, so it is no longer required
           controlImpl.ClearBackground();
           break;
         }
@@ -418,18 +307,9 @@ public:
         case Toolkit::Control::Property::BACKGROUND:
         {
           Property::Map map;
-
-          Background* back = controlImpl.mImpl->mBackground;
-          if ( back && back->actor)
+          if( controlImpl.mImpl->mBackgroundRenderer )
           {
-            if( back->image )
-            {
-              Scripting::CreatePropertyMap( back->image, map );
-            }
-            else
-            {
-              map[BACKGROUND_COLOR_NAME] = back->color;
-            }
+            (controlImpl.mImpl->mBackgroundRenderer).CreatePropertyMap( map );
           }
 
           value = map;
@@ -451,7 +331,7 @@ public:
 
   Control& mControlImpl;
   std::string mStyleName;
-  Background* mBackground;           ///< Only create the background if we use it
+  Toolkit::ControlRenderer mBackgroundRenderer;   ///< The control renderer to render the background
   Vector3* mStartingPinchScale;      ///< The scale when a pinch gesture starts, TODO: consider removing this
   Toolkit::Control::KeyEventSignalType mKeyEventSignal;
   Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
@@ -521,81 +401,93 @@ const std::string& Control::GetStyleName() const
 
 void Control::SetBackgroundColor( const Vector4& color )
 {
-  Background& background( mImpl->GetBackground() );
+  Actor self( Self() );
+  Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get();
 
-  // The background renderer exits and it is a color renderer, we continue to use the current renderer
-  if ( background.actor && (!background.image)
-      &&  (!Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, color ) ))
+  if( mImpl->mBackgroundRenderer )
   {
-    background.color = color;
+    Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer );
+    // if ResetRenderer returns false, we continue to use the current renderer with a new color set to it.
+    if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, color ) )
+    {
+      return;
+    }
+    // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset.
+    currentRenderer.RemoveAndReset( self );
   }
   else
   {
-    // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor
-    if( background.actor )
-    {
-      mImpl->mAddRemoveBackgroundChild = true;
-      Self().Remove( background.actor );
-      mImpl->mAddRemoveBackgroundChild = false;
-    }
-    // Create background actor
-    CreateBackground(background, color );
-    mImpl->mAddRemoveBackgroundChild = true;
-    // The actor does not need to be inserted to guarantee order.
-    Self().Add( background.actor );
-    mImpl->mAddRemoveBackgroundChild = false;
+    mImpl->mBackgroundRenderer = factory.GetControlRenderer( color );
+  }
+
+  if( self.OnStage() )
+  {
+    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+    mImpl->mBackgroundRenderer.SetOnStage( self );
   }
 }
 
 Vector4 Control::GetBackgroundColor() const
 {
-  if ( mImpl->mBackground )
+  return Color::TRANSPARENT;
+}
+
+void Control::SetBackground(const Property::Map& map)
+{
+  const Property::Value* colorValue = map.Find( BACKGROUND_COLOR_NAME );
+  Vector4 color;
+  if( colorValue && colorValue->Get(color))
   {
-    return mImpl->mBackground->color;
+    SetBackgroundColor( color );
+    return;
+  }
+
+  Actor self( Self() );
+  mImpl->mBackgroundRenderer.RemoveAndReset( self );
+
+  Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get();
+  mImpl->mBackgroundRenderer = factory.GetControlRenderer( map );
+
+  // mBackgroundRenderer might be empty, if an invalid map is provided, no background.
+  if( self.OnStage() && mImpl->mBackgroundRenderer)
+  {
+    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+    mImpl->mBackgroundRenderer.SetOnStage( self );
   }
-  return Color::TRANSPARENT;
 }
 
 void Control::SetBackgroundImage( Image image )
 {
-  Background& background( mImpl->GetBackground() );
+  Actor self( Self() );
+  Toolkit::RendererFactory factory = Toolkit::RendererFactory::Get();
 
-  // The background renderer exits and it is an image renderer, we continue to use the current renderer
-  if( background.actor && background.image
-      && (! Toolkit::RendererFactory::Get().ResetRenderer( background.controlRenderer, image ) ) )
+  if(  mImpl->mBackgroundRenderer  )
   {
-    background.image = image;
+    Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer );
+    // if ResetRenderer returns false, we continue to use the current renderer with a new image set to it.
+    if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, image )  )
+    {
+      return;
+    }
+    // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset.
+    currentRenderer.RemoveAndReset( self );
   }
   else
   {
-    // TODO: Apply the new renderer directly, as Actor::RemoveRenderer is not working yet, we create a new actor
-    if( background.actor )
-    {
-      mImpl->mAddRemoveBackgroundChild = true;
-      Self().Remove( background.actor );
-      mImpl->mAddRemoveBackgroundChild = false;
-    }
-    // Create background actor
-    CreateBackground(background, image);
-    mImpl->mAddRemoveBackgroundChild = true;
-    // The actor does not need to be inserted to guarantee order.
-    Self().Add( background.actor );
-    mImpl->mAddRemoveBackgroundChild = false;
+    mImpl->mBackgroundRenderer = factory.GetControlRenderer( image );
+  }
+
+  if( self.OnStage() )
+  {
+    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+    mImpl->mBackgroundRenderer.SetOnStage( self );
   }
 }
 
 void Control::ClearBackground()
 {
-  if ( mImpl->mBackground )
-  {
-    Background& background( mImpl->GetBackground() );
-    mImpl->mAddRemoveBackgroundChild = true;
-    Self().Remove( background.actor );
-    mImpl->mAddRemoveBackgroundChild = false;
-
-    delete mImpl->mBackground;
-    mImpl->mBackground = NULL;
-  }
+  Actor self(Self());
+  mImpl->mBackgroundRenderer.RemoveAndReset( self );
 }
 
 void Control::EnableGestureDetection(Gesture::Type type)
@@ -928,14 +820,21 @@ void Control::OnStageConnection( int depth )
     }
   }
 
-  if( mImpl->mBackground && mImpl->mBackground->controlRenderer)
+  if( mImpl->mBackgroundRenderer)
   {
-    mImpl->mBackground->controlRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth );
+    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+    Actor self(Self());
+    mImpl->mBackgroundRenderer.SetOnStage( self );
   }
 }
 
 void Control::OnStageDisconnection()
 {
+  if( mImpl->mBackgroundRenderer)
+  {
+    Actor self(Self());
+    mImpl->mBackgroundRenderer.SetOffStage( self );
+  }
 }
 
 void Control::OnKeyInputFocusGained()
@@ -1016,30 +915,13 @@ void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dime
 
 Vector3 Control::GetNaturalSize()
 {
-  //Control's natural size is the size of its background image if it has been set, or ZERO otherwise
-  Vector3 naturalSize = Vector3::ZERO;
-  if( mImpl->mBackground )
+  if( mImpl->mBackgroundRenderer )
   {
-    if( mImpl->mBackground->actor.GetRendererCount() > 0 )
-    {
-      Material backgroundMaterial = mImpl->mBackground->actor.GetRendererAt(0).GetMaterial();
-      if( backgroundMaterial.GetNumberOfSamplers() > 0 )
-      {
-        Image backgroundImage =  backgroundMaterial.GetSamplerAt(0).GetImage();
-        if( backgroundImage )
-        {
-          naturalSize.x = backgroundImage.GetWidth();
-          naturalSize.y = backgroundImage.GetHeight();
-        }
-      }
-    }
-    else
-    {
-      return mImpl->mBackground->actor.GetNaturalSize();
-    }
+    Vector2 naturalSize;
+    mImpl->mBackgroundRenderer.GetNaturalSize(naturalSize);
+    return Vector3(naturalSize);
   }
-
-  return naturalSize;
+  return Vector3::ZERO;
 }
 
 float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
@@ -1049,27 +931,11 @@ float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dim
 
 float Control::GetHeightForWidth( float width )
 {
-  if( mImpl->mBackground )
-  {
-    Actor actor = mImpl->mBackground->actor;
-    if( actor )
-    {
-      return actor.GetHeightForWidth( width );
-    }
-  }
   return GetHeightForWidthBase( width );
 }
 
 float Control::GetWidthForHeight( float height )
 {
-  if( mImpl->mBackground )
-  {
-    Actor actor = mImpl->mBackground->actor;
-    if( actor )
-    {
-      return actor.GetWidthForHeight( height );
-    }
-  }
   return GetWidthForHeightBase( height );
 }
 
index 4a8466d..aa86d6a 100644 (file)
@@ -102,6 +102,13 @@ public:
   void SetBackgroundImage( Image image );
 
   /**
+   * @brief Set the background with a property map.
+   *
+   * @param[in] map The background property map.
+   */
+  void SetBackground(const Property::Map& map);
+
+  /**
    * @copydoc Dali::Toolkit::Control::ClearBackground
    */
   void ClearBackground();
index d6425e2..51f6bd1 100644 (file)
@@ -89,7 +89,7 @@ public:
     enum
     {
       STYLE_NAME = PROPERTY_START_INDEX,       ///< name "style-name",       @see SetStyleName,       type std::string
-      BACKGROUND,                              ///< name "background",       @see SetBackgroundImage, type Map,         @since DALi 1.1.4
+      BACKGROUND,                              ///< name "background",       @since DALi 1.1.4,       type Map
       KEY_INPUT_FOCUS,                         ///< name "key-input-focus",  @see SetKeyInputFocus,   type bool
     };
   };
index 6e63182..a7b1d49 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 4;
+const unsigned int TOOLKIT_MICRO_VERSION = 5;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index e3500ea..b80108a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.1.4
+Version:    1.1.5
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0, BSD-2.0, MIT