Add GetVisualProperty to Control 41/247841/6
authorHeeyong Song <heeyong.song@samsung.com>
Tue, 17 Nov 2020 10:16:33 +0000 (19:16 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Wed, 9 Dec 2020 14:44:22 +0000 (23:44 +0900)
Change-Id: I099bb989dfc5808907c6ebe7cc260727b39faaa4

18 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/controls/control-devel.cpp
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/devel-api/visuals/color-visual-properties-devel.h
dali-toolkit/devel-api/visuals/visual-properties-devel.h
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/public-api/visuals/visual-properties.h

index fde1197..c135c9f 100644 (file)
@@ -3934,3 +3934,261 @@ int UtcDaliVisualGetType(void)
 
   END_TEST;
 }
+
+int UtcDaliVisualGetVisualProperty01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetVisualProperty01: Test animatable property, Visual::Base, ColorVisual" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+  propertyMap.Insert(Visual::Property::MIX_COLOR, Color::BLUE);
+  propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, 10.0f);
+  propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS_POLICY, Toolkit::Visual::Transform::Policy::RELATIVE);
+  propertyMap.Insert(DevelColorVisual::Property::BLUR_RADIUS, 20.0f);
+  Visual::Base colorVisual = factory.CreateVisual(propertyMap);
+
+  DummyControl dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, colorVisual);
+  dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+  application.GetScene().Add(dummyControl);
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 targetColor(1.0f, 1.0f, 1.0f);
+  float targetOpacity = 0.5f;
+  float targetCornerRadius = 20.0f;
+  float targetBlurRadius = 10.0f;
+
+  Animation animation = Animation::New(1.0f);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::MIX_COLOR), targetColor);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::OPACITY), targetOpacity);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), targetCornerRadius);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelColorVisual::Property::BLUR_RADIUS), targetBlurRadius);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render();
+  application.Render(1001u); // End of animation
+
+  Property::Map resultMap;
+  colorVisual.CreatePropertyMap( resultMap );
+
+  // Test property values: they should be updated
+  Property::Value* colorValue = resultMap.Find(ColorVisual::Property::MIX_COLOR, Property::VECTOR4);
+  DALI_TEST_CHECK(colorValue);
+  DALI_TEST_EQUALS(colorValue->Get<Vector4>(), Vector4(targetColor.r, targetColor.g, targetColor.b, targetOpacity), TEST_LOCATION);
+
+  Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(cornerRadiusValue);
+  DALI_TEST_EQUALS(cornerRadiusValue->Get< float >(), targetCornerRadius, TEST_LOCATION);
+
+  Property::Value* blurRadiusValue = resultMap.Find(DevelColorVisual::Property::BLUR_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(blurRadiusValue);
+  DALI_TEST_EQUALS(blurRadiusValue->Get< float >(), targetBlurRadius, TEST_LOCATION);
+
+  // Test uniform values
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector3>("mixColor", targetColor), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("cornerRadius", targetCornerRadius), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("blurRadius", targetBlurRadius), true, TEST_LOCATION);
+
+  // Test not-supported property
+  Property property1 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::PREMULTIPLIED_ALPHA);
+  DALI_TEST_CHECK(!property1.object);
+  DALI_TEST_CHECK(property1.propertyIndex == Property::INVALID_INDEX);
+
+  // Test not-supported property
+  Property property2 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelColorVisual::Property::RENDER_IF_TRANSPARENT);
+  DALI_TEST_CHECK(!property2.object);
+  DALI_TEST_CHECK(property2.propertyIndex == Property::INVALID_INDEX);
+
+  // Test unregistered visual
+  Property property3 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL2, Visual::Property::MIX_COLOR);
+  DALI_TEST_CHECK(!property3.object);
+  DALI_TEST_CHECK(property3.propertyIndex == Property::INVALID_INDEX);
+
+  // Test after the control is unparented
+  dummyControl.Unparent();
+
+  Property property4 = DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::MIX_COLOR);
+  DALI_TEST_CHECK(!property4.object);
+  DALI_TEST_CHECK(property4.propertyIndex == Property::INVALID_INDEX);
+
+  END_TEST;
+}
+
+int UtcDaliVisualGetVisualProperty02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetVisualProperty02: Test animatable property" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+  Visual::Base colorVisual = factory.CreateVisual(propertyMap);
+
+  DummyControl dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, colorVisual);
+  dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+  application.GetScene().Add(dummyControl);
+
+  application.SendNotification();
+  application.Render();
+
+  Vector3 targetColor(1.0f, 1.0f, 1.0f);
+  float targetOpacity = 0.5f;
+  float targetCornerRadius = 20.0f;
+  float targetBlurRadius = 10.0f;
+
+  // Should work when the properties are not set before
+  Animation animation = Animation::New(1.0f);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, "mixColor"), targetColor);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, "opacity"), targetOpacity);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, "cornerRadius"), targetCornerRadius);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, "blurRadius"), targetBlurRadius);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render();
+  application.Render(1001u); // End of animation
+
+  Property::Map resultMap;
+  colorVisual.CreatePropertyMap(resultMap);
+
+  // Test property values: they should be updated
+  Property::Value* colorValue = resultMap.Find(ColorVisual::Property::MIX_COLOR, Property::VECTOR4);
+  DALI_TEST_CHECK(colorValue);
+  DALI_TEST_EQUALS(colorValue->Get<Vector4>(), Vector4(targetColor.r, targetColor.g, targetColor.b, targetOpacity), TEST_LOCATION);
+
+  Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(cornerRadiusValue);
+  DALI_TEST_EQUALS(cornerRadiusValue->Get< float >(), targetCornerRadius, TEST_LOCATION);
+
+  Property::Value* blurRadiusValue = resultMap.Find(DevelColorVisual::Property::BLUR_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(blurRadiusValue);
+  DALI_TEST_EQUALS(blurRadiusValue->Get< float >(), targetBlurRadius, TEST_LOCATION);
+
+  // Test uniform values
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector3>("mixColor", targetColor), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("cornerRadius", targetCornerRadius), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("blurRadius", targetBlurRadius), true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliVisualGetVisualProperty03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetVisualProperty01: Test animatable property, ImageVisual" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
+  propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME);
+  Visual::Base imageVisual = factory.CreateVisual(propertyMap);
+
+  DummyControl dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+  dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+  application.GetScene().Add(dummyControl);
+
+  // Wait for image loading
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  float targetOpacity = 0.5f;
+  float targetCornerRadius = 20.0f;
+
+  Animation animation = Animation::New(1.0f);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::OPACITY), targetOpacity);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), targetCornerRadius);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render();
+  application.Render(1001u); // End of animation
+
+  Property::Map resultMap;
+  imageVisual.CreatePropertyMap( resultMap );
+
+  // Test property values: they should be updated
+  Property::Value* colorValue = resultMap.Find(Visual::Property::MIX_COLOR, Property::VECTOR4);
+  DALI_TEST_CHECK(colorValue);
+  DALI_TEST_EQUALS(colorValue->Get<Vector4>(), Vector4(1.0f, 1.0f, 1.0f, targetOpacity), TEST_LOCATION);
+
+  Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(cornerRadiusValue);
+  DALI_TEST_EQUALS(cornerRadiusValue->Get< float >(), targetCornerRadius, TEST_LOCATION);
+
+  // Test uniform value
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("cornerRadius", targetCornerRadius), true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliVisualGetVisualProperty04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetVisualProperty01: Test animatable property, GradientVisual" );
+
+  Vector2 start(-1.f, -1.f);
+  Vector2 end(1.f, 1.f);
+  Property::Array stopColors;
+  stopColors.PushBack( Color::RED );
+  stopColors.PushBack( Color::GREEN );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE,  Visual::GRADIENT);
+  propertyMap.Insert(GradientVisual::Property::START_POSITION, start);
+  propertyMap.Insert(GradientVisual::Property::END_POSITION, end);
+  propertyMap.Insert(GradientVisual::Property::STOP_OFFSET, Vector2(0.f, 1.f));
+  propertyMap.Insert(GradientVisual::Property::SPREAD_METHOD, GradientVisual::SpreadMethod::REPEAT);
+  propertyMap.Insert(GradientVisual::Property::STOP_COLOR, stopColors);
+  Visual::Base gradientVisual = factory.CreateVisual(propertyMap);
+
+  DummyControl dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, gradientVisual);
+  dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f);
+  application.GetScene().Add(dummyControl);
+
+  application.SendNotification();
+  application.Render();
+
+  float targetOpacity = 0.5f;
+  float targetCornerRadius = 20.0f;
+
+  Animation animation = Animation::New(1.0f);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, Visual::Property::OPACITY), targetOpacity);
+  animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), targetCornerRadius);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render();
+  application.Render(1001u); // End of animation
+
+  Property::Map resultMap;
+  gradientVisual.CreatePropertyMap( resultMap );
+
+  // Test property values: they should be updated
+  Property::Value* colorValue = resultMap.Find(Visual::Property::MIX_COLOR, Property::VECTOR4);
+  DALI_TEST_CHECK(colorValue);
+  DALI_TEST_EQUALS(colorValue->Get<Vector4>(), Vector4(1.0f, 1.0f, 1.0f, targetOpacity), TEST_LOCATION);
+
+  Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::FLOAT);
+  DALI_TEST_CHECK(cornerRadiusValue);
+  DALI_TEST_EQUALS(cornerRadiusValue->Get< float >(), targetCornerRadius, TEST_LOCATION);
+
+  // Test uniform value
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<float>("cornerRadius", targetCornerRadius), true, TEST_LOCATION);
+
+  END_TEST;
+}
index a855b2d..0670e68 100644 (file)
@@ -115,6 +115,13 @@ VisualEventSignalType& VisualEventSignal(Control control)
   return controlDataImpl.VisualEventSignal();
 }
 
