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;
}
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;
}
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;
END_TEST;
}
-int UtcDaliControlRendererSetDepthIndex(void)
+int UtcDaliControlRendererSetGetDepthIndex(void)
{
ToolkitTestApplication application;
tet_infoline( "UtcDaliControlRendererSetDepthIndex" );
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;
}
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;
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)
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);
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 );
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.
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.
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.
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
*/
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);
*/
// 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
{
* 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;
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
* @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
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 );
}
{
}
-void BorderRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void BorderRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
{
Initialize( factoryCache );
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 );
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
/**
* @copydoc ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const;
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
public:
{
}
-void ColorRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void ColorRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
{
Initialize( factoryCache );
//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 );
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
/**
* @copydoc ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const;
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
protected:
/**
--- /dev/null
+/*
+ * 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
*
*/
-// 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
{
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
// 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
{
ControlRenderer::ControlRenderer()
: mImpl( new Impl() )
{
- mImpl->mIsOnStage = false;
}
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;
}
}
+float ControlRenderer::GetDepthIndex() const
+{
+ return mImpl->mDepthIndex;
+}
+
void ControlRenderer::SetOnStage( Actor& actor )
{
Material material = Material::New( mImpl->mShader );
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 )
{
}
+void ControlRenderer::CreatePropertyMap( Property::Map& map ) const
+{
+ if( mImpl->mCustomShader )
+ {
+ mImpl->mCustomShader->CreatePropertyMap( map );
+ }
+ DoCreatePropertyMap( map );
+}
+
} // namespace Internal
} // namespace Toolkit
// 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>
* 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
{
* @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
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.
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
*/
/**
* @copydoc Toolkit::ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const = 0;
+ void CreatePropertyMap( Property::Map& map ) const;
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.
*/
ControlRenderer& operator=( const ControlRenderer& renderer );
protected:
-
struct Impl;
Impl* mImpl;
};
{
}
-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) )
//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 );
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
/**
* @copydoc ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const;
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
protected:
/**
// 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
{
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");
}\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()
{
}
-void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void ImageRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
{
Initialize(factoryCache);
if( imageURLValue )
{
imageURLValue->Get( mImageUrl );
+ if( !mImageUrl.empty() )
+ {
+ mImage.Reset();
+ }
Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE );
if( fittingValue )
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 )
}
}
-void ImageRenderer::CreatePropertyMap( Property::Map& map ) const
+void ImageRenderer::DoCreatePropertyMap( Property::Map& map ) const
{
map.Clear();
map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
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 )
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
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 );
/**
* @copydoc ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const;
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
protected:
/**
{
}
-void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+void NPatchRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
{
Initialize(factoryCache);
}
}
+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 );
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 );
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
/**
* @copydoc ControlRenderer::CreatePropertyMap
*/
- virtual void CreatePropertyMap( Property::Map& map ) const;
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
protected:
/**
}
}
+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
/**
* @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& )
$(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 \
mScrollDistance( SCROLL_DISTANCE ),
mTextDepth( 0u ),
mActiveCopyPastePopup( false ),
+ mPopupSetNewPosition( true ),
mCursorBlinkStatus( true ),
mDelayCursorBlink( false ),
mPrimaryCursorVisible( false ),
if( mCopyPastePopup.actor )
{
mCopyPastePopup.actor.HidePopup();
+ mPopupSetNewPosition = true;
}
}
}
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 );
SetUpPopupPositionNotifications();
mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+ mPopupSetNewPosition = false;
}
void PopupRelayoutComplete( Actor actor )
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.
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()
// Now remove references for the old text
RemoveText();
mTextCache.Swap( newTextCache );
+ RemoveAllShadowRenderTasks();
if( thereAreUnderlinedGlyphs )
{
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();
}
}
}
}
- 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
AtlasRenderer::~AtlasRenderer()
{
- mImpl->RemoveShadowRenderTask();
+ mImpl->RemoveAllShadowRenderTasks();
mImpl->RemoveText();
delete mImpl;
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
Impl(Control& controlImpl)
: mControlImpl( controlImpl ),
mStyleName(""),
- mBackground( NULL ),
+ mBackgroundRenderer(),
mStartingPinchScale( NULL ),
mKeyEventSignal(),
mPinchGestureDetector(),
~Impl()
{
// All gesture detectors will be destroyed so no need to disconnect.
- delete mBackground;
delete mStartingPinchScale;
}
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
/**
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;
}
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;
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;
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)
}
}
- 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()
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 )
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 );
}
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();
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
};
};
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
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