Show the broken image in case of invalid svg files
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-base-impl.cpp
index ce31fb1..a814d6b 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -77,6 +77,25 @@ Visual::Base::~Base()
   delete mImpl;
 }
 
+void Visual::Base::Initialize()
+{
+  // The Renderer should be created inside derived class here.
+  OnInitialize();
+
+  if(mImpl->mRenderer)
+  {
+    RegisterMixColor();
+
+    if(IsRoundedCornerRequired())
+    {
+      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);
+    }
+  }
+}
+
 void Visual::Base::SetCustomShader( const Property::Map& shaderMap )
 {
   if( mImpl->mCustomShader )
@@ -87,6 +106,9 @@ void Visual::Base::SetCustomShader( const Property::Map& shaderMap )
   {
     mImpl->mCustomShader = new Impl::CustomShader( shaderMap );
   }
+
+  // Let derived class know
+  UpdateShader();
 }
 
 void Visual::Base::SetProperties( const Property::Map& propertyMap )
@@ -317,22 +339,13 @@ void Visual::Base::SetOnScene( Actor& actor )
     // Thus the calling of actor.AddRenderer() should happen inside derived class as base class does not know the exact timing.
     DoSetOnScene( actor );
 
-    if( mImpl->mRenderer )
+    if(mImpl->mRenderer)
     {
-      RegisterMixColor();
-
-      if( IsRoundedCornerRequired() )
-      {
-        mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty( CORNER_RADIUS, mImpl->mCornerRadius );
-        mImpl->mRenderer.RegisterProperty( CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy );
-
-        mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
-      }
-
-      mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
-      mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
-      mImpl->mFlags |= Impl::IS_ON_SCENE; // Only sets the flag if renderer exists
+      mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
+      mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex);
     }
+
+    mImpl->mFlags |= Impl::IS_ON_SCENE;
   }
 }
 
@@ -341,19 +354,36 @@ void Visual::Base::SetOffScene( Actor& actor )
   if( IsOnScene() )
   {
     DoSetOffScene( actor );
-    mImpl->mMixColorIndex = Property::INVALID_INDEX;
-    mImpl->mCornerRadiusIndex = Property::INVALID_INDEX;
     mImpl->mFlags &= ~Impl::IS_ON_SCENE;
   }
 }
 
 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->mTransform.mOffsetIndex != Property::INVALID_INDEX)
+    {
+      mImpl->mTransform.mOffset = mImpl->mRenderer.GetProperty<Vector2>(mImpl->mTransform.mOffsetIndex);
+    }
+    if(mImpl->mTransform.mSizeIndex != Property::INVALID_INDEX)
+    {
+      mImpl->mTransform.mSize = mImpl->mRenderer.GetProperty<Vector2>(mImpl->mTransform.mSizeIndex);
+    }
+    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;
@@ -384,9 +414,6 @@ void Visual::Base::CreateInstancePropertyMap( Property::Map& map ) const
   {
     mImpl->mCustomShader->CreatePropertyMap( map );
   }
-
-  //map.Insert( Toolkit::Visual::Property::DEPTH_INDEX, mImpl->mDepthIndex );
-  //map.Insert( Toolkit::Visual::Property::ENABLED, (bool) mImpl->mRenderer );
 }
 
 
@@ -413,15 +440,9 @@ bool Visual::Base::IsPreMultipliedAlphaEnabled() const
   return mImpl->mFlags & Impl::IS_PREMULTIPLIED_ALPHA;
 }
 
-bool Visual::Base::IsAdvancedBlendEquationApplied() const
-{
-  return IsPreMultipliedAlphaEnabled() && DevelRenderer::IsAdvancedBlendEquationApplied( mImpl->mRenderer );
-}
-
 void Visual::Base::DoSetOffScene( Actor& actor )
 {
   actor.RemoveRenderer( mImpl->mRenderer );
-  mImpl->mRenderer.Reset();
 }
 
 bool Visual::Base::IsOnScene() const
@@ -431,7 +452,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 )
@@ -484,11 +510,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;
@@ -629,21 +650,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 );
   }
@@ -750,6 +762,83 @@ 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.indexKey == Toolkit::Visual::Transform::Property::OFFSET)
+    {
+      return Dali::Property(mImpl->mRenderer, OFFSET);
+    }
+    else if(key.indexKey == Toolkit::Visual::Transform::Property::SIZE)
+    {
+      return Dali::Property(mImpl->mRenderer, SIZE);
+    }
+  }
+  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);
+    }
+    else if(key.stringKey == OFFSET)
+    {
+      return Dali::Property(mImpl->mRenderer, OFFSET);
+    }
+    else if(key.stringKey == SIZE)
+    {
+      return Dali::Property(mImpl->mRenderer, SIZE);
+    }
+  }
+
+  // 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);
+
+      mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+
+      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