+Dali::Property GetVisualProperty(Control control, Dali::Property::Index index, Dali::Property::Key visualPropertyKey)
+{
+  Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
+  Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(internalControl);
+  return controlDataImpl.GetVisualProperty(index, visualPropertyKey);
+}
+
 static Toolkit::Internal::Control::Impl *GetControlImplementationIfAny( Dali::Actor actor)
 {
   Dali::Toolkit::Control c = Toolkit::Control::DownCast( actor );
index 5753a69..af6c76c 100644 (file)
@@ -358,6 +358,18 @@ using VisualEventSignalType = Signal<void(Control, Dali::Property::Index, Dali::
 DALI_TOOLKIT_API VisualEventSignalType& VisualEventSignal(Control control);
 
 /**
+ * @brief Retrieve the property object associated with the given property index and the visual property key.
+ *
+ * @param[in] control The control
+ * @param[in] index The Property index of the visual.
+ * @param[in] visualPropertyKey The key of the visual's property.
+ * @return The Property object
+ * @pre The control should be added to the Scene.
+ * @pre The returned object is valid for as long as the control is on the Scene.
+ */
+DALI_TOOLKIT_API Dali::Property GetVisualProperty(Control control, Dali::Property::Index index, Dali::Property::Key visualPropertyKey);
+
+/**
  * @brief The signal is emmited as a succession of "activate" signal send by accessibility client.
  * @return The signal to connect to
  */
index d325a9c..448bf88 100644 (file)
@@ -49,7 +49,7 @@ enum
 
   /**
    * @brief The blur radius of the visual.
-   * @details Name "blurRadius", type Property::FLOAT.
+   * @details Name "blurRadius", type Property::FLOAT, animatable.
    *          If the value is 0, the edge is sharp. Otherwise, the larger the value, the more the edge is blurred.
    * @note Optional.
    * @note The default is 0.
index 99e3837..6a5f51d 100644 (file)
@@ -73,7 +73,7 @@ enum Type
 
   /**
    * @brief The radius for the rounded corners of the visual
-   * @details Name "cornerRadius", type Property::FLOAT.
+   * @details Name "cornerRadius", type Property::FLOAT, animatable
    * @note Optional.
    */
   CORNER_RADIUS = OPACITY + 2,
index 4e7dff9..2c9dca5 100755 (executable)
@@ -169,6 +169,24 @@ Toolkit::Visual::Base GetVisualByName(
   return visualHandle;
 }
 
+Toolkit::Visual::Base GetVisualByIndex(
+  const RegisteredVisualContainer& visuals,
+  Property::Index                  index)
+{
+  Toolkit::Visual::Base visualHandle;
+
+  RegisteredVisualContainer::Iterator iter;
+  for(iter = visuals.Begin(); iter != visuals.End(); iter++)
+  {
+    if((*iter)->index == index)
+    {
+      visualHandle = (*iter)->visual;
+      break;
+    }
+  }
+  return visualHandle;
+}
+
 /**
  * Move visual from source to destination container
  */
@@ -1820,6 +1838,19 @@ void Control::Impl::ClearShadow()
    mControlImpl.RelayoutRequest();
 }
 
+Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dali::Property::Key visualPropertyKey)
+{
+  Toolkit::Visual::Base visual = GetVisualByIndex(mVisuals, index);
+  if(visual)
+  {
+    Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
+    return visualImpl.GetPropertyObject(visualPropertyKey);
+  }
+
+  Handle handle;
+  return Dali::Property(handle, Property::INVALID_INDEX);
+}
+
 void Control::Impl::EmitResourceReadySignal()
 {
   if(!mIsEmittingResourceReadySignal)
index aefb484..aa16060 100755 (executable)
@@ -391,6 +391,11 @@ public:
    */
   void ClearShadow();
 
+  /**
+   * @copydoc DevelControl::GetVisualProperty()
+   */
+  Dali::Property GetVisualProperty(Dali::Property::Index index, Dali::Property::Key visualPropertyKey);
+
 private:
 
   /**
index edebccf..68dc04a 100644 (file)
@@ -187,10 +187,12 @@ ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Propert
   return colorVisualPtr;
 }
 
-ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
-: Visual::Base( factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR ),
-  mBlurRadius( 0.0f ),
-  mRenderIfTransparent( false )
+ColorVisual::ColorVisual(VisualFactoryCache& factoryCache)
+: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR),
+  mBlurRadius(0.0f),
+  mBlurRadiusIndex(Property::INVALID_INDEX),
+  mRenderIfTransparent(false),
+  mNeedBlurRadius(false)
 {
 }
 
@@ -259,13 +261,36 @@ void ColorVisual::DoSetOnScene( Actor& actor )
   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
 }
 
+void ColorVisual::DoSetOffScene(Actor& actor)
+{
+  if(mImpl->mRenderer && mBlurRadiusIndex != Property::INVALID_INDEX)
+  {
+    // Update values from Renderer
+    mBlurRadius = mImpl->mRenderer.GetProperty<float>(mBlurRadiusIndex);
+  }
+
+  actor.RemoveRenderer(mImpl->mRenderer);
+  mImpl->mRenderer.Reset();
+  mBlurRadiusIndex = Property::INVALID_INDEX;
+}
+
 void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR );
   map.Insert( Toolkit::ColorVisual::Property::MIX_COLOR, mImpl->mMixColor );
   map.Insert( Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, mRenderIfTransparent );
-  map.Insert( Toolkit::DevelColorVisual::Property::BLUR_RADIUS, mBlurRadius );
+
+  if(mImpl->mRenderer && mBlurRadiusIndex != Property::INVALID_INDEX)
+  {
+    // Update values from Renderer
+    float blurRadius = mImpl->mRenderer.GetProperty<float>(mBlurRadiusIndex);
+    map.Insert(Toolkit::DevelColorVisual::Property::BLUR_RADIUS, blurRadius);
+  }
+  else
+  {
+    map.Insert(Toolkit::DevelColorVisual::Property::BLUR_RADIUS, mBlurRadius);
+  }
 }
 
 void ColorVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -273,7 +298,6 @@ void ColorVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
   // Do nothing
 }
 
-
 void ColorVisual::OnSetTransform()
 {
   if( mImpl->mRenderer )
@@ -299,12 +323,42 @@ void ColorVisual::OnDoAction( const Property::Index actionId, const Property::Va
   }
 }
 
+void ColorVisual::UpdateShader()
+{
+  if(mImpl->mRenderer)
+  {
+    Shader shader = GetShader();
+    mImpl->mRenderer.SetShader(shader);
+  }
+}
+
 void ColorVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
+  Shader shader = GetShader();
+
+  mImpl->mRenderer = Renderer::New(geometry, shader);
+
+  // ColorVisual has it's own index key for mix color - use this instead
+  // of using the new base index to avoid changing existing applications
+  // String keys will get to this property.
+  mImpl->mMixColorIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ColorVisual::Property::MIX_COLOR, MIX_COLOR, Vector3(mImpl->mMixColor));
+
+  if(!EqualsZero(mBlurRadius))
+  {
+    mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius);
+    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+  }
+
+  // Register transform properties
+  mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+}
+
+Shader ColorVisual::GetShader()
+{
   Shader shader;
-  if( !EqualsZero( mBlurRadius ) )
+  if(!EqualsZero(mBlurRadius) || mNeedBlurRadius)
   {
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_BLUR_EDGE );
     if( !shader )
@@ -332,22 +386,33 @@ void ColorVisual::InitializeRenderer()
     }
   }
 
-  mImpl->mRenderer = Renderer::New( geometry, shader );
-
-  // ColorVisual has it's own index key for mix color - use this instead
-  // of using the new base index to avoid changing existing applications
-  // String keys will get to this property.
-  mImpl->mMixColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::ColorVisual::Property::MIX_COLOR, MIX_COLOR, Vector3(mImpl->mMixColor) );
+  return shader;
+}
 
-  mImpl->mRenderer.RegisterProperty( BLUR_RADIUS_NAME, mBlurRadius );
+Dali::Property ColorVisual::OnGetPropertyObject(Dali::Property::Key key)
+{
+  if(!mImpl->mRenderer)
+  {
+    Handle handle;
+    return Dali::Property(handle, Property::INVALID_INDEX);
+  }
 
-  if( !EqualsZero( mBlurRadius ) )
+  if((key.type == Property::Key::INDEX && key.indexKey == DevelColorVisual::Property::BLUR_RADIUS) || (key.type == Property::Key::STRING && key.stringKey == BLUR_RADIUS_NAME))
   {
-    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+    mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius);
+
+    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+
+    mNeedBlurRadius = true;
+
+    // Change shader
+    UpdateShader();
+
+    return Dali::Property(mImpl->mRenderer, mBlurRadiusIndex);
   }
 
-  // Register transform properties
-  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+  Handle handle;
+  return Dali::Property(handle, Property::INVALID_INDEX);
 }
 
 } // namespace Internal
index d5b2a6f..bf28d25 100644 (file)
@@ -95,6 +95,11 @@ protected:
   void DoSetOnScene( Actor& actor ) override;
 
   /**
+   * @copydoc Visual::Base::DoSetOffScene
+   */
+  void DoSetOffScene(Actor& actor) override;
+
+  /**
    * @copydoc Visual::Base::OnSetTransform
    */
   void OnSetTransform() override;
@@ -104,12 +109,28 @@ protected:
    */
   void OnDoAction( const Property::Index actionId, const Property::Value& attributes ) override;
 
+  /**
+   * @copydoc Visual::Base::UpdateShader
+   */
+  void UpdateShader() override;
+
+  /**
+   * @copydoc Visual::Base::OnGetPropertyObject
+   */
+  Dali::Property OnGetPropertyObject(Dali::Property::Key key) override;
+
 private:
   /**
    * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
    */
   void InitializeRenderer();
 
+  /**
+   * @brief Get a shader for the current properties.
+   * @return The shader for the current properties.
+   */
+  Shader GetShader();
+
 private:
 
   // Undefined
@@ -119,9 +140,10 @@ private:
   ColorVisual& operator=( const ColorVisual& colorRenderer );
 
 private:
-
-  float mBlurRadius;         ///< The blur radius
-  bool mRenderIfTransparent; ///< Whether we should render even if the mix-color is transparent.
+  float           mBlurRadius;          ///< The blur radius
+  Property::Index mBlurRadiusIndex;     ///< The blur radius property index
+  bool            mRenderIfTransparent; ///< Whether we should render even if the mix-color is transparent.
+  bool            mNeedBlurRadius;      ///< Whether we need the blur radius in shader.
 };
 
 } // namespace Internal
