}
/**
- * @copydoc PlatformAbstraction::GetDefaultFontDescription()
- */
-void TestPlatformAbstraction::GetDefaultFontDescription( std::string& family, std::string& style ) const
-{
- // TODO
-}
-
-/**
* @copydoc PlatformAbstraction::GetDefaultFontSize()
*/
int TestPlatformAbstraction::GetDefaultFontSize() const
virtual bool IsLoading();
/**
- * @copydoc PlatformAbstraction::GetDefaultFontDescription()
- */
- virtual void GetDefaultFontDescription( std::string& family, std::string& style ) const;
-
- /**
* @copydoc PlatformAbstraction::GetDefaultFontSize()
*/
virtual int GetDefaultFontSize() const;
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;
using namespace Dali;
using namespace Dali::Toolkit;
+namespace
+{
+const char* TEST_IMAGE_FILE_NAME = "gallery_image_01.jpg";
+const char* TEST_NPATCH_FILE_NAME = "gallery_image_01.9.jpg";
+}
+
void dali_control_renderer_startup(void)
{
test_return_value = TET_UNDEF;
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;
}
-int UtcDaliControlRendererSetOnStage(void)
+int UtcDaliControlRendererSetOnOffStage(void)
{
ToolkitTestApplication application;
tet_infoline( "UtcDaliControlRendererSetDepthIndex" );
DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
controlRenderer.SetOnStage( actor );
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+ controlRenderer.SetOffStage( actor );
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+ 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;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap1: ColorRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ Property::Map propertyMap;
+ propertyMap.Insert("renderer-type", "color-renderer");
+ propertyMap.Insert("blend-color", Color::BLUE);
+ ControlRenderer colorRenderer = factory.GetControlRenderer( propertyMap );
+
+ Property::Map resultMap;
+ colorRenderer.CreatePropertyMap( resultMap );
+
+ Property::Value* typeValue = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( typeValue );
+ DALI_TEST_CHECK( typeValue->Get<std::string>() == "color-renderer" );
+
+ Property::Value* colorValue = resultMap.Find( "blend-color", Property::VECTOR4 );
+ DALI_TEST_CHECK( colorValue );
+ DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
+
+ // change the blend color
+ factory.ResetRenderer( colorRenderer, Color::CYAN );
+ colorRenderer.CreatePropertyMap( resultMap );
+
+ colorValue = resultMap.Find( "blend-color", Property::VECTOR4 );
+ DALI_TEST_CHECK( colorValue );
+ DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::CYAN );
+
+ END_TEST;
+}
+
+int UtcDaliControlRendererGetPropertyMap2(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap2: BorderRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ Property::Map propertyMap;
+ propertyMap.Insert("renderer-type", "border-renderer");
+ propertyMap.Insert("border-color", Color::BLUE);
+ propertyMap.Insert("border-size", 5.f);
+ ControlRenderer borderRenderer = factory.GetControlRenderer( propertyMap );
+
+ Property::Map resultMap;
+ borderRenderer.CreatePropertyMap( resultMap );
+
+ // check the property values from the returned map from control renderer
+ Property::Value* typeValue = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( typeValue );
+ DALI_TEST_CHECK( typeValue->Get<std::string>() == "border-renderer" );
+
+ Property::Value* colorValue = resultMap.Find( "border-color", Property::VECTOR4 );
+ DALI_TEST_CHECK( colorValue );
+ DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
+
+ Property::Value* sizeValue = resultMap.Find( "border-size", Property::FLOAT );
+ DALI_TEST_CHECK( sizeValue );
+ DALI_TEST_CHECK( sizeValue->Get<float>() == 5.f );
+
+ borderRenderer = factory.GetControlRenderer( 10.f, Color::CYAN );
+ borderRenderer.CreatePropertyMap( resultMap );
+
+ typeValue = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( typeValue );
+ DALI_TEST_CHECK( typeValue->Get<std::string>() == "border-renderer" );
+
+ colorValue = resultMap.Find( "border-color", Property::VECTOR4 );
+ DALI_TEST_CHECK( colorValue );
+ DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::CYAN );
+
+ colorValue = resultMap.Find( "border-size", Property::FLOAT );
+ DALI_TEST_CHECK( colorValue );
+ DALI_TEST_CHECK( colorValue->Get<float>() == 10.f );
+
+ END_TEST;
+}
+
+int UtcDaliControlRendererGetPropertyMap3(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap3: linear GradientRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ 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-spread-method", "repeat");
+
+ propertyMap.Insert("gradient-stop-offset", Vector2(0.2f, 0.8f));
+
+ Property::Array stopColors;
+ stopColors.PushBack( Color::RED );
+ stopColors.PushBack( Color::GREEN );
+ propertyMap.Insert("gradient-stop-color", stopColors);
+
+ ControlRenderer gradientRenderer = factory.GetControlRenderer(propertyMap);
+
+ Property::Map resultMap;
+ gradientRenderer.CreatePropertyMap( resultMap );
+
+ // check the property values from the returned map from control renderer
+ Property::Value* value = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "gradient-renderer" );
+
+ value = resultMap.Find( "gradient-units", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "object-bounding-box" );
+
+ value = resultMap.Find( "gradient-spread-method", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "repeat" );
+
+ value = resultMap.Find( "gradient-start-position", Property::VECTOR2 );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( value->Get<Vector2>(), start , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-end-position", Property::VECTOR2 );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( value->Get<Vector2>(), end , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-stop-offset", Property::ARRAY );
+ DALI_TEST_CHECK( value );
+ Property::Array* offsetArray = value->GetArray();
+ DALI_TEST_CHECK( offsetArray->Count() == 2 );
+ DALI_TEST_EQUALS( offsetArray->GetElementAt(0).Get<float>(), 0.2f , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ DALI_TEST_EQUALS( offsetArray->GetElementAt(1).Get<float>(), 0.8f , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-stop-color", Property::ARRAY );
+ DALI_TEST_CHECK( value );
+ Property::Array* colorArray = value->GetArray();
+ DALI_TEST_CHECK( colorArray->Count() == 2 );
+ DALI_TEST_EQUALS( colorArray->GetElementAt(0).Get<Vector4>(), Color::RED , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ DALI_TEST_EQUALS( colorArray->GetElementAt(1).Get<Vector4>(), Color::GREEN , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliControlRendererGetPropertyMap4(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap4: radial GradientRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ Property::Map propertyMap;
+ propertyMap.Insert("renderer-type", "gradient-renderer");
+
+ Vector2 center(100.f, 100.f);
+ float radius = 100.f;
+ propertyMap.Insert("gradient-units", "user-space");
+ propertyMap.Insert("gradient-center", center);
+ propertyMap.Insert("gradient-radius", radius);
+ propertyMap.Insert("gradient-stop-offset", Vector3(0.1f, 0.3f, 1.1f));
+
+ Property::Array stopColors;
+ stopColors.PushBack( Color::RED );
+ stopColors.PushBack( Color::BLACK );
+ stopColors.PushBack( Color::GREEN );
+ propertyMap.Insert("gradient-stop-color", stopColors);
+
+ ControlRenderer gradientRenderer = factory.GetControlRenderer(propertyMap);
+ DALI_TEST_CHECK( gradientRenderer );
+
+ Property::Map resultMap;
+ gradientRenderer.CreatePropertyMap( resultMap );
+
+ // check the property values from the returned map from control renderer
+ Property::Value* value = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "gradient-renderer" );
+
+ value = resultMap.Find( "gradient-units", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "user-space" );
+
+ value = resultMap.Find( "gradient-spread-method", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "pad" );
+
+ value = resultMap.Find( "gradient-center", Property::VECTOR2 );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( value->Get<Vector2>(), center , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-radius", Property::FLOAT );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( value->Get<float>(), radius , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-stop-offset", Property::ARRAY );
+ DALI_TEST_CHECK( value );
+ Property::Array* offsetArray = value->GetArray();
+ DALI_TEST_CHECK( offsetArray->Count() == 3 );
+ DALI_TEST_EQUALS( offsetArray->GetElementAt(0).Get<float>(), 0.1f , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ DALI_TEST_EQUALS( offsetArray->GetElementAt(1).Get<float>(), 0.3f , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ // any stop value will be clamped to [0.0, 1.0];
+ DALI_TEST_EQUALS( offsetArray->GetElementAt(2).Get<float>(), 1.0f , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ value = resultMap.Find( "gradient-stop-color", Property::ARRAY );
+ DALI_TEST_CHECK( value );
+ Property::Array* colorArray = value->GetArray();
+ DALI_TEST_CHECK( colorArray->Count() == 3 );
+ DALI_TEST_EQUALS( colorArray->GetElementAt(0).Get<Vector4>(), Color::RED , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ DALI_TEST_EQUALS( colorArray->GetElementAt(1).Get<Vector4>(), Color::BLACK , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+ DALI_TEST_EQUALS( colorArray->GetElementAt(2).Get<Vector4>(), Color::GREEN , Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliControlRendererGetPropertyMap5(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap5: ImageRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ Property::Map propertyMap;
+ propertyMap.Insert( "renderer-type", "image-renderer" );
+ propertyMap.Insert( "image-url", TEST_IMAGE_FILE_NAME );
+ propertyMap.Insert( "image-desired-width", 20 );
+ propertyMap.Insert( "image-desired-height", 30 );
+ propertyMap.Insert( "image-fitting-mode", "fit-height" );
+ propertyMap.Insert( "image-sampling-mode", "box-then-nearest" );
+
+ ControlRenderer imageRenderer = factory.GetControlRenderer(propertyMap);
+ DALI_TEST_CHECK( imageRenderer );
+
+ Property::Map resultMap;
+ imageRenderer.CreatePropertyMap( resultMap );
+
+ // check the property values from the returned map from control renderer
+ Property::Value* value = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "image-renderer" );
+
+ value = resultMap.Find( "image-url", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == TEST_IMAGE_FILE_NAME );
+
+ value = resultMap.Find( "image-fitting-mode", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "fit-height" );
+
+ value = resultMap.Find( "image-sampling-mode", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "box-then-nearest" );
+
+ value = resultMap.Find( "image-desired-width", Property::INTEGER );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<int>() == 20 );
+
+ value = resultMap.Find( "image-desired-height", Property::INTEGER );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<int>() == 30 );
+
+ // Get an image renderer with an image handle, and test the default property values
+ Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
+ imageRenderer = factory.GetControlRenderer(image);
+ imageRenderer.CreatePropertyMap( resultMap );
+
+ value = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "image-renderer" );
+
+ value = resultMap.Find( "image-url", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == TEST_IMAGE_FILE_NAME );
+
+ value = resultMap.Find( "image-fitting-mode", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "shrink-to-fit" );
+
+ value = resultMap.Find( "image-sampling-mode", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "box" );
+
+ value = resultMap.Find( "image-desired-width", Property::INTEGER );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<int>() == 100 );
+
+ value = resultMap.Find( "image-desired-height", Property::INTEGER );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<int>() == 200 );
+
+ END_TEST;
+}
+
+int UtcDaliControlRendererGetPropertyMap6(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliControlRendererGetPropertyMap6: NPatchRenderer" );
+
+ RendererFactory factory = RendererFactory::Get();
+ Property::Map propertyMap;
+ propertyMap.Insert( "renderer-type", "n-patch-renderer" );
+ propertyMap.Insert( "image-url", TEST_NPATCH_FILE_NAME );
+ propertyMap.Insert( "border-only", true );
+ ControlRenderer nPatchRenderer = factory.GetControlRenderer( propertyMap );
+
+ Property::Map resultMap;
+ nPatchRenderer.CreatePropertyMap( resultMap );
+
+ // check the property values from the returned map from control renderer
+ Property::Value* value = resultMap.Find( "renderer-type", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == "n-patch-renderer" );
+
+ value = resultMap.Find( "image-url", Property::STRING );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<std::string>() == TEST_NPATCH_FILE_NAME );
+
+ value = resultMap.Find( "border-only", Property::BOOLEAN );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get<bool>() );
+
END_TEST;
}
DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
+ controlRenderer.SetOffStage( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
END_TEST;
}
DALI_TEST_CHECK( gl.GetUniformValue<float>( "uBorderSize", actualSize ) );
DALI_TEST_EQUALS( actualSize, testSize, TEST_LOCATION );
+ controlRenderer.SetOffStage( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
END_TEST;
}
application.SendNotification();
application.Render(0);
+ controlRenderer.SetOffStage( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
END_TEST;
}
DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+ controlRenderer.SetOffStage( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
END_TEST;
}
DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+ controlRenderer.SetOffStage( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
END_TEST;
}
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);
}
+void ControlRenderer::SetOffStage( Actor& actor )
+{
+ GetImplementation( *this ).SetOffStage(actor);
+}
+
+void ControlRenderer::RemoveAndReset( Actor& actor )
+{
+ if( actor && *this )
+ {
+ SetOffStage( actor );
+ }
+ Reset();
+}
+
+void ControlRenderer::CreatePropertyMap( Property::Map& map ) const
+{
+ GetImplementation( *this ).CreatePropertyMap( map );
+}
+
} // namespace Toolkit
} // namespace Dali
}
/**
- * ControlRenderer provides renderer for rendering the controls. A control may have multiple ControlRenders.
+ * @brief ControlRenderer provides renderer for rendering the controls. A control may have multiple ControlRenders.
+ *
* ControlRenderers reuses geometry, shader etc. across controls and manages the renderer and material to exist only when control is on-stage.
* It also responds to actor size and color change, and provides the clipping at the renderer level.
* Note: The control renderer responds to the the Actor::COLOR by blending it with the 'Multiply' operator.
ControlRenderer& operator=( const ControlRenderer& handle );
/**
- * Set the size of the painting area.
+ * @brief Set the size of the painting area.
*
* @param[in] size The size of the painting area.
*/
void SetSize( const Vector2& size );
/**
- * Set the depth index of this renderer.
+ * @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.
* Renderer with higher depth indices are rendered in front of other renderer with smaller values
*
void SetDepthIndex( float index );
/**
- * Renderer only exists when control is on stage.
+ * @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.
*
* @param[in] actor The actor applying this renderer.
*/
void SetOnStage( Actor& actor );
+ /**
+ * @brief Renderer is destroyed when control is off stage.
+ *
+ * This function should be called when the control removes from stage
+ *
+ * @param[in] actor The actor applying this renderer.
+ */
+ 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.
+ */
+ void CreatePropertyMap( Property::Map& map ) const;
+
public: // Not intended for application developers
explicit DALI_INTERNAL ControlRenderer(Internal::ControlRenderer *impl);
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
}
/**
- * RendererFactory is a singleton object that provides and shares renderers for controls
+ * @brief RendererFactory is a singleton object that provides and shares renderers for controls
*
* The renderer type is required in the property map for requesting a control renderer.
*
*/
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 );
}
namespace
{
+const char * const RENDERER_TYPE("renderer-type");
+const char * const RENDERER_TYPE_VALUE("border-renderer");
+
const char * const COLOR_NAME("border-color");
const char * const COLOR_UNIFORM_NAME("uBorderColor");
const char * const SIZE_NAME("border-size");
{
}
-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::DoCreatePropertyMap( Property::Map& map ) const
+{
+ map.Clear();
+ map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+ map.Insert( COLOR_NAME, mBorderColor );
+ map.Insert( SIZE_NAME, mBorderSize );
+}
+
void BorderRenderer::Initialize( RendererFactoryCache& factoryCache)
{
mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::BORDER_GEOMETRY );
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
*/
virtual void DoSetOnStage( Actor& actor );
+ /**
+ * @copydoc ControlRenderer::CreatePropertyMap
+ */
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
public:
/**
namespace
{
+const char * const RENDERER_TYPE("renderer-type");
+const char * const RENDERER_TYPE_VALUE("color-renderer");
const char * const COLOR_NAME("blend-color");
const char * const COLOR_UNIFORM_NAME("uBlendColor");
{
}
-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::DoCreatePropertyMap( Property::Map& map ) const
+{
+ map.Clear();
+ map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+ map.Insert( COLOR_NAME, mBlendColor );
+}
+
void ColorRenderer::DoSetOnStage( Actor& actor )
{
mBlendColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor );
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 SetOffset( const Vector2& offset );
+ /**
+ * @copydoc ControlRenderer::CreatePropertyMap
+ */
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
protected:
/**
* @copydoc ControlRenderer::DoSetOnStage
--- /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
*/
void SetOnStage( Actor& actor );
/**
- * ToDo: Add this function to Toolkit::ControlRenderer when the Renderer can be removed from actor properly.
- *
- * Renderer is destroyed when control is off stage.
- * This function should be called when the control removes from stage
- *
- * @param[in] actor The actor applying this renderer.
+ * @copydoc Toolkit::ControlRenderer::SetOffStage
*/
void SetOffStage( Actor& actor );
+ /**
+ * @copydoc Toolkit::ControlRenderer::CreatePropertyMap
+ */
+ 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;
/**
- * Called by SetOnStage() allowing sub classes to respond to the SetOnStage event
+ * @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:
+
+ /**
+ * @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;
};
#include "gradient-renderer.h"
// EXTERNAL INCLUDES
+#include <typeinfo>
#include <dali/integration-api/debug.h>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/images/buffer-image.h>
namespace
{
+const char * const RENDERER_TYPE("renderer-type");
+const char * const RENDERER_TYPE_VALUE("gradient-renderer");
+
// properties: linear gradient
const char * const GRADIENT_START_POSITION_NAME("gradient-start-position"); // Property::VECTOR2
const char * const GRADIENT_END_POSITION_NAME("gradient-end-position"); // Property::VECTOR2
// 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");
{
}
-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::DoCreatePropertyMap( Property::Map& map ) const
+{
+ map.Clear();
+ map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+
+ Gradient::GradientUnits units = mGradient->GetGradientUnits();
+ if( units == Gradient::USER_SPACE_ON_USE )
+ {
+ map.Insert( GRADIENT_UNITS_NAME, UNIT_USER_SPACE );
+ }
+ else // if( units == Gradient::OBJECT_BOUNDING_BOX )
+ {
+ map.Insert( GRADIENT_UNITS_NAME, UNIT_BOUNDING_BOX );
+ }
+
+ Gradient::SpreadMethod spread = mGradient->GetSpreadMethod();
+ if( spread == Gradient::PAD )
+ {
+ map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_PAD );
+ }
+ else if( spread == Gradient::REFLECT )
+ {
+ map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REFLECT );
+ }
+ else // if( units == Gradient::REPEAT )
+ {
+ map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REPEAT );
+ }
+
+ const Vector<Gradient::GradientStop>& stops( mGradient->GetStops() );
+ Property::Array offsets;
+ Property::Array colors;
+ for( unsigned int i=0; i<stops.Count(); i++ )
+ {
+ offsets.PushBack( stops[i].mOffset );
+ colors.PushBack( stops[i].mStopColor );
+ }
+
+ map.Insert( GRADIENT_STOP_OFFSET_NAME, offsets );
+ map.Insert( GRADIENT_STOP_COLOR_NAME, colors );
+
+ if( &typeid( *mGradient ) == &typeid(LinearGradient) )
+ {
+ LinearGradient* gradient = static_cast<LinearGradient*>( mGradient.Get() );
+ map.Insert( GRADIENT_START_POSITION_NAME, gradient->GetStartPosition() );
+ map.Insert( GRADIENT_END_POSITION_NAME, gradient->GetEndPosition() );
+ }
+ else // if( &typeid( *mGradient ) == &typeid(RadialGradient) )
+ {
+ RadialGradient* gradient = static_cast<RadialGradient*>( mGradient.Get() );
+ map.Insert( GRADIENT_CENTER_NAME, gradient->GetCenter() );
+ map.Insert( GRADIENT_RADIUS_NAME, gradient->GetRadius() );
+ }
+}
+
void GradientRenderer::DoSetOnStage( Actor& actor )
{
mGradientTransformIndex = (mImpl->mRenderer).RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
Property::Value* stopColorValue = propertyMap.Find( GRADIENT_STOP_COLOR_NAME );
if( stopOffsetValue && stopColorValue )
{
- Property::Array* offsetArray = stopOffsetValue->GetArray();
+ Vector<float> offsetArray;
Property::Array* colorArray = stopColorValue->GetArray();
- if( offsetArray && colorArray )
+ if( colorArray && GetStopOffsets( stopOffsetValue, offsetArray ))
{
- unsigned int numStop = offsetArray->Count() < colorArray->Count() ?
- offsetArray->Count() : colorArray->Count();
- float offset;
+ unsigned int numStop = offsetArray.Count() < colorArray->Count() ?
+ offsetArray.Count() : colorArray->Count();
Vector4 color;
for( unsigned int i=0; i<numStop; i++ )
{
- if( (offsetArray->GetElementAt(i)).Get(offset)
- && (colorArray->GetElementAt(i)).Get(color) )
+ if( (colorArray->GetElementAt(i)).Get(color) )
{
- mGradient->AddStop( offset, color);
+ mGradient->AddStop( offsetArray[i], color);
numValidStop++;
}
}
}
}
+
if( numValidStop < 1u ) // no valid stop
{
return false;
return true;
}
+bool GradientRenderer::GetStopOffsets(const Property::Value* value, Vector<float>& stopOffsets)
+{
+ Vector2 offset2;
+ if( value->Get( offset2 ) )
+ {
+ stopOffsets.PushBack( offset2.x );
+ stopOffsets.PushBack( offset2.y );
+ return true;
+ }
+
+ Vector3 offset3;
+ if( value->Get( offset3 ) )
+ {
+ stopOffsets.PushBack( offset3.x );
+ stopOffsets.PushBack( offset3.y );
+ stopOffsets.PushBack( offset3.z );
+ return true;
+ }
+
+ Vector4 offset4;
+ if( value->Get( offset4 ) )
+ {
+ stopOffsets.PushBack( offset4.x );
+ stopOffsets.PushBack( offset4.y );
+ stopOffsets.PushBack( offset4.z );
+ stopOffsets.PushBack( offset4.w );
+ return true;
+ }
+
+ Property::Array* offsetArray = value->GetArray();
+ if( offsetArray )
+ {
+ unsigned int numStop = offsetArray->Count();
+ float offset;
+ for( unsigned int i=0; i<numStop; i++ )
+ {
+ if( offsetArray->GetElementAt(i).Get(offset) )
+ {
+ stopOffsets.PushBack( offset );
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
} // namespace Internal
} // namespace Toolkit
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 SetOffset( const Vector2& offset );
+ /**
+ * @copydoc ControlRenderer::CreatePropertyMap
+ */
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
protected:
/**
* @copydoc ControlRenderer::DoSetOnStage
*/
bool NewGradient(Type gradientType, const Property::Map& propertyMap);
+ /**
+ * Get the stop-offsets from the property.
+ * The valid property type are ARRAY, VECTOR2, VECTOR3, VECTOR4.
+ *
+ * @param[in] value The property value of stop-offsets
+ * @param[out] stopOffsets The vector contains the stop offset values.
+ */
+ static bool GetStopOffsets(const Property::Value* value, Vector<float>& stopOffsets);
+
// Undefined
GradientRenderer( const GradientRenderer& gradientRenderer );
mGradientStops.PushBack( GradientStop( Clamp( offset, 0.f, 1.f ), color) );
}
+const Vector<Gradient::GradientStop>& Gradient::GetStops()
+{
+ return mGradientStops;
+}
+
void Gradient::SetGradientUnits( GradientUnits gradientUnits )
{
mGradientUnits = gradientUnits;
void AddStop(float offset, const Vector4& color);
/**
+ * Get the gradient stops.
+ * @return The vector of gradient stops.
+ */
+ const Vector<GradientStop>& GetStops();
+
+ /**
* Set the coordinate system used by the gradient attributes.
* @param[in] gradientUnits The the attributes are defined using the current user coordinate system or the bounding box of the shape.
*/
// 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
{
namespace
{
-
-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 RENDERER_TYPE("renderer-type");
+const char * const RENDERER_TYPE_VALUE("image-renderer");
+
+// property names
+const char * const IMAGE_URL_NAME( "image-url" );
+const char * const IMAGE_FITTING_MODE( "image-fitting-mode" );
+const char * const IMAGE_SAMPLING_MODE( "image-sampling-mode" );
+const char * const IMAGE_DESIRED_WIDTH( "image-desired-width" );
+const char * const IMAGE_DESIRED_HEIGHT( "image-desired-height" );
+
+// fitting modes
+const char * const SHRINK_TO_FIT("shrink-to-fit");
+const char * const SCALE_TO_FILL("scale-to-fill");
+const char * const FIT_WIDTH("fit-width");
+const char * const FIT_HEIGHT("fit-height");
+const char * const DEFAULT("default");
+
+// sampling modes
+const char * const BOX("box");
+const char * const NEAREST("nearest");
+const char * const LINEAR("linear");
+const char * const BOX_THEN_NEAREST("box-then-nearest");
+const char * const BOX_THEN_LINEAR("box-then-linear");
+const char * const NO_FILTER("no-filter");
+const char * const DONT_CARE("dont-care");
std::string TEXTURE_UNIFORM_NAME = "sTexture";
}\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 )
fittingValue->Get( fitting );
mFittingMode = FittingMode::DEFAULT;
- if( fitting == "shrink-to-fit" )
+ if( fitting == SHRINK_TO_FIT )
{
mFittingMode = FittingMode::SHRINK_TO_FIT;
}
- else if( fitting == "scale-to-fill" )
+ else if( fitting == SCALE_TO_FILL )
{
mFittingMode = FittingMode::SCALE_TO_FILL;
}
- else if( fitting == "fit-width" )
+ else if( fitting == FIT_WIDTH )
{
mFittingMode = FittingMode::FIT_WIDTH;
}
- else if( fitting == "fit-height" )
+ else if( fitting == FIT_HEIGHT )
{
mFittingMode = FittingMode::FIT_HEIGHT;
}
- else if( fitting == "default" )
+ else if( fitting == DEFAULT )
{
mFittingMode = FittingMode::DEFAULT;
}
samplingValue->Get( sampling );
mSamplingMode = SamplingMode::DEFAULT;
- if( sampling == "box" )
+ if( sampling == BOX )
{
mSamplingMode = SamplingMode::BOX;
}
- else if( sampling == "nearest" )
+ else if( sampling == NEAREST )
{
mSamplingMode = SamplingMode::NEAREST;
}
- else if( sampling == "linear" )
+ else if( sampling == LINEAR )
{
mSamplingMode = SamplingMode::LINEAR;
}
- else if( sampling == "box-then-nearest" )
+ else if( sampling == BOX_THEN_NEAREST )
{
mSamplingMode = SamplingMode::BOX_THEN_NEAREST;
}
- else if( sampling == "box-then-linear" )
+ else if( sampling == BOX_THEN_LINEAR )
{
mSamplingMode = SamplingMode::BOX_THEN_LINEAR;
}
- else if( sampling == "no-filter" )
+ else if( sampling == NO_FILTER )
{
mSamplingMode = SamplingMode::NO_FILTER;
}
- else if( sampling == "dont-care" )
+ else if( sampling == DONT_CARE )
{
mSamplingMode = SamplingMode::DONT_CARE;
}
- else if( sampling == "default" )
+ else if( sampling == DEFAULT )
{
mSamplingMode = SamplingMode::DEFAULT;
}
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::Initialize( RendererFactoryCache& factoryCache )
+void ImageRenderer::DoCreatePropertyMap( Property::Map& map ) const
{
- mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
- if( !(mImpl->mGeometry) )
+ map.Clear();
+ map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+ if( !mImageUrl.empty() )
{
- mImpl->mGeometry = factoryCache.CreateQuadGeometry();
- factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
+ map.Insert( IMAGE_URL_NAME, mImageUrl );
+ map.Insert( IMAGE_DESIRED_WIDTH, mDesiredSize.GetWidth() );
+ map.Insert( IMAGE_DESIRED_HEIGHT, mDesiredSize.GetHeight() );
}
+ else if( mImage )
+ {
+ map.Insert( IMAGE_DESIRED_WIDTH, static_cast<int>(mImage.GetWidth()) );
+ map.Insert( IMAGE_DESIRED_HEIGHT, static_cast<int>(mImage.GetHeight()) );
- mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
- if( !mImpl->mShader )
+ ResourceImage resourceImage = ResourceImage::DownCast(mImage);
+ if( resourceImage )
+ {
+ map.Insert( IMAGE_URL_NAME, resourceImage.GetUrl() );
+ }
+ }
+
+ switch( mFittingMode )
{
- mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
- factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
+ case Dali::FittingMode::FIT_HEIGHT:
+ {
+ map.Insert( IMAGE_FITTING_MODE, FIT_HEIGHT );
+ break;
+ }
+ case Dali::FittingMode::FIT_WIDTH:
+ {
+ map.Insert( IMAGE_FITTING_MODE, FIT_WIDTH );
+ break;
+ }
+ case Dali::FittingMode::SCALE_TO_FILL:
+ {
+ map.Insert( IMAGE_FITTING_MODE, SCALE_TO_FILL );
+ break;
+ }
+ case Dali::FittingMode::SHRINK_TO_FIT:
+ {
+ map.Insert( IMAGE_FITTING_MODE, SHRINK_TO_FIT );
+ break;
+ }
+ default:
+ {
+ map.Insert( IMAGE_FITTING_MODE, DEFAULT );
+ break;
+ }
}
- mDesiredSize = ImageDimensions();
- mFittingMode = FittingMode::DEFAULT;
- mSamplingMode = SamplingMode::DEFAULT;
- mImageUrl.clear();
+ switch( mSamplingMode )
+ {
+ case Dali::SamplingMode::BOX:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, BOX );
+ break;
+ }
+ case Dali::SamplingMode::NEAREST:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, NEAREST );
+ break;
+ }
+ case Dali::SamplingMode::LINEAR:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, LINEAR );
+ break;
+ }
+ case Dali::SamplingMode::BOX_THEN_LINEAR:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, BOX_THEN_LINEAR );
+ break;
+ }
+ case Dali::SamplingMode::BOX_THEN_NEAREST:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, BOX_THEN_NEAREST );
+ break;
+ }
+ case Dali::SamplingMode::NO_FILTER:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, NO_FILTER );
+ break;
+ }
+ case Dali::SamplingMode::DONT_CARE:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, DONT_CARE );
+ break;
+ }
+ default:
+ {
+ map.Insert( IMAGE_SAMPLING_MODE, DEFAULT );
+ break;
+ }
+ }
+}
+
+void ImageRenderer::Initialize( RendererFactoryCache& factoryCache )
+{
+ if( !mImpl->mCustomShader )
+ {
+ mImpl->mGeometry = CreateGeometry( factoryCache, ImageDimensions( 1, 1 ) );
+
+ 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->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 );
+ }
+ }
+
+ 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 );
*/
virtual void SetOffset( const Vector2& offset );
+ /**
+ * @copydoc ControlRenderer::CreatePropertyMap
+ */
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
protected:
/**
* @copydoc ControlRenderer::DoSetOnStage
namespace
{
+const char * const RENDERER_TYPE("renderer-type");
+const char * const RENDERER_TYPE_VALUE("n-patch-renderer");
const char * const IMAGE_URL_NAME("image-url");
const char * const BORDER_ONLY("border-only");
{
}
-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::DoCreatePropertyMap( Property::Map& map ) const
+{
+ map.Clear();
+ map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+ if( !mImageUrl.empty() )
+ {
+ map.Insert( IMAGE_URL_NAME, mImageUrl );
+ }
+ else if( mImage )
+ {
+ map.Insert( IMAGE_URL_NAME, mImage.GetUrl() );
+ }
+ map.Insert( BORDER_ONLY, mBorderOnly );
+}
+
void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache )
{
mNinePatchGeometry = factoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY );
* | %Property Name | Type |
* |---------------------------|------------------|
* | image-url | STRING |
+ * | border-only | BOOLEAN
*
*/
class NPatchRenderer: public ControlRenderer
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
*/
virtual void SetOffset( const Vector2& offset );
+ /**
+ * @copydoc ControlRenderer::CreatePropertyMap
+ */
+ virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
protected:
/**
* @copydoc ControlRenderer::DoSetOnStage
}
}
+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& )
{
const std::string fontFamily = value.Get< std::string >();
DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
-
- if( impl.mController->GetDefaultFontFamily() != fontFamily )
- {
- impl.mController->SetDefaultFontFamily( fontFamily, true ); // "true" as SetProperty means user defined font so don't change when system font changes.
- }
+ impl.mController->SetDefaultFontFamily( fontFamily );
}
break;
}
const std::string fontFamily = value.Get< std::string >();
DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
- if( impl.mController->GetDefaultFontFamily() != fontFamily )
- {
- impl.mController->SetDefaultFontFamily( fontFamily, true );
- }
+ impl.mController->SetDefaultFontFamily( fontFamily );
}
break;
}
$(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;
return mImpl->mMaximumNumberOfCharacters;
}
-void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily, bool userDefined )
+void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
{
if( !mImpl->mFontDefaults )
{
}
mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s userDefined: %s\n", defaultFontFamily.c_str(), userDefined ? "true":"false" );
- mImpl->mUserDefinedFontFamily = userDefined;
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
+ mImpl->mUserDefinedFontFamily = true;
// Clear the font-specific data
ClearFontData();
* @brief Set the default font family.
*
* @param[in] defaultFontFamily The default font family.
- * @param[in] userDefined If set by the user
*/
- void SetDefaultFontFamily( const std::string& defaultFontFamily, bool userDefined );
+ void SetDefaultFontFamily( const std::string& defaultFontFamily );
/**
* @brief Retrieve the default font family.
// Deprecated API
/**
- * @brief Sets the label with an actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the label with an actor.
+ *
* @param[in] label The actor to use as a label
*/
void SetLabel( Actor label );
/**
- * @brief Sets the button image.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the button image.
+ *
* @param[in] image The button image.
*/
void SetButtonImage( Image image );
/**
- * @brief Sets the selected image.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the selected image.
+ *
* @param[in] image The selected image.
*/
void SetSelectedImage( Image image );
/**
- * @brief Gets the button image.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Gets the button image.
+ *
* @return An actor with the button image.
*/
Actor GetButtonImage() const;
/**
- * @brief Gets the selected image.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Gets the selected image.
+ *
* @return An actor with the selected image.
*/
Actor GetSelectedImage() const;
using Button::SetButtonImage;
/**
- * @brief Sets the unselected image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the unselected image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetButtonImage( Actor image );
using Button::SetBackgroundImage;
/**
- * @brief Sets the background image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the background image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetBackgroundImage( Actor image );
using Button::SetSelectedImage;
/**
- * @brief Sets the selected image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the selected image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetSelectedImage( Actor image );
using Button::SetSelectedBackgroundImage;
/**
- * @brief Sets the selected background image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the selected background image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetSelectedBackgroundImage( Actor image );
using Button::SetDisabledBackgroundImage;
/**
- * @brief Sets the disabled background image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the disabled background image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetDisabledBackgroundImage( Actor image );
using Button::SetDisabledImage;
/**
- * @brief Sets the disabled image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the disabled image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetDisabledImage( Actor image );
using Button::SetDisabledSelectedImage;
/**
- * @brief Sets the disabled selected image with an Actor.
- *
* @deprecated DALi 1.0.50
*
+ * @brief Sets the disabled selected image with an Actor.
+ *
* @param[in] image The Actor to use.
*/
void SetDisabledSelectedImage( Actor image );
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
};
};
*
* If the handle is empty, ImageView will display nothing
*
- * @param[in] url The Image resource to display.
- *
* @since DALi 1.1.4
+ *
+ * @param[in] url The Image resource to display.
*/
void SetImage( const std::string& url );
}
/**
- * PageTurnView is a base class of different mode of pageTurnViews ( portrait or landscape )
+ * @brief PageTurnView is a base class of different mode of pageTurnViews ( portrait or landscape )
+ *
* Page actors are provided from an external PageFactory
* PanGesture is used to activate the page bending, streching and tuning forward/backward
*
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