Fix various SVACE errors
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / gradient / gradient-visual.cpp
index 8c0de84..bfc9130 100644 (file)
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/images/buffer-image.h>
 #include <dali/public-api/object/property-array.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+#include <dali/devel-api/scripting/scripting.h>
 
-//INTERNAL INCLUDES
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/gradient-visual-properties.h>
+#include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -58,12 +62,16 @@ const char * const STOP_COLOR_NAME("stopColor"); // Property::Array VECTOR4
 const char * const UNITS_NAME("units"); // Property::String  "userSpaceOnUse | objectBoundingBox"
 const char * const SPREAD_METHOD_NAME("spreadMethod"); // Property::String  "pad | reflect | repeat"
 
-// string values
-const char * const UNIT_USER_SPACE("USER_SPACE");
-const char * const UNIT_BOUNDING_BOX("OBJECT_BOUNDING_BOX");
-const char * const SPREAD_PAD("PAD");
-const char * const SPREAD_REFLECT("REFLECT");
-const char * const SPREAD_REPEAT("REPEAT");
+DALI_ENUM_TO_STRING_TABLE_BEGIN( UNITS )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::GradientVisual::Units, OBJECT_BOUNDING_BOX )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::GradientVisual::Units, USER_SPACE )
+DALI_ENUM_TO_STRING_TABLE_END( UNITS )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( SPREAD_METHOD )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::GradientVisual::SpreadMethod, PAD )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::GradientVisual::SpreadMethod, REFLECT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::GradientVisual::SpreadMethod, REPEAT )
+DALI_ENUM_TO_STRING_TABLE_END( SPREAD_METHOD )
 
 // uniform names
 const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" );
@@ -72,17 +80,17 @@ const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" );
 const unsigned int DEFAULT_OFFSET_MINIMUM = 0.0f;
 const unsigned int DEFAULT_OFFSET_MAXIMUM = 1.0f;
 
-VisualFactoryCache::ShaderType GetShaderType( GradientVisual::Type type, Gradient::GradientUnits units)
+VisualFactoryCache::ShaderType GetShaderType( GradientVisual::Type type, Toolkit::GradientVisual::Units::Type units )
 {
-  if( type==GradientVisual::LINEAR )
+  if( type == GradientVisual::LINEAR )
   {
-   if( units == Gradient::USER_SPACE_ON_USE )
+   if( units == Toolkit::GradientVisual::Units::USER_SPACE )
    {
      return VisualFactoryCache::GRADIENT_SHADER_LINEAR_USER_SPACE;
    }
    return VisualFactoryCache::GRADIENT_SHADER_LINEAR_BOUNDING_BOX;
   }
-  else if( units == Gradient::USER_SPACE_ON_USE )
+  else if( units == Toolkit::GradientVisual::Units::USER_SPACE )
   {
     return VisualFactoryCache::GRADIENT_SHADER_RADIAL_USER_SPACE;
   }
@@ -92,39 +100,68 @@ VisualFactoryCache::ShaderType GetShaderType( GradientVisual::Type type, Gradien
 
 const char* VERTEX_SHADER[] =
 {
-// vertex shader for gradient units as USER_SPACE_ON_USE
-DALI_COMPOSE_SHADER(
+// vertex shader for gradient units as OBJECT_BOUNDING_BOX
+ DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   \n
+
+  //Visual size and offset
+  uniform mediump vec2 offset;\n
+  uniform mediump vec2 size;\n
+  uniform mediump vec4 offsetSizeMode;\n
+  uniform mediump vec2 origin;\n
+  uniform mediump vec2 anchorPoint;\n
+
+  vec4 ComputeVertexPosition()\n
+  {\n
+    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
+    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
+    return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
+  }\n
+
   void main()\n
   {\n
     mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
-    vertexPosition.xyz *= uSize;\n
-    gl_Position = uMvpMatrix * vertexPosition;\n
-    \n
     vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n
+    \n
+    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
   }\n
 ),
 
-// vertex shader for gradient units as OBJECT_BOUNDING_BOX
- DALI_COMPOSE_SHADER(
+// vertex shader for gradient units as USER_SPACE
+DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   \n
+
+  //Visual size and offset
+  uniform mediump vec2 offset;\n
+  uniform mediump vec2 size;\n
+  uniform mediump vec4 offsetSizeMode;\n
+  uniform mediump vec2 origin;\n
+  uniform mediump vec2 anchorPoint;\n
+
+  vec4 ComputeVertexPosition()\n
+  {\n
+    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
+    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
+    return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
+  }\n
+
   void main()\n
   {\n
     mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
-    vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n
-    \n
     vertexPosition.xyz *= uSize;\n
-    gl_Position = uMvpMatrix * vertexPosition;\n
+    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
+    \n
+    vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n
   }\n
 )
 };
@@ -156,19 +193,19 @@ DALI_COMPOSE_SHADER(
 )
 };
 
-Dali::WrapMode::Type GetWrapMode( Gradient::SpreadMethod spread )
+Dali::WrapMode::Type GetWrapMode( Toolkit::GradientVisual::SpreadMethod::Type spread )
 {
   switch(spread)
   {
-    case Gradient::REPEAT:
+    case Toolkit::GradientVisual::SpreadMethod::REPEAT:
     {
       return Dali::WrapMode::REPEAT;
     }
-    case Gradient::REFLECT:
+    case Toolkit::GradientVisual::SpreadMethod::REFLECT:
     {
       return Dali::WrapMode::MIRRORED_REPEAT;
     }
-    case Gradient::PAD:
+    case Toolkit::GradientVisual::SpreadMethod::PAD:
     default:
     {
       return Dali::WrapMode::CLAMP_TO_EDGE;
@@ -176,12 +213,17 @@ Dali::WrapMode::Type GetWrapMode( Gradient::SpreadMethod spread )
   }
 }
 
-}
+} // unnamed namespace
 