index d0807df..b86f9a7 100644 (file)
@@ -385,6 +385,15 @@ void GradientVisual::DoSetOnScene( Actor& actor )
   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
 }
 
+void GradientVisual::UpdateShader()
+{
+  if(mImpl->mRenderer)
+  {
+    Shader shader = GetShader();
+    mImpl->mRenderer.SetShader(shader);
+  }
+}
+
 void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
@@ -436,16 +445,7 @@ void GradientVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 void GradientVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
-
-  Toolkit::GradientVisual::Units::Type gradientUnits = mGradient->GetGradientUnits();
-  int roundedCorner = IsRoundedCornerRequired() ? 1 : 0;
-  VisualFactoryCache::ShaderType shaderType = SHADER_TYPE_TABLE[mGradientType][gradientUnits + roundedCorner * 2];
-  Shader shader = mFactoryCache.GetShader( shaderType );
-  if( !shader )
-  {
-    shader = Shader::New( VERTEX_SHADER[gradientUnits + roundedCorner * 2], FRAGMENT_SHADER[ mGradientType + roundedCorner * 2 ] );
-    mFactoryCache.SaveShader( shaderType, shader );
-  }
+  Shader   shader   = GetShader();
 
   //Set up the texture set
   TextureSet textureSet = TextureSet::New();