+GradientVisualPtr GradientVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new GradientVisual( factoryCache );
+}
 
 GradientVisual::GradientVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
-  mGradientType( LINEAR )
+  mGradientType( LINEAR ),
+  mIsOpaque( true )
 {
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
 }
@@ -190,20 +232,18 @@ GradientVisual::~GradientVisual()
 {
 }
 
-void GradientVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void GradientVisual::DoSetProperties( const Property::Map& propertyMap )
 {
-  Gradient::GradientUnits gradientUnits = Gradient::OBJECT_BOUNDING_BOX;
-  Property::Value* unitsValue = propertyMap.Find( UNITS_NAME );
-  std::string units;
-  // The default unit is OBJECT_BOUNDING_BOX.
-  // Only need to set new units if 'USER_SPACE'
-  if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE )
+  Toolkit::GradientVisual::Units::Type gradientUnits = Toolkit::GradientVisual::Units::OBJECT_BOUNDING_BOX;
+
+  Property::Value* unitsValue = propertyMap.Find( Toolkit::GradientVisual::Property::UNITS, UNITS_NAME );
+  if( unitsValue )
   {
-    gradientUnits = Gradient::USER_SPACE_ON_USE;
+    Scripting::GetEnumerationProperty( *unitsValue, UNITS_TABLE, UNITS_TABLE_COUNT, gradientUnits );
   }
 
   mGradientType = LINEAR;
-  if( propertyMap.Find( RADIUS_NAME ))
+  if( propertyMap.Find( Toolkit::GradientVisual::Property::RADIUS, RADIUS_NAME ) )
   {
     mGradientType = RADIAL;
   }
@@ -215,60 +255,36 @@ void GradientVisual::DoInitialize( Actor& actor, const Property::Map& propertyMa
   }
   else
   {
-    DALI_LOG_ERROR( "Fail to provide valid properties to create a GradientVisual object" );
+    DALI_LOG_ERROR( "Fail to provide valid properties to create a GradientVisual object\n" );
   }
 }
 
-void GradientVisual::SetSize( const Vector2& size )
-{
-  Visual::Base::SetSize( size );
-}
-
-void GradientVisual::SetClipRect( const Rect<int>& clipRect )
+void GradientVisual::OnSetTransform()
 {
-  Visual::Base::SetClipRect( clipRect );
-
-  //ToDo: renderer responds to the clipRect change
+  if( mImpl->mRenderer )
+  {
+    mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+  }
 }
 
-void GradientVisual::SetOffset( const Vector2& offset )
+void GradientVisual::SetSize( const Vector2& size )
 {
-  //ToDo: renderer applies the offset
+  Visual::Base::SetSize( size );
 }
 
 void GradientVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
+
+  actor.AddRenderer( mImpl->mRenderer );
 }
 
 void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
-  map.Insert( RENDERER_TYPE, GRADIENT_RENDERER );
-
-  Gradient::GradientUnits units = mGradient->GetGradientUnits();
-  if( units == Gradient::USER_SPACE_ON_USE )
-  {
-    map.Insert( UNITS_NAME, UNIT_USER_SPACE );
-  }
-  else // if( units == Gradient::OBJECT_BOUNDING_BOX )
-  {
-    map.Insert( UNITS_NAME, UNIT_BOUNDING_BOX );
-  }
-
-  Gradient::SpreadMethod spread = mGradient->GetSpreadMethod();
-  if( spread == Gradient::PAD )
-  {
-    map.Insert( SPREAD_METHOD_NAME, SPREAD_PAD );
-  }
-  else if( spread == Gradient::REFLECT )
-  {
-    map.Insert( SPREAD_METHOD_NAME, SPREAD_REFLECT );
-  }
-  else // if( units == Gradient::REPEAT )
-  {
-    map.Insert( SPREAD_METHOD_NAME, SPREAD_REPEAT );
-  }
+  map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::GRADIENT );
+  map.Insert( Toolkit::GradientVisual::Property::UNITS, mGradient->GetGradientUnits() );
+  map.Insert( Toolkit::GradientVisual::Property::SPREAD_METHOD, mGradient->GetSpreadMethod() );
 
   const Vector<Gradient::GradientStop>& stops( mGradient->GetStops() );
   Property::Array offsets;
@@ -289,23 +305,34 @@ void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
     }
   }
 
-  map.Insert( STOP_OFFSET_NAME, offsets );
-  map.Insert( STOP_COLOR_NAME, colors );
+  map.Insert( Toolkit::GradientVisual::Property::STOP_OFFSET, offsets );
+  map.Insert( Toolkit::GradientVisual::Property::STOP_COLOR, colors );
 
   if( &typeid( *mGradient ) == &typeid(LinearGradient) )
   {
     LinearGradient* gradient = static_cast<LinearGradient*>( mGradient.Get() );
-    map.Insert( START_POSITION_NAME, gradient->GetStartPosition() );
-    map.Insert( END_POSITION_NAME, gradient->GetEndPosition() );
+    map.Insert( Toolkit::GradientVisual::Property::START_POSITION, gradient->GetStartPosition() );
+    map.Insert( Toolkit::GradientVisual::Property::END_POSITION, gradient->GetEndPosition() );
   }
   else // if( &typeid( *mGradient ) == &typeid(RadialGradient) )
   {
     RadialGradient* gradient = static_cast<RadialGradient*>( mGradient.Get() );
-    map.Insert( CENTER_NAME, gradient->GetCenter() );
-    map.Insert( RADIUS_NAME, gradient->GetRadius() );
+    map.Insert( Toolkit::GradientVisual::Property::CENTER, gradient->GetCenter() );
+    map.Insert( Toolkit::GradientVisual::Property::RADIUS, gradient->GetRadius() );
   }
 }
 
+void GradientVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value GradientVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void GradientVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
@@ -315,7 +342,7 @@ void GradientVisual::InitializeRenderer()
     mFactoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry );
   }
 
-  Gradient::GradientUnits gradientUnits = mGradient->GetGradientUnits();
+  Toolkit::GradientVisual::Units::Type gradientUnits = mGradient->GetGradientUnits();
   VisualFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, gradientUnits );
   Shader shader = mFactoryCache.GetShader( shaderType );
   if( !shader )