@@ -554,6 +554,21 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
   return true;
 }
 
+Shader GradientVisual::GetShader()
+{
+  Toolkit::GradientVisual::Units::Type gradientUnits = mGradient->GetGradientUnits();
+  int                                  roundedCorner = IsRoundedCornerRequired() ? 1 : 0;
+  VisualFactoryCache::ShaderType       shaderType    = SHADER_TYPE_TABLE[mGradientType][gradientUnits + roundedCorner * 2];
+  Shader                               shader        = mFactoryCache.GetShader(shaderType);
+  if(!shader)
+  {
+    shader = Shader::New(VERTEX_SHADER[gradientUnits + roundedCorner * 2], FRAGMENT_SHADER[mGradientType + roundedCorner * 2]);
+    mFactoryCache.SaveShader(shaderType, shader);
+  }
+
+  return shader;
+}
+
 void GradientVisual::GetStopOffsets(const Property::Value* value, Vector<float>& stopOffsets)
 {
 
index 70cdb4e..71ae1d6 100644 (file)
@@ -134,6 +134,11 @@ protected:
    */
   void DoSetOnScene( Actor& actor ) override;
 
+  /**
+   * @copydoc Visual::Base::UpdateShader
+   */
+  void UpdateShader() override;
+
 private:
 
   /**
@@ -149,6 +154,12 @@ private:
   bool NewGradient(Type gradientType, const Property::Map& propertyMap);
 
   /**
+   * @brief Get a shader for the current properties.
+   * @return The shader for the current properties.
+   */
+  Shader GetShader();
+
+  /**
    * Get the stop-offsets from the property.
    * The valid property type are ARRAY, VECTOR2, VECTOR3, VECTOR4.
    *
index ec130e2..22a54e6 100644 (file)
@@ -513,7 +513,6 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize )
 void ImageVisual::CreateRenderer( TextureSet& textureSet )
 {
   Geometry geometry;
-  Shader shader;
 
   // Get the geometry
   if( mImpl->mCustomShader )
@@ -534,65 +533,7 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
     }
   }
 
-  std::string vertexShader;
-  bool usesWholeTexture = true;
-  if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty())
-  {
-    vertexShader = mImpl->mCustomShader->mVertexShader;
-    usesWholeTexture = false; // Impossible to tell.
-  }
-  else
-  {
-    vertexShader = mImageVisualShaderFactory.GetVertexShaderSource().data();
-  }
-
-  std::string fragmentShader;
-  if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty())
-  {
-    fragmentShader = mImpl->mCustomShader->mFragmentShader;
-  }
-  else
-  {
-    fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource().data();
-  }
-
-  // If the texture is native, we may need to change prefix and sampler in
-  // the fragment shader
-  bool modifiedFragmentShader = false;
-  if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0)))
-  {
-    Texture nativeTexture = mTextures.GetTexture(0);
-    modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShader);
-  }
-
-  const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader;
-  if(useStandardShader)
-  {
-    // Create and cache the standard shader
-    shader = mImageVisualShaderFactory.GetShader(
-      mFactoryCache,
-      mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
-      mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE,
-      IsRoundedCornerRequired() );
-  }
-  else if(mImpl->mCustomShader)
-  {
-    shader = Shader::New(vertexShader, fragmentShader, mImpl->mCustomShader->mHints);
-  }
-  else
-  {
-    shader = Shader::New(vertexShader, fragmentShader);
-  }
-
-  if(usesWholeTexture)
-  {
-    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-  }
-
-  // Set pixel align off as default.
-  // ToDo: Pixel align causes issues such as rattling image animation.
-  // We should trun it off until issues are resolved
-  shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF );
+  Shader shader = GetShader();
 
   // Create the renderer
   mImpl->mRenderer = Renderer::New( geometry, shader );
@@ -828,6 +769,15 @@ bool ImageVisual::IsResourceReady() const
            mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED );
 }
 
+void ImageVisual::UpdateShader()
+{
+  if(mImpl->mRenderer)
+  {
+    Shader shader = GetShader();
+    mImpl->mRenderer.SetShader(shader);
+  }
+}
+
 // From existing atlas manager
 void ImageVisual::UploadCompleted()
 {
@@ -962,6 +912,73 @@ void ImageVisual::RemoveTexture()
   }
 }
 
+Shader ImageVisual::GetShader()
+{
+  Shader shader;
+
+  std::string vertexShader;
+  bool        usesWholeTexture = true;
+  if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty())
+  {
+    vertexShader     = mImpl->mCustomShader->mVertexShader;
+    usesWholeTexture = false; // Impossible to tell.
+  }
+  else
+  {
+    vertexShader = mImageVisualShaderFactory.GetVertexShaderSource().data();
+  }
+
+  std::string fragmentShader;
+  if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty())
+  {
+    fragmentShader = mImpl->mCustomShader->mFragmentShader;
+  }
+  else
+  {
+    fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource().data();
+  }
+
+  // If the texture is native, we may need to change prefix and sampler in
+  // the fragment shader
+  bool modifiedFragmentShader = false;
+  if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0)))
+  {
+    Texture nativeTexture  = mTextures.GetTexture(0);
+    modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShader);
+  }
+
+  const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader;
+  if(useStandardShader)
+  {
+    // Create and cache the standard shader
+    shader = mImageVisualShaderFactory.GetShader(
+      mFactoryCache,
+      mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
+      mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE,
+      IsRoundedCornerRequired());
+  }
+  else if(mImpl->mCustomShader)
+  {
+    shader = Shader::New(vertexShader, fragmentShader, mImpl->mCustomShader->mHints);
+  }
+  else
+  {
+    shader = Shader::New(vertexShader, fragmentShader);
+  }
+
+  if(usesWholeTexture)
+  {
+    shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
+  }
+
+  // Set pixel align off as default.
+  // ToDo: Pixel align causes issues such as rattling image animation.
+  // We should trun it off until issues are resolved
+  shader.RegisterProperty(PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF);
+
+  return shader;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index f52bd69..9ae50df 100644 (file)
@@ -229,6 +229,11 @@ protected:
    */
   bool IsResourceReady() const override;
 
+  /**
+   * @copydoc Visual::Base::UpdateShader
+   */
+  void UpdateShader() override;
+
 public:
 
   /**
@@ -318,6 +323,12 @@ private:
    */
   void DoSetProperty( Property::Index index, const Property::Value& value );
 
+  /**
+   * @brief Get a shader for the current properties.
+   * @return The shader for the current properties.
+   */
+  Shader GetShader();
+
 private:
 
   Vector4 mPixelArea;
index c7b8a14..fc962bd 100644 (file)
@@ -115,21 +115,22 @@ bool GetPolicyFromValue( const Property::Value& value, Vector2& policy )
 
 } // unnamed namespace
 
-Internal::Visual::Base::Impl::Impl( FittingMode fittingMode, Toolkit::Visual::Type type )
-: mCustomShader( NULL ),
-  mEventObserver( NULL ),
+Internal::Visual::Base::Impl::Impl(FittingMode fittingMode, Toolkit::Visual::Type type)
+: mCustomShader(NULL),
+  mEventObserver(NULL),
   mTransform(),
-  mMixColor( Color::WHITE ),
-  mControlSize( Vector2::ZERO ),
-  mCornerRadius( 0.0f ),
-  mCornerRadiusPolicy( 1.0f ),
-  mDepthIndex( 0.0f ),
-  mMixColorIndex( Property::INVALID_INDEX ),
-  mCornerRadiusIndex( Property::INVALID_INDEX ),
-  mFittingMode( fittingMode ),
-  mFlags( 0 ),
-  mResourceStatus( Toolkit::Visual::ResourceStatus::PREPARING ),
-  mType( type )
+  mMixColor(Color::WHITE),
+  mControlSize(Vector2::ZERO),
+  mCornerRadius(0.0f),
+  mCornerRadiusPolicy(1.0f),
+  mDepthIndex(0.0f),
+  mMixColorIndex(Property::INVALID_INDEX),
+  mCornerRadiusIndex(Property::INVALID_INDEX),
+  mFittingMode(fittingMode),
+  mFlags(0),
+  mResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
+  mType(type),
+  mNeedCornerRadius(false)
 {
 }
 