@@ -336,15 +363,24 @@ void GradientVisual::InitializeRenderer()
   mImpl->mRenderer = Renderer::New( geometry, shader );
   mImpl->mRenderer.SetTextures( textureSet );
 
+  // If opaque then no need to have blending
+  if( mIsOpaque )
+  {
+    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
+  }
+
   mImpl->mRenderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
+
+  //Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
 }
 
 bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propertyMap)
 {
-  if( gradientType==LINEAR )
+  if( gradientType == LINEAR )
   {
-    Property::Value* startPositionValue = propertyMap.Find( START_POSITION_NAME );
-    Property::Value* endPositionValue = propertyMap.Find( END_POSITION_NAME );
+    Property::Value* startPositionValue = propertyMap.Find( Toolkit::GradientVisual::Property::START_POSITION, START_POSITION_NAME );
+    Property::Value* endPositionValue = propertyMap.Find( Toolkit::GradientVisual::Property::END_POSITION, END_POSITION_NAME );
     Vector2 startPosition;
     Vector2 endPosition;
 
@@ -360,8 +396,8 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
   }
   else // type==RADIAL
   {
-    Property::Value* centerValue = propertyMap.Find( CENTER_NAME );
-    Property::Value* radiusValue = propertyMap.Find( RADIUS_NAME );
+    Property::Value* centerValue = propertyMap.Find( Toolkit::GradientVisual::Property::CENTER, CENTER_NAME );
+    Property::Value* radiusValue = propertyMap.Find( Toolkit::GradientVisual::Property::RADIUS, RADIUS_NAME );
     Vector2 center;
     float radius;
     if( centerValue && centerValue->Get(center)
@@ -376,8 +412,8 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
   }
 
   unsigned int numValidStop = 0u;
-  Property::Value* stopOffsetValue = propertyMap.Find( STOP_OFFSET_NAME );
-  Property::Value* stopColorValue = propertyMap.Find( STOP_COLOR_NAME );
+  Property::Value* stopOffsetValue = propertyMap.Find( Toolkit::GradientVisual::Property::STOP_OFFSET, STOP_OFFSET_NAME );
+  Property::Value* stopColorValue = propertyMap.Find( Toolkit::GradientVisual::Property::STOP_COLOR, STOP_COLOR_NAME );
   if( stopColorValue )
   {
     Vector<float> offsetArray;
@@ -394,6 +430,10 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
         {
           mGradient->AddStop( offsetArray[i], Vector4(color.r*color.a, color.g*color.a, color.b*color.a, color.a));
           numValidStop++;
+          if( ! Equals( color.a, 1.0f, Math::MACHINE_EPSILON_1 ) )
+          {
+            mIsOpaque = false;
+          }
         }
       }
     }
@@ -404,19 +444,14 @@ bool GradientVisual::NewGradient(Type gradientType, const Property::Map& propert
     return false;
   }
 
-  Property::Value* spread = propertyMap.Find( SPREAD_METHOD_NAME );
-  std::string stringValue ;
-  // The default spread method is PAD.
-  // Only need to set new spread if 'reflect' or 'repeat"
-  if( spread && spread->Get( stringValue ))
+  Property::Value* spread = propertyMap.Find( Toolkit::GradientVisual::Property::SPREAD_METHOD, SPREAD_METHOD_NAME );
+  // The default spread method is PAD. Only need to set new spread if it's anything else.
+  if( spread )
   {
-    if( stringValue == SPREAD_REFLECT )
-    {
-      mGradient->SetSpreadMethod( Gradient::REFLECT );
-    }
-    else if( stringValue == SPREAD_REPEAT )
+    Toolkit::GradientVisual::SpreadMethod::Type spreadMethod = Toolkit::GradientVisual::SpreadMethod::PAD;
+    if( Scripting::GetEnumerationProperty( *spread, SPREAD_METHOD_TABLE, SPREAD_METHOD_TABLE_COUNT, spreadMethod ) )
     {
-      mGradient->SetSpreadMethod( Gradient::REPEAT );
+      mGradient->SetSpreadMethod( spreadMethod );
     }
   }