index ae7a93e..a1056ac 100644 (file)
@@ -134,6 +134,7 @@ struct Base::Impl
   int             mFlags;
   Toolkit::Visual::ResourceStatus  mResourceStatus;
   const Toolkit::Visual::Type      mType;
+  bool                             mNeedCornerRadius;
 };
 
 } // namespace Visual
index aca317e..6e04f0a 100755 (executable)
@@ -323,7 +323,7 @@ void Visual::Base::SetOnScene( Actor& actor )
 
       if( IsRoundedCornerRequired() )
       {
-        mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty( CORNER_RADIUS, mImpl->mCornerRadius );
+        mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::CORNER_RADIUS, CORNER_RADIUS, mImpl->mCornerRadius);
         mImpl->mRenderer.RegisterProperty( CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy );
 
         mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
@@ -340,6 +340,17 @@ void Visual::Base::SetOffScene( Actor& actor )
 {
   if( IsOnScene() )
   {
+    if(mImpl->mRenderer)
+    {
+      // Update values from Renderer
+      mImpl->mMixColor   = mImpl->mRenderer.GetProperty<Vector3>(mImpl->mMixColorIndex);
+      mImpl->mMixColor.a = mImpl->mRenderer.GetProperty<float>(DevelRenderer::Property::OPACITY);
+      if(mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+      {
+        mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<float>(mImpl->mCornerRadiusIndex);
+      }
+    }
+
     DoSetOffScene( actor );
     mImpl->mMixColorIndex = Property::INVALID_INDEX;
     mImpl->mCornerRadiusIndex = Property::INVALID_INDEX;
@@ -349,11 +360,22 @@ void Visual::Base::SetOffScene( Actor& actor )
 
 void Visual::Base::CreatePropertyMap( Property::Map& map ) const
 {
-  DoCreatePropertyMap( map );
+  if(mImpl->mRenderer)
+  {
+    // Update values from Renderer
+    mImpl->mMixColor   = mImpl->mRenderer.GetProperty<Vector3>(mImpl->mMixColorIndex);
+    mImpl->mMixColor.a = mImpl->mRenderer.GetProperty<float>(DevelRenderer::Property::OPACITY);
+    if(mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+    {
+      mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<float>(mImpl->mCornerRadiusIndex);
+    }
+  }
 
-  if( mImpl->mCustomShader )
+  DoCreatePropertyMap(map);
+
+  if(mImpl->mCustomShader)
   {
-    mImpl->mCustomShader->CreatePropertyMap( map );
+    mImpl->mCustomShader->CreatePropertyMap(map);
   }
 
   Property::Map transform;
@@ -426,7 +448,12 @@ bool Visual::Base::IsOnScene() const
 
 bool Visual::Base::IsRoundedCornerRequired() const
 {
-  return !EqualsZero( mImpl->mCornerRadius );
+  if(mImpl->mRenderer && mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+  {
+    // Update values from Renderer
+    mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<float>(mImpl->mCornerRadiusIndex);
+  }
+  return !EqualsZero(mImpl->mCornerRadius) || mImpl->mNeedCornerRadius;
 }
 
 void Visual::Base::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
@@ -479,11 +506,6 @@ void Visual::Base::SetMixColor( const Vector3& color )
   }
 }
 
-const Vector4& Visual::Base::GetMixColor() const
-{
-  return mImpl->mMixColor;
-}
-
 void Visual::Base::AddEventObserver( Visual::EventObserver& observer)
 {
   mImpl->mEventObserver = &observer;
@@ -624,21 +646,12 @@ void Visual::Base::AnimateProperty(
   }
 #endif
 
-  Property::Map map;
-  DoCreatePropertyMap( map );
-  Property::Value* valuePtr = map.Find( Toolkit::Visual::Property::TYPE );
-  int visualType = -1;
-  if( valuePtr )
-  {
-    valuePtr->Get( visualType );
-  }
-
-  if( animator.propertyKey == Toolkit::Visual::Property::MIX_COLOR ||
-      animator.propertyKey == MIX_COLOR ||
-      ( visualType == Toolkit::Visual::COLOR &&
-        animator.propertyKey == ColorVisual::Property::MIX_COLOR ) ||
-      ( visualType == Toolkit::Visual::PRIMITIVE &&
-        animator.propertyKey == PrimitiveVisual::Property::MIX_COLOR ) )
+  if(animator.propertyKey == Toolkit::Visual::Property::MIX_COLOR ||
+     animator.propertyKey == MIX_COLOR ||
+     (mImpl->mType == Toolkit::Visual::COLOR &&
+      animator.propertyKey == ColorVisual::Property::MIX_COLOR) ||
+     (mImpl->mType == Toolkit::Visual::PRIMITIVE &&
+      animator.propertyKey == PrimitiveVisual::Property::MIX_COLOR))
   {
     AnimateMixColorProperty( transition, animator );
   }
@@ -745,6 +758,65 @@ void Visual::Base::AnimateMixColorProperty(
   }
 }
 
+Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
+{
+  if(!mImpl->mRenderer)
+  {
+    Handle handle;
+    return Dali::Property(handle, Property::INVALID_INDEX);
+  }
+
+  // Mix color or opacity cases
+  if(key.type == Property::Key::INDEX)
+  {
+    if(key.indexKey == Toolkit::Visual::Property::MIX_COLOR || (mImpl->mType == Toolkit::Visual::COLOR && key.indexKey == ColorVisual::Property::MIX_COLOR) || (mImpl->mType == Toolkit::Visual::PRIMITIVE && key.indexKey == PrimitiveVisual::Property::MIX_COLOR))
+    {
+      return Dali::Property(mImpl->mRenderer, mImpl->mMixColorIndex);
+    }
+    else if(key.indexKey == Toolkit::Visual::Property::OPACITY)
+    {
+      return Dali::Property(mImpl->mRenderer, DevelRenderer::Property::OPACITY);
+    }
+  }
+  else
+  {
+    if(key.stringKey == MIX_COLOR)
+    {
+      return Dali::Property(mImpl->mRenderer, mImpl->mMixColorIndex);
+    }
+    else if(key.stringKey == OPACITY)
+    {
+      return Dali::Property(mImpl->mRenderer, DevelRenderer::Property::OPACITY);
+    }
+  }
+
+  // Other cases
+  Property::Index index = GetPropertyIndex(key);
+  if(index == Property::INVALID_INDEX)
+  {
+    if((key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::CORNER_RADIUS) || (key.type == Property::Key::STRING && key.stringKey == CORNER_RADIUS))
+    {
+      // Register CORNER_RADIUS property
+      mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::CORNER_RADIUS, CORNER_RADIUS, mImpl->mCornerRadius);
+      mImpl->mRenderer.RegisterProperty(CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
+      index = mImpl->mCornerRadiusIndex;
+
+      mImpl->mNeedCornerRadius = true;
+
+      // Change shader
+      UpdateShader();
+    }
+    else
+    {
+      // We can't find the property in the base class.
+      // Request to child class
+      return OnGetPropertyObject(key);
+    }
+  }
+
+  return Dali::Property(mImpl->mRenderer, index);
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index b925e46..8b0132e 100644 (file)
@@ -203,12 +203,6 @@ public:
   void SetMixColor( const Vector3& color );
 
   /**
-   * Gets the mix color of the visual.
-   * @return The mix color
-   */
-  const Vector4& GetMixColor() const;
-
-  /**
    * Animate the property if it exists in the visual or renderer.
    *
    * If it's a visual property such as mix color or a transform property,
@@ -279,8 +273,15 @@ public:
    */
   Toolkit::Visual::Type GetType() const;
 
- protected:
+  /**
+   * @brief Retrieve the property object associated with the property key.
+   *
+   * @param[in] key The Property key of the visual.
+   * @return The Property object
+   */
+  Dali::Property GetPropertyObject(Dali::Property::Key key);
 
+protected:
   /**
    * @brief Constructor.
    *
@@ -350,6 +351,25 @@ protected:
    */
   virtual void OnDoAction( const Property::Index actionId, const Property::Value& attributes );
 
+  /**
+   * @brief Update the shader when some properties are changed.
+   */
+  virtual void UpdateShader()
+  {
+  }
+
+  /**
+   * @brief Called by GetPropertyObject() allowing sub classes to respond to the GetPropertyObject event
+   * @note The derived class is required to register the given property.
+   * @param[in] key The key of the visual's property.
+   * @return The Property object
+   */
+  virtual Dali::Property OnGetPropertyObject(Dali::Property::Key key)
+  {
+    Handle handle;
+    return Dali::Property(handle, Property::INVALID_INDEX);
+  }
+
 protected:
 
   /**
index be3aead..bea661d 100644 (file)
@@ -107,15 +107,16 @@ enum
 
   /**
    * @brief Mix color is a blend color for any visual.
-   * @details Name "mixColor", type Property::VECTOR3 or Property::VECTOR4.
+   * @details Name "mixColor", type Property::VECTOR3 or Property::VECTOR4, animatable
    * @SINCE_1_2.60
    * @note Optional
+   * @note To animate an opacity, OPACITY property should be used.
    */
   MIX_COLOR,
 
   /**
    * @brief Opacity is the alpha component of the mixColor, above.
-   * @details Name "opacity", type Property::FLOAT.
+   * @details Name "opacity", type Property::FLOAT, animatable
    * @SINCE_1_2.60
    * @note Optional
    */