[dali_1.1.3] Merge branch 'devel/master' 55/48355/1
authorXiangyin Ma <x1.ma@samsung.com>
Fri, 18 Sep 2015 10:03:45 +0000 (11:03 +0100)
committerXiangyin Ma <x1.ma@samsung.com>
Fri, 18 Sep 2015 10:03:45 +0000 (11:03 +0100)
Change-Id: I7bfe198ba4590cd26b0e7ce569525d67b6d8c537

36 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp [new file with mode: 0644]
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h [new file with mode: 0644]
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/controls/renderers/color/color-renderer.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/color/color-renderer.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/control-renderer-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/gradient.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/gradient.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/image/image-renderer.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/renderer-factory-cache.h [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/renderers/renderer-factory-impl.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 446bb36..9b656a7 100644 (file)
@@ -49,6 +49,8 @@ SET(TC_SOURCES
    utc-Dali-SuperBlurView.cpp
    utc-Dali-Toolkit.cpp
    utc-Dali-Model3dView.cpp
+   utc-Dali-ControlRenderer.cpp
+   utc-Dali-RendererFactory.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
index 722f0a8..f77f903 100644 (file)
@@ -396,17 +396,21 @@ int UtcDaliControlBackgroundImage(void)
 
   Image image = ResourceImage::New("TestImage");
   control.SetBackgroundImage( image );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::WHITE, TEST_LOCATION );
+  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 );
 
   control.SetBackgroundColor( Color::YELLOW );
   control.SetBackgroundImage( image );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::YELLOW, TEST_LOCATION );
+  // The background can be either an image or a color, not both
+  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
 
   END_TEST;
 }
@@ -418,32 +422,33 @@ int UtcDaliControlBackgroundProperties(void)
 
   DALI_TEST_CHECK( control.GetChildCount() == 0 );
   DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
-  DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::TRANSPARENT, TEST_LOCATION );
-  DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND_IMAGE ).Get< Property::Map >().Empty() );
+  DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() );
 
-  control.SetProperty( Control::Property::BACKGROUND_COLOR, Color::RED );
-  DALI_TEST_CHECK( control.GetChildCount() > 0 );
+  Property::Map colorMap;
+  colorMap["color"] = Color::RED;
+  control.SetProperty( Control::Property::BACKGROUND, colorMap );
   DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION );
-  DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), 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 );
 
   Property::Map imageMap;
   imageMap[ "filename" ] = "TestImage";
-  control.SetProperty( Control::Property::BACKGROUND_IMAGE, imageMap );
+  control.SetProperty( Control::Property::BACKGROUND, imageMap );
   DALI_TEST_CHECK( control.GetChildCount() > 0 );
-  DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::RED, TEST_LOCATION );
-  DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::RED, TEST_LOCATION );
-
-  Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND_IMAGE );
-  Property::Map* resultMap = propValue.GetMap();
+  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" );
 
   Property::Map emptyMap;
-  control.SetProperty( Control::Property::BACKGROUND_IMAGE, emptyMap );
+  control.SetProperty( Control::Property::BACKGROUND, emptyMap );
   DALI_TEST_CHECK( control.GetChildCount() == 0 );
   DALI_TEST_EQUALS( control.GetBackgroundColor(), Color::TRANSPARENT, TEST_LOCATION );
-  DALI_TEST_EQUALS( control.GetProperty( Control::Property::BACKGROUND_COLOR ).Get< Vector4 >(), Color::TRANSPARENT, TEST_LOCATION );
-  DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND_IMAGE ).Get< Property::Map >().Empty() );
+  DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() );
 
   END_TEST;
 }
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp
new file mode 100644 (file)
index 0000000..be623c2
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali/devel-api/rendering/material.h>
+#include <dali/devel-api/rendering/shader.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+void dali_control_renderer_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void dali_control_renderer_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliControlRendererCopyAndAssignment(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliControlRendererCopyAndAssignment" );
+
+  RendererFactory factory = RendererFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert("renderer-type", "color-renderer");
+  propertyMap.Insert("blend-color", Color::BLUE);
+  ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+
+  ControlRenderer controlRendererCopy( controlRenderer );
+  DALI_TEST_CHECK(controlRenderer == controlRendererCopy);
+
+  ControlRenderer emptyControlRenderer;
+  ControlRenderer emptyControlRendererCopy( emptyControlRenderer );
+  DALI_TEST_CHECK(emptyControlRenderer == emptyControlRendererCopy);
+
+  ControlRenderer controlRendererEquals;
+  controlRendererEquals = controlRenderer;
+  DALI_TEST_CHECK(controlRenderer == controlRendererEquals);
+
+  ControlRenderer emptyControlRendererEquals;
+  emptyControlRendererEquals = emptyControlRenderer;
+  DALI_TEST_CHECK( emptyControlRenderer == emptyControlRendererEquals );
+
+  //self assignment
+  controlRenderer = controlRenderer;
+  DALI_TEST_CHECK( controlRenderer = controlRendererCopy );
+
+  END_TEST;
+}
+
+int UtcDaliControlRendererSetDepthIndex(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliControlRendererSetDepthIndex" );
+
+  RendererFactory factory = RendererFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert("renderer-type", "color-renderer");
+  propertyMap.Insert("blend-color", Color::BLUE);
+  ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+
+  controlRenderer.SetDepthIndex( 1.f );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), 1.f, TEST_LOCATION );
+
+  controlRenderer.SetDepthIndex( -1.f );
+  DALI_TEST_EQUALS( actor.GetRendererAt(0u).GetDepthIndex(), -1.f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliControlRendererSetOnStage(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliControlRendererSetDepthIndex" );
+
+  RendererFactory factory = RendererFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert("renderer-type", "color-renderer");
+  propertyMap.Insert("blend-color", Color::BLUE);
+  ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  controlRenderer.SetOnStage( actor );
+
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp
new file mode 100644 (file)
index 0000000..a49de61
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * 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.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali/devel-api/rendering/material.h>
+#include <dali/devel-api/rendering/shader.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace
+{
+const char* TEST_IMAGE_FILE_NAME =  "gallery_image_01.jpg";
+} // namespace
+
+
+void dali_renderer_factory_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void dali_renderer_factory_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliRendererFactoryGet(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactory" );
+
+  //Register type
+  TypeInfo type;
+  type = TypeRegistry::Get().GetTypeInfo( "RendererFactory" );
+  DALI_TEST_CHECK( type );
+  BaseHandle handle = type.CreateInstance();
+  DALI_TEST_CHECK( handle );
+
+  RendererFactory factory;
+  factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  RendererFactory newFactory = RendererFactory::Get();
+  DALI_TEST_CHECK( newFactory );
+
+  // Check that renderer factory is a singleton
+  DALI_TEST_CHECK(factory == newFactory);
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryCopyAndAssignment(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryCopyAndAssignment" );
+  RendererFactory factory = RendererFactory::Get();
+
+  RendererFactory factoryCopy( factory );
+  DALI_TEST_CHECK(factory == factoryCopy);
+
+  RendererFactory emptyFactory;
+  RendererFactory emptyFactoryCopy( emptyFactory );
+  DALI_TEST_CHECK(emptyFactory == emptyFactoryCopy);
+
+  RendererFactory factoryEquals;
+  factoryEquals = factory;
+  DALI_TEST_CHECK(factory == factoryEquals);
+
+  RendererFactory emptyFactoryEquals;
+  emptyFactoryEquals = emptyFactory;
+  DALI_TEST_CHECK( emptyFactory == emptyFactoryEquals );
+
+  //self assignment
+  factory = factory;
+  DALI_TEST_CHECK( factory = factoryCopy );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetColorRenderer1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetColorRenderer1:  Request color renderer with a Property::Map" );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f );
+  propertyMap.Insert("renderer-type", "color-renderer");
+  propertyMap.Insert("blend-color", testColor);
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap);
+  DALI_TEST_CHECK( controlRenderer );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+
+  application.SendNotification();
+  application.Render(0);
+
+  Vector4 actualValue(Vector4::ZERO);
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetColorRenderer2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetColorRenderer2: Request color renderer with a Vector4" );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f );
+  ControlRenderer controlRenderer = factory.GetControlRenderer(testColor);
+  DALI_TEST_CHECK( controlRenderer );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+
+  application.SendNotification();
+  application.Render(0);
+
+  Vector4 actualValue(Vector4::ZERO);
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetLinearGradientRenderer(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliRendererFactoryGetRadialGradientRenderer");
+
+  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");
+
+  Property::Array stopOffsets;
+  stopOffsets.PushBack( 0.2f );
+  stopOffsets.PushBack( 0.8f );
+  propertyMap.Insert("gradient-stop-offset", stopOffsets);
+
+  Property::Array stopColors;
+  stopColors.PushBack( Color::RED );
+  stopColors.PushBack( Color::GREEN );
+  propertyMap.Insert("gradient-stop-color", stopColors);
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap);
+  DALI_TEST_CHECK( controlRenderer );
+
+  Actor actor = Actor::New();
+  Vector2 size(200.f, 200.f);
+  actor.SetSize(size);
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetOnStage( actor );
+  controlRenderer.SetSize(size);
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  // A lookup texture is generated and pass to shader as sampler
+  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+
+  application.SendNotification();
+  application.Render(0);
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetRadialGradientRenderer(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliRendererFactoryGetRadialGradientRenderer");
+
+  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);
+
+  Property::Array stopOffsets;
+  stopOffsets.PushBack( 0.0f );
+  stopOffsets.PushBack( 1.f );
+  propertyMap.Insert("gradient-stop-offset", stopOffsets);
+
+  Property::Array stopColors;
+  stopColors.PushBack( Color::RED );
+  stopColors.PushBack( Color::GREEN );
+  propertyMap.Insert("gradient-stop-color", stopColors);
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap);
+  DALI_TEST_CHECK( controlRenderer );
+
+  Actor actor = Actor::New();
+  Vector2 size(200.f, 200.f);
+  actor.SetSize(size);
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize(size);
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  // A lookup texture is generated and pass to shader as sampler
+  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  application.SendNotification();
+  application.Render(0);
+
+  Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f );
+  alignMatrix.Invert();
+
+  Matrix3 actualValue( Matrix3::IDENTITY );
+  DALI_TEST_CHECK( gl.GetUniformValue<Matrix3>( "uAlignmentMatrix", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, alignMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetImageRenderer1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetImageRenderer1: Request image renderer with a Property::Map" );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( "renderer-type", "image-renderer" );
+  propertyMap.Insert( "image-url", TEST_IMAGE_FILE_NAME );
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+  DALI_TEST_CHECK( controlRenderer );
+
+  Actor actor = Actor::New();
+  actor.SetSize( 200.f, 200.f );
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize( Vector2(200.f, 200.f) );
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  application.SendNotification();
+  application.Render();
+
+  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
+  if(request)
+  {
+    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)));
+  }
+
+  application.Render();
+  application.SendNotification();
+
+  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  int textureUnit = -1;
+  DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+  DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryGetImageRenderer2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetImageRenderer2: Request image renderer with an image handle" );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME);
+  ControlRenderer controlRenderer = factory.GetControlRenderer( image );
+
+  Actor actor = Actor::New();
+  actor.SetSize( 200.f, 200.f );
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize( Vector2(200.f, 200.f) );
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  application.SendNotification();
+  application.Render();
+
+  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
+  if(request)
+  {
+    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)));
+  }
+
+  application.Render();
+  application.SendNotification();
+
+  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
+
+  int textureUnit = -1;
+  DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+  DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryResetRenderer1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryResetRenderer1" );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer( Color::RED );
+  DALI_TEST_CHECK( controlRenderer );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  application.SendNotification();
+  application.Render(0);
+  Vector4 actualValue(Vector4::ZERO);
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION );
+
+  bool isNewRenderer = factory.ResetRenderer( controlRenderer, Color::GREEN );
+  DALI_TEST_CHECK( !isNewRenderer );
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, Color::GREEN, TEST_LOCATION );
+
+  Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) );
+  isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage );
+  DALI_TEST_CHECK( isNewRenderer );
+
+  Actor actor2 = Actor::New();
+  actor2.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor2 );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor2 );
+  application.SendNotification();
+  application.Render(0);
+  Image samplerImage = actor2.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage();
+  DALI_TEST_CHECK( BufferImage::DownCast( samplerImage ) );
+
+  END_TEST;
+}
+
+int UtcDaliRendererFactoryResetRenderer2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryResetRenderer2" );
+
+  Actor actor = Actor::New();
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Image resourceImage = ResourceImage::New(TEST_IMAGE_FILE_NAME);
+  ControlRenderer controlRenderer = factory.GetControlRenderer( resourceImage );
+  DALI_TEST_CHECK( controlRenderer );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  application.SendNotification();
+  application.Render(0);
+  Image samplerImage = actor.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage();
+  DALI_TEST_CHECK( ResourceImage::DownCast( samplerImage ) );
+
+  Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) );
+  bool isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage );
+  DALI_TEST_CHECK( !isNewRenderer );
+  application.SendNotification();
+  application.Render(0);
+  samplerImage = actor.GetRendererAt(0u).GetMaterial().GetSamplerAt(0u).GetImage();
+  DALI_TEST_CHECK( BufferImage::DownCast( samplerImage ) );
+
+  isNewRenderer = factory.ResetRenderer( controlRenderer, Color::RED );
+  DALI_TEST_CHECK( isNewRenderer );
+
+  Actor actor2 = Actor::New();
+  actor2.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor2 );
+  controlRenderer.SetSize(Vector2(200.f, 200.f));
+  controlRenderer.SetOnStage( actor2 );
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  application.SendNotification();
+  application.Render(0);
+  Vector4 actualValue(Vector4::ZERO);
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
+  DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
index bd24d22..75d8ca4 100644 (file)
@@ -88,6 +88,7 @@ develapibloomviewdir =          $(develapicontrolsdir)/bloom-view
 develapibubbleemitterdir =      $(develapicontrolsdir)/bubble-effect
 develapieffectsviewdir =        $(develapicontrolsdir)/effects-view
 develapimagnifierdir =          $(develapicontrolsdir)/magnifier
+develapirendererfactorydir =    $(develapicontrolsdir)/renderer-factory
 develapipopupdir =              $(develapicontrolsdir)/popup
 develapisliderdir =             $(develapicontrolsdir)/slider
 develapishadowviewdir =         $(develapicontrolsdir)/shadow-view
@@ -108,6 +109,7 @@ develapieffectsview_HEADERS =       $(devel_api_effects_view_header_files)
 develapifocusmanager_HEADERS =      $(devel_api_focus_manager_header_files)
 develapimagnifier_HEADERS =         $(devel_api_magnifier_header_files)
 develapipopup_HEADERS =             $(devel_api_popup_header_files)
+develapirendererfactory_HEADERS =   $(devel_api_renderer_factory_header_files)
 develapiscripting_HEADERS =         $(devel_api_scripting_header_files)
 develapishadowview_HEADERS =        $(devel_api_shadow_view_header_files)
 develapishadereffects_HEADERS =     $(devel_api_shader_effects_header_files)
diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp
new file mode 100644 (file)
index 0000000..e460b77
--- /dev/null
@@ -0,0 +1,71 @@
+ /*
+ * 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.h"
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+ControlRenderer::ControlRenderer()
+{
+}
+
+ControlRenderer::~ControlRenderer()
+{
+}
+
+ControlRenderer::ControlRenderer( const ControlRenderer& handle )
+: BaseHandle( handle )
+{
+}
+
+ControlRenderer& ControlRenderer::operator=( const ControlRenderer& handle )
+{
+  BaseHandle::operator=( handle );
+  return *this;
+}
+
+ControlRenderer::ControlRenderer(Internal::ControlRenderer *impl)
+: BaseHandle(impl)
+{
+}
+
+void ControlRenderer::SetSize( const Vector2& size )
+{
+  GetImplementation( *this ).SetSize(size);
+}
+
+void ControlRenderer::SetDepthIndex( float index )
+{
+  GetImplementation( *this ).SetDepthIndex(index);
+}
+
+void ControlRenderer::SetOnStage( Actor& actor )
+{
+  GetImplementation( *this ).SetOnStage(actor);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h b/dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h
new file mode 100644 (file)
index 0000000..d5f0df4
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef __DALI_TOOLKIT_CONTROL_RENDERER_H__
+#define __DALI_TOOLKIT_CONTROL_RENDERER_H__
+/*
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/actors/actor.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class ControlRenderer;
+}
+
+/**
+ * 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.
+ */
+class DALI_IMPORT_API ControlRenderer : public BaseHandle
+{
+public:
+
+  /**
+   * @brief Create an empty ControlRenderer Handle
+   */
+  ControlRenderer();
+
+  /**
+   * @brief Destructor
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~ControlRenderer();
+
+  /**
+   * @brief This copy constructor is required for (smart) pointer semantics.
+   *
+   * @param[in] handle A reference to the copied handle.
+   */
+  ControlRenderer( const ControlRenderer& handle );
+
+  /**
+   * @brief This assignment operator is required for (smart) pointer semantics.
+   *
+   * @param [in] handle  A reference to the copied handle.
+   * @return A reference to this.
+   */
+  ControlRenderer& operator=( const ControlRenderer& handle );
+
+  /**
+   * 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.
+   * Depth-index controls draw-order for overlapping renderers.
+   * Renderer with higher depth indices are rendered in front of other renderer with smaller values
+   *
+   * @param[in] depthIndex The depth index of this renderer.
+   */
+  void SetDepthIndex( float index );
+
+  /**
+   * 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 );
+
+public: // Not intended for application developers
+
+  explicit DALI_INTERNAL ControlRenderer(Internal::ControlRenderer *impl);
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /*__DALI_TOOLKIT_CONTROL_RENDERER_H__*/
diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp
new file mode 100644 (file)
index 0000000..f836e8c
--- /dev/null
@@ -0,0 +1,112 @@
+ /*
+ * 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 "renderer-factory.h"
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/singleton-service.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+RendererFactory RendererFactory::Get()
+{
+  RendererFactory factory;
+
+  // Check whether the RendererFactory is already created
+  SingletonService singletonService( SingletonService::Get() );
+  if( singletonService )
+  {
+    BaseHandle handle = singletonService.GetSingleton( typeid(RendererFactory) );
+    if( handle )
+    {
+      //If so, downcast the handle of singleton to RendererFactory
+      factory = RendererFactory( dynamic_cast<Internal::RendererFactory*>(handle.GetObjectPtr()) );
+    }
+
+    if( !factory )
+    {
+      // If not, create the RendererFactory and register it as a singleton
+      factory = RendererFactory( new Internal::RendererFactory() );
+      singletonService.Register( typeid(RendererFactory), factory );
+
+    }
+  }
+
+  return factory;
+}
+
+RendererFactory::RendererFactory()
+{
+}
+
+RendererFactory::~RendererFactory()
+{
+}
+
+RendererFactory::RendererFactory( const RendererFactory& handle )
+: BaseHandle( handle )
+{
+}
+
+RendererFactory& RendererFactory::operator=( const RendererFactory& handle )
+{
+  BaseHandle::operator=( handle );
+  return *this;
+}
+
+RendererFactory::RendererFactory(Internal::RendererFactory *impl)
+: BaseHandle(impl)
+{
+}
+
+ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap )
+{
+  return GetImplementation( *this ).GetControlRenderer( propertyMap );
+}
+
+ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color )
+{
+  return GetImplementation( *this ).GetControlRenderer( color );
+}
+
+bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Vector4& color )
+{
+  return GetImplementation( *this ).ResetRenderer( renderer, color );
+}
+
+ControlRenderer RendererFactory::GetControlRenderer( const Image& image )
+{
+  return GetImplementation( *this ).GetControlRenderer( image );
+}
+
+bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Image& image )
+{
+  return GetImplementation( *this ).ResetRenderer( renderer, image );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h
new file mode 100644 (file)
index 0000000..4a30888
--- /dev/null
@@ -0,0 +1,143 @@
+#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_H__
+#define __DALI_TOOLKIT_RENDERER_FACTORY_H__
+/*
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+
+// INTERNAK INCLUDES
+#include <dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h>
+
+namespace Dali
+{
+class Image;
+class Vector4;
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class RendererFactory;
+}
+
+/**
+ * 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.
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | renderer-type             | STRING           |
+ */
+class DALI_IMPORT_API RendererFactory : public BaseHandle
+{
+public:
+
+  /**
+   * @brief Create or retrieve RendererFactory singleton.
+   *
+   * @return A handle to the RendererFactory control.
+   */
+  static RendererFactory Get();
+
+  /**
+   * @brief Create a RendererFactory handle.
+   *
+   * Calling member functions with an uninitialised handle is not allowed.
+   */
+  RendererFactory();
+
+  /**
+   * @brief Destructor
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~RendererFactory();
+
+  /**
+   * @brief This copy constructor is required for (smart) pointer semantics.
+   *
+   * @param[in] handle A reference to the copied handle.
+   */
+  RendererFactory( const RendererFactory& handle );
+
+  /**
+   * @brief This assignment operator is required for (smart) pointer semantics.
+   *
+   * @param [in] handle  A reference to the copied handle.
+   * @return A reference to this.
+   */
+  RendererFactory& operator=( const RendererFactory& handle );
+
+  /**
+   * @brief Request the control 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 The pointer pointing to control renderer
+   */
+  ControlRenderer GetControlRenderer( const Property::Map& propertyMap  );
+
+  /**
+   * @brief Request the control renderer to render the given color
+   *
+   * @param[in] color The color to be rendered
+   * @return The pointer pointing to the control renderer
+   */
+  ControlRenderer GetControlRenderer( const Vector4& color );
+
+  /**
+   * @brief Request the current control renderer to render the given color
+   *
+   * if the current renderer is a handle to an internal color renderer, set this color to it,
+   * else the renderer would be a handle to a newly created internal color renderer.
+   *
+   * @return Whether a new internal control renderer is created.
+   */
+  bool ResetRenderer( ControlRenderer& renderer, const Vector4& color );
+
+  /**
+   * @brief Request the control renderer to render the image.
+   *
+   * @param[in] image The image to be rendered.
+   * @return The pointer pointing to the control renderer
+   */
+  ControlRenderer GetControlRenderer( const Image& image );
+
+  /**
+   * @brief Request the current control renderer to render the given image
+   *
+   * if the current renderer is a handle to an internal image renderer, set this image to it,
+   * else the renderer would be a handle to a newly created internal image renderer.
+   *
+   * @return Whether a new internal control renderer is created.
+   */
+  bool ResetRenderer( ControlRenderer& renderer, const Image& image );
+
+private:
+
+  explicit DALI_INTERNAL RendererFactory(Internal::RendererFactory *impl);
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_RENDERER_FACTORY_H__ */
index 9668fcd..bf62a04 100755 (executable)
@@ -10,6 +10,8 @@ devel_api_src_files = \
   $(devel_api_src_dir)/controls/magnifier/magnifier.cpp \
   $(devel_api_src_dir)/controls/popup/confirmation-popup.cpp \
   $(devel_api_src_dir)/controls/popup/popup.cpp \
+  $(devel_api_src_dir)/controls/renderer-factory/renderer-factory.cpp \
+  $(devel_api_src_dir)/controls/renderer-factory/control-renderer.cpp \
   $(devel_api_src_dir)/controls/shadow-view/shadow-view.cpp \
   $(devel_api_src_dir)/controls/slider/slider.cpp \
   $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \
@@ -47,6 +49,10 @@ devel_api_popup_header_files = \
   $(devel_api_src_dir)/controls/popup/confirmation-popup.h \
   $(devel_api_src_dir)/controls/popup/popup.h
 
+devel_api_renderer_factory_header_files = \
+  $(devel_api_src_dir)/controls/renderer-factory/renderer-factory.h \
+  $(devel_api_src_dir)/controls/renderer-factory/control-renderer.h
+
 devel_api_shadow_view_header_files = \
   $(devel_api_src_dir)/controls/shadow-view/shadow-view.h
 
diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp
new file mode 100644 (file)
index 0000000..7b3ae1c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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 "color-renderer.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+//INTERNAL INCLUDES
+#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-data-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+const char * const COLOR_NAME("blend-color");
+const char * const COLOR_UNIFORM_NAME("uBlendColor");
+
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    gl_Position = uMvpMatrix * vertexPosition;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec4 uBlendColor;\n
+  \n
+  void main()\n
+  {\n
+    gl_FragColor = uBlendColor*uColor;\n
+  }\n
+);
+}
+
+ColorRenderer::ColorRenderer()
+: ControlRenderer(),
+  mBlendColorIndex( Property::INVALID_INDEX )
+{
+}
+
+ColorRenderer::~ColorRenderer()
+{
+}
+
+void ColorRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+{
+  Initialize( factoryCache );
+
+  Property::Value* color = propertyMap.Find( COLOR_NAME );
+  if( !( color && color->Get(mBlendColor) ) )
+  {
+    DALI_LOG_ERROR( "Fail to provide a color to the ColorRenderer object" );
+  }
+}
+
+void ColorRenderer::SetSize( const Vector2& size )
+{
+  ControlRenderer::SetSize( size );
+
+  // ToDo: renderer responds to the size change
+}
+
+void ColorRenderer::SetClipRect( const Rect<int>& clipRect )
+{
+  ControlRenderer::SetClipRect( clipRect );
+
+  //ToDo: renderer responds to the clipRect change
+}
+
+void ColorRenderer::SetOffset( const Vector2& offset )
+{
+  //ToDo: renderer applies the offset
+}
+
+void ColorRenderer::DoSetOnStage( Actor& actor )
+{
+  mBlendColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor );
+  if( mBlendColor.a < 1.f )
+  {
+    (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
+  }
+}
+
+void ColorRenderer::Initialize( RendererFactoryCache& factoryCache)
+{
+  mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
+  if( !(mImpl->mGeometry) )
+  {
+    mImpl->mGeometry =  RendererFactoryCache::CreateQuadGeometry();
+    factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
+  }
+
+  mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::COLOR_SHADER );
+  if( !(mImpl->mShader) )
+  {
+    mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+    factoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, mImpl->mShader );
+  }
+}
+
+void ColorRenderer::SetColor(const Vector4& color)
+{
+  mBlendColor = color;
+
+  if( mImpl->mIsOnStage )
+  {
+    (mImpl->mRenderer).SetProperty( mBlendColorIndex, color );
+    if( color.a < 1.f &&  (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON)
+    {
+      (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
+    }
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.h b/dali-toolkit/internal/controls/renderers/color/color-renderer.h
new file mode 100644 (file)
index 0000000..5f5dd27
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__
+#define __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__
+
+/*
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * The renderer which renders a solid color to the control's quad
+ *
+ * The following properties are required for create a ColorRender
+ *
+ * | %Property Name   | Type        |
+ * |------------------|-------------|
+ * | blend-color      | VECTOR4     |
+ */
+class ColorRenderer: public ControlRenderer
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  ColorRenderer();
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ColorRenderer();
+
+public:  // from ControlRenderer
+
+  /**
+   * @copydoc ControlRenderer::Initialize
+   */
+  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc ControlRenderer::SetSize
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc ControlRenderer::SetClipRect
+   */
+  virtual void SetClipRect( const Rect<int>& clipRect );
+
+  /**
+   * @copydoc ControlRenderer::SetOffset
+   */
+  virtual void SetOffset( const Vector2& offset );
+
+protected:
+  /**
+   * @copydoc ControlRenderer::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+public:
+
+  /**
+   * Request the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   *
+   * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
+   */
+  void Initialize( RendererFactoryCache& factoryCache );
+
+  /**
+   * Set the color for rendering.
+   * @param[in] color The color to be rendered.
+   */
+  void SetColor( const Vector4& color );
+
+private:
+
+  // Undefined
+  ColorRenderer( const ColorRenderer& colorRenderer );
+
+  // Undefined
+  ColorRenderer& operator=( const ColorRenderer& colorRenderer );
+
+private:
+
+  Vector4 mBlendColor;
+  Property::Index mBlendColorIndex;
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_COLOR_RENDERER_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h
new file mode 100644 (file)
index 0000000..e865a0e
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__
+#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__
+
+/*
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+#include <dali/devel-api/rendering/renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+struct Internal::ControlRenderer::Impl
+{
+  Geometry mGeometry;
+  Shader   mShader;
+  Renderer mRenderer;
+
+  Vector2   mSize;
+  Vector2   mOffset;
+  Rect<int> mClipRect;
+  float     mDepthIndex;
+  bool      mIsOnStage;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp
new file mode 100644 (file)
index 0000000..acc3ead
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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-impl.h"
+
+// EXTERNAL HEADER
+#include <dali/public-api/common/dali-common.h>
+
+//INTERNAL HEARDER
+#include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+ControlRenderer::ControlRenderer()
+: mImpl( new Impl() )
+{
+  mImpl->mIsOnStage = false;
+}
+
+ControlRenderer::~ControlRenderer()
+{
+  delete mImpl;
+}
+
+void ControlRenderer::SetSize( const Vector2& size )
+{
+  mImpl->mSize = size;
+}
+
+void ControlRenderer::SetClipRect( const Rect<int>& clipRect )
+{
+  mImpl->mClipRect = clipRect;
+}
+
+void ControlRenderer::SetOffset( const Vector2& offset )
+{
+  mImpl->mOffset = offset;
+}
+
+void ControlRenderer::SetDepthIndex( float index )
+{
+  mImpl->mDepthIndex = index;
+  if( mImpl->mRenderer )
+  {
+    mImpl->mRenderer.SetDepthIndex( mImpl->mDepthIndex );
+  }
+}
+
+void ControlRenderer::SetOnStage( Actor& actor )
+{
+  Material material = Material::New( mImpl->mShader );
+  mImpl->mRenderer = Renderer::New( mImpl->mGeometry, material );
+  mImpl->mRenderer.SetDepthIndex( mImpl->mDepthIndex );
+  actor.AddRenderer( mImpl->mRenderer );
+  mImpl->mIsOnStage = true;
+
+  DoSetOnStage( actor );
+}
+
+void ControlRenderer::SetOffStage( Actor& actor )
+{
+  DoSetOffStage( actor );
+
+  actor.RemoveRenderer( mImpl->mRenderer );
+  mImpl->mRenderer.Reset();
+
+  mImpl->mIsOnStage = false;
+}
+
+void ControlRenderer::DoSetOnStage( Actor& actor )
+{
+}
+
+void ControlRenderer::DoSetOffStage( Actor& actor )
+{
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h
new file mode 100644 (file)
index 0000000..7c72734
--- /dev/null
@@ -0,0 +1,169 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__
+#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__
+
+/*
+ * 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.
+ *
+ */
+
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class RendererFactoryCache;
+
+/**
+ * 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.
+ */
+class ControlRenderer : public BaseObject
+{
+public:
+
+  /**
+   * Initialisation of the renderer, this API should only called by the RendererFactory:
+   *  request the geometry and shader from the cache, if not available, create and save to the cache for sharing;
+   *  record the property values.
+   *
+   * @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;
+
+  /**
+   * @copydoc Toolkit::ControlRenderer::SetSize
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * ToDo: Add this function to Toolkit::ControlRenderer when it is fully implemented.
+   *
+   * Set the clip rectangular of this renderer.
+   * The contents of the renderer will not be visible outside this rectangular.
+   *
+   * @param [in] clipRect The clipping rectangular.
+   */
+  virtual void SetClipRect( const Rect<int>& clipRect );
+
+  /**
+   *ToDo: Add this function to Toolkit::ControlRenderer when it is fully implemented.
+   *
+   * Reposition this renderer with a 2D offset.
+   *
+   * @param[in] offset The offset to reposition the renderer.
+   */
+  virtual void SetOffset( const Vector2& offset );
+
+  /**
+   * @copydoc Toolkit::ControlRenderer::SetDepthIndex
+   */
+  void SetDepthIndex( float index );
+
+  /**
+   * @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.
+   */
+  void SetOffStage( Actor& actor );
+
+protected:
+
+  /**
+   * @brief Constructor.
+   */
+  ControlRenderer();
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ControlRenderer();
+
+protected:
+
+  /**
+   * 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
+   *
+   * @param[in] actor The actor applying this renderer.
+   */
+  virtual void DoSetOffStage( Actor& actor );
+
+private:
+
+  // Undefined
+  ControlRenderer( const ControlRenderer& renderer );
+
+  // Undefined
+  ControlRenderer& operator=( const ControlRenderer& renderer );
+
+protected:
+
+  struct Impl;
+  Impl* mImpl;
+};
+
+} // namespace Internal
+
+inline const Internal::ControlRenderer& GetImplementation(const Toolkit::ControlRenderer& renderer)
+{
+  DALI_ASSERT_ALWAYS( renderer && "ControlRenderer handle is empty" );
+
+  const BaseObject& handle = renderer.GetBaseObject();
+
+  return static_cast<const Internal::ControlRenderer&>(handle);
+}
+
+inline Internal::ControlRenderer& GetImplementation(Toolkit::ControlRenderer& renderer)
+{
+  DALI_ASSERT_ALWAYS( renderer && "ControlRenderer handle is empty" );
+
+  BaseObject& handle = renderer.GetBaseObject();
+
+  return static_cast<Internal::ControlRenderer&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H___ */
diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp
new file mode 100644 (file)
index 0000000..85beb72
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * 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 "gradient-renderer.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/images/buffer-image.h>
+#include <dali/public-api/object/property-array.h>
+
+//INTERNAL INCLUDES
+#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-data-impl.h>
+#include <dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h>
+#include <dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+// 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
+
+// properties: radial gradient
+const char * const GRADIENT_CENTER_NAME("gradient-center"); // Property::VECTOR2
+const char * const GRADIENT_RADIUS_NAME("gradient-radius"); // Property::FLOAT
+
+// properties: linear&radial gradient
+const char * const GRADIENT_STOP_OFFSET_NAME("gradient-stop-offset"); // Property::Array FLOAT
+const char * const GRADIENT_STOP_COLOR_NAME("gradient-stop-color"); // Property::Array VECTOR4
+const char * const GRADIENT_UNITS_NAME("gradient-units"); // Property::String  "userSpaceOnUse | objectBoundingBox"
+const char * const GRADIENT_SPREAD_METHOD_NAME("gradient-spread-method"); // Property::String  "pad | reflect | repeat"
+
+// string values
+const char * const UNIT_USER_SPACE("user-space");
+const char * const SPREAD_REFLECT("reflect");
+const char * const SPREAD_REPEAT("repeat");
+
+// uniform names
+const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" );
+const char * const UNIFORM_TEXTULRE_NAME("sTexture");
+
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump mat3 uAlignmentMatrix;\n
+  varying mediump vec2 vTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    gl_Position = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_LINEAR = DALI_COMPOSE_SHADER(
+  uniform sampler2D sTexture;\n // sampler1D?
+  uniform lowp vec4 uColor;\n
+  varying mediump vec2 vTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    gl_FragColor = texture2D( sTexture, vec2( vTexCoord.y, 0.5 ) ) * uColor;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_RADIAL = DALI_COMPOSE_SHADER(
+  uniform sampler2D sTexture;\n // sampler1D?
+  uniform lowp vec4 uColor;\n
+  varying mediump vec2 vTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    gl_FragColor = texture2D( sTexture, vec2( length(vTexCoord), 0.5 ) ) * uColor;\n
+  }\n
+);
+
+Sampler::WrapMode GetWrapMode( Gradient::SpreadMethod spread )
+{
+  switch(spread)
+  {
+    case Gradient::REPEAT:
+    {
+      return Sampler::REPEAT;
+    }
+    case Gradient::REFLECT:
+    {
+      return Sampler::MIRRORED_REPEAT;
+    }
+    case Gradient::PAD:
+    default:
+    {
+      return Sampler::CLAMP_TO_EDGE;
+    }
+  }
+}
+
+}
+
+
+GradientRenderer::GradientRenderer()
+:mGradientTransformIndex( Property::INVALID_INDEX )
+{
+}
+
+GradientRenderer::~GradientRenderer()
+{
+}
+
+void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+{
+  mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
+  if( !(mImpl->mGeometry) )
+  {
+    mImpl->mGeometry =  RendererFactoryCache::CreateQuadGeometry();
+    factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
+  }
+
+  Type gradientType;
+  if( propertyMap.Find( GRADIENT_RADIUS_NAME ))
+  {
+    mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL );
+    if( !(mImpl->mShader) )
+    {
+      mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RADIAL );
+      factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL, mImpl->mShader );
+    }
+    gradientType = RADIAL;
+  }
+  else
+  {
+    mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR );
+    if( !(mImpl->mShader) )
+    {
+      mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_LINEAR );
+      factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR, mImpl->mShader );
+    }
+    gradientType = LINEAR;
+  }
+
+  if( NewGradient(gradientType, propertyMap) )
+  {
+    mGradientTransform = mGradient->GetAlignmentTransform();
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Fail to provide valid properties to create a GradientRenderer object" );
+  }
+}
+
+void GradientRenderer::SetSize( const Vector2& size )
+{
+  ControlRenderer::SetSize( size );
+
+  if( mGradient->GetGradientUnits() == Gradient::OBJECT_BOUNDING_BOX )
+  {
+    // Apply scaling
+    Matrix3 scaling( 1.f/(size.x+Math::MACHINE_EPSILON_100), 0.f, 0.f,
+                     0.f, 1.f/(size.y+Math::MACHINE_EPSILON_100), 0.f, 0.5f, 0.5f, 1.f );
+    Matrix3::Multiply( mGradientTransform, scaling, mGradient->GetAlignmentTransform() );
+
+    if( mImpl->mRenderer )
+    {
+      (mImpl->mRenderer).SetProperty( mGradientTransformIndex, mGradientTransform );
+    }
+  }
+}
+
+void GradientRenderer::SetClipRect( const Rect<int>& clipRect )
+{
+  ControlRenderer::SetClipRect( clipRect );
+
+  //ToDo: renderer responds to the clipRect change
+}
+
+void GradientRenderer::SetOffset( const Vector2& offset )
+{
+  //ToDo: renderer applies the offset
+}
+
+void GradientRenderer::DoSetOnStage( Actor& actor )
+{
+  mGradientTransformIndex = (mImpl->mRenderer).RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
+
+  Dali::BufferImage lookupTexture = mGradient->GenerateLookupTexture();
+  Sampler sampler = Sampler::New( lookupTexture, UNIFORM_TEXTULRE_NAME );
+  Sampler::WrapMode wrap = GetWrapMode( mGradient->GetSpreadMethod() );
+  sampler.SetWrapMode(  wrap, wrap  );
+
+  Material material = (mImpl->mRenderer).GetMaterial();
+  if( material )
+  {
+    material.AddSampler( sampler );
+  }
+}
+
+bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& propertyMap)
+{
+  if( gradientType==LINEAR )
+  {
+    Property::Value* startPositionValue = propertyMap.Find( GRADIENT_START_POSITION_NAME );
+    Property::Value* endPositionValue = propertyMap.Find( GRADIENT_END_POSITION_NAME );
+    Vector2 startPosition;
+    Vector2 endPosition;
+
+    if( startPositionValue && startPositionValue->Get(startPosition)
+     && endPositionValue && endPositionValue->Get( endPosition ) )
+    {
+      mGradient = new LinearGradient( startPosition, endPosition );
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else // type==RADIAL
+  {
+    Property::Value* centerValue = propertyMap.Find( GRADIENT_CENTER_NAME );
+    Property::Value* radiusValue = propertyMap.Find( GRADIENT_RADIUS_NAME );
+    Vector2 center;
+    float radius;
+    if( centerValue && centerValue->Get(center)
+        && radiusValue && radiusValue->Get(radius) )
+    {
+      mGradient = new RadialGradient( center, radius );
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  unsigned int numValidStop = 0u;
+  Property::Value* stopOffsetValue = propertyMap.Find( GRADIENT_STOP_OFFSET_NAME );
+  Property::Value* stopColorValue = propertyMap.Find( GRADIENT_STOP_COLOR_NAME );
+  if( stopOffsetValue && stopColorValue )
+  {
+    Property::Array* offsetArray = stopOffsetValue->GetArray();
+    Property::Array* colorArray = stopColorValue->GetArray();
+    if( offsetArray && colorArray )
+    {
+      unsigned int numStop = offsetArray->Count() < colorArray->Count() ?
+                             offsetArray->Count() : colorArray->Count();
+      float offset;
+      Vector4 color;
+      for( unsigned int i=0; i<numStop; i++ )
+      {
+        if( (offsetArray->GetElementAt(i)).Get(offset)
+         && (colorArray->GetElementAt(i)).Get(color) )
+        {
+          mGradient->AddStop( offset, color);
+          numValidStop++;
+        }
+      }
+    }
+  }
+  if( numValidStop < 1u ) // no valid stop
+  {
+    return false;
+  }
+
+  Property::Value* unitsValue = propertyMap.Find( GRADIENT_UNITS_NAME );
+  std::string units;
+  // The default unit is OBJECT_BOUNDING_BOX.
+  // Only need to set new units if 'user-space'
+  if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE )
+  {
+     mGradient->SetGradientUnits( Gradient::USER_SPACE_ON_USE );
+  }
+
+  Property::Value* spread = propertyMap.Find( GRADIENT_SPREAD_METHOD_NAME );
+  std::string stringValue ;
+  // The default spread method is PAD.
+  // Only need to set new spread if 'reflect' or 'repeat"
+  if( spread && spread->Get( stringValue ))
+  {
+    if( stringValue == SPREAD_REFLECT )
+    {
+      mGradient->SetSpreadMethod( Gradient::REFLECT );
+    }
+    else if( stringValue == SPREAD_REPEAT )
+    {
+      mGradient->SetSpreadMethod( Gradient::REPEAT );
+    }
+  }
+
+  return true;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h
new file mode 100644 (file)
index 0000000..4d595db
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__
+#define __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__
+
+/*
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+#include <dali-toolkit/internal/controls/renderers/gradient/gradient.h>
+
+namespace Dali
+{
+class Vector2;
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class Gradient;
+
+/**
+ * The renderer which renders smooth transition of colors to the control's quad.
+ * It supports two types of gradients: linear and radial.
+ *
+ * The following properties are essential for create a LINEAR GradientRender
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | gradient-start-position   | VECTOR2          |
+ * | gradient-end-position     | VECTOR2          |
+ * | gradient-stop-offset      | ARRAY of FLOAT   |
+ * | gradient-stop-color       | ARRAY of VECTOR4 |
+ *
+ * The following properties are essential for create a RADIAL GradientRender
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | gradient-center           | VECTOR2          |
+ * | gradient-radius           | FLOAT            |
+ * | gradient-stop-offset      | ARRAY of FLOAT   |
+ * | gradient-stop-color       | ARRAY of VECTOR4 |
+ *
+ * The following properties are optional for both LINEAR and RADIAL GradientRender.
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | gradient-units            | STRING           |
+ * | gradient-spread-method    | STRING           |
+ *
+ * Valid values for gradient-units are 'user-space' and 'object-bounding-box'.
+ * Valid values for gradient-spread-method are 'pad', 'repeat' and 'reflect.'
+ * If not provided, 'objectBoundingBox' is used as default gradient units, and 'pad' is used as default spread method.
+ */
+class GradientRenderer: public ControlRenderer
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  GradientRenderer();
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  ~GradientRenderer();
+
+public:  // from ControlRenderer
+
+  /**
+   * @copydoc ControlRenderer::Initialize
+   */
+  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc ControlRenderer::SetSize
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc ControlRenderer::SetClipRect
+   */
+  virtual void SetClipRect( const Rect<int>& clipRect );
+
+  /**
+   * @copydoc ControlRenderer::SetOffset
+   */
+  virtual void SetOffset( const Vector2& offset );
+
+protected:
+  /**
+   * @copydoc ControlRenderer::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+private:
+
+  /**
+   * Types of the gradient
+   */
+  enum Type
+  {
+    LINEAR,
+    RADIAL
+  };
+
+  /**
+   * New a gradient object with the given property map.
+   *
+   * @return True if the property map provides valid properties to create a gradient. Otherwise, returns false.
+   */
+  bool NewGradient(Type gradientType, const Property::Map& propertyMap);
+
+  // Undefined
+  GradientRenderer( const GradientRenderer& gradientRenderer );
+
+  // Undefined
+  GradientRenderer& operator=( const GradientRenderer& gradientRenderer );
+
+private:
+
+  Matrix3 mGradientTransform;
+  Property::Index mGradientTransformIndex;
+  IntrusivePtr<Gradient> mGradient;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient.cpp
new file mode 100644 (file)
index 0000000..920fddd
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ *
+ */
+
+#include "gradient.h"
+
+#include <algorithm>    // std::sort
+#include <dali/public-api/math/vector4.h>
+
+namespace
+{
+// The maximum width of the lookup texture ( it is a 1-dimension texture with the height as 1 )
+const unsigned int MAXIMUM_TEXTURE_RESOLUTION(128u);
+}
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+Gradient::Gradient()
+: mGradientUnits( OBJECT_BOUNDING_BOX ),
+  mSpreadMethod( PAD )
+{}
+
+Gradient::~Gradient()
+{}
+
+void Gradient::AddStop( float offset, const Vector4& color )
+{
+  // the offset is clamped to the range [0.0, 1.0]
+  mGradientStops.PushBack( GradientStop( Clamp( offset, 0.f, 1.f ), color) );
+}
+
+void Gradient::SetGradientUnits( GradientUnits gradientUnits )
+{
+  mGradientUnits = gradientUnits;
+}
+
+Gradient::GradientUnits Gradient::GetGradientUnits() const
+{
+  return mGradientUnits;
+}
+
+void Gradient::SetSpreadMethod( SpreadMethod spread )
+{
+  mSpreadMethod = spread;
+}
+
+Gradient::SpreadMethod Gradient::GetSpreadMethod() const
+{
+  return mSpreadMethod;
+}
+
+const Matrix3& Gradient::GetAlignmentTransform() const
+{
+  return mAlignmentTransform;
+}
+
+/**
+ * Following the SVG gradient.
+ *
+ * Not only the spread method decides the texture wrap mode:
+ *    PAD-->GL_CLAMP_TO_EDGE; REPEAT-->GL_REPEAT; REFLECT-->GL_MIRROR_REPEAT
+ *
+ *  If the stops have not covered the whole zero to one range,
+ *  the REPEAT spread behaves different from the two others in the lookup texture generation.
+ */
+BufferImage Gradient::GenerateLookupTexture()
+{
+  std::sort( mGradientStops.Begin(), mGradientStops.End() );
+
+  unsigned int numStops = mGradientStops.Count();
+
+  /**
+   * If the stops have not covered the whole zero to one range,
+   * for PAD and REFLECT, use the color of the first stop to fill the range  [0.0, first stop offset)
+   *                  and use the color of the last stop to fill the range (last stop offset, 1.0]
+   * for REPEAT, mix the two color of the first and last stop to fill the remainder
+   */
+  bool tempFirstStop = false;
+  if( mGradientStops[0].mOffset > 0.f )
+  {
+    tempFirstStop = true;
+    Vector4 firstStopColor( mGradientStops[0].mStopColor ); // If spread method is PAD or REFLECT
+    if( mSpreadMethod == REPEAT )
+    {
+      firstStopColor = ( mGradientStops[0].mStopColor * (1.f-mGradientStops[numStops-1].mOffset)
+                       + mGradientStops[numStops-1].mStopColor  * mGradientStops[0].mOffset )
+                   / ( mGradientStops[0].mOffset+1.f-mGradientStops[numStops-1].mOffset);
+    }
+
+    mGradientStops.Insert( mGradientStops.Begin(), GradientStop(0.f, firstStopColor) );
+    numStops++;
+  }
+
+  bool tempLastStop = false;
+  if( mGradientStops[numStops-1].mOffset < 1.f )
+  {
+    tempLastStop = true;
+    Vector4 lastStopColor( mGradientStops[numStops-1].mStopColor ); // If spread method is PAD or REFLECT
+    if( mSpreadMethod == REPEAT )
+    {
+      lastStopColor = mGradientStops[0].mStopColor;
+    }
+    mGradientStops.PushBack( GradientStop(1.f, lastStopColor) );
+    numStops++;
+  }
+
+  /**
+   * Generate the pixels with the color transit from one stop to next.
+   */
+  unsigned int resolution = EstimateTextureResolution();
+  BufferImage texture = BufferImage::New( resolution, 1 );
+  PixelBuffer* pixels = texture.GetBuffer();
+  int segmentStart = 0;
+  int segmentEnd = 0;
+  int k = 0;
+  float length = static_cast<float>(resolution);
+  for( unsigned int i=0; i<numStops-1u; i++ )
+  {
+    segmentEnd = floorf(mGradientStops[i+1].mOffset * length + 0.5f);
+    if( segmentEnd == segmentStart )
+    {
+      continue;
+    }
+    float segmentWidth = static_cast<float>(segmentEnd-segmentStart);
+
+    for( int j = segmentStart; j<segmentEnd; j++ )
+    {
+      float ratio = static_cast<float>(j-segmentStart)/segmentWidth;
+      Vector4 currentColor = mGradientStops[i].mStopColor * (1.f-ratio) + mGradientStops[i+1].mStopColor * ratio;
+      pixels[k*4] = static_cast<unsigned char>( 255.f * Clamp( currentColor.r, 0.f, 1.f ) );
+      pixels[k*4+1] = static_cast<unsigned char>( 255.f * Clamp( currentColor.g, 0.f, 1.f ) );
+      pixels[k*4+2] = static_cast<unsigned char>( 255.f * Clamp( currentColor.b, 0.f, 1.f ) );
+      pixels[k*4+3] = static_cast<unsigned char>( 255.f * Clamp( currentColor.a, 0.f, 1.f ) );
+      k++;
+    }
+    segmentStart = segmentEnd;
+  }
+
+  // remove the stops added temporarily for generating the pixels, as the spread method might get changed later
+  if( tempLastStop )
+  {
+    mGradientStops.Erase( mGradientStops.Begin()+numStops-1 );
+  }
+  if( tempFirstStop )
+  {
+    mGradientStops.Erase( mGradientStops.Begin());
+  }
+
+  return texture;
+}
+
+unsigned int Gradient::EstimateTextureResolution()
+{
+  float minInterval = 1.0;
+  for( unsigned int i=0, numStops = mGradientStops.Count(); i<numStops-1u; i++ )
+  {
+    float interval = mGradientStops[i+1].mOffset - mGradientStops[i].mOffset;
+    minInterval = interval > minInterval ? minInterval:interval;
+  }
+  // Use at least three pixels for each segment between two stops
+  unsigned int resolution = static_cast<int>(3.f/(minInterval+Math::MACHINE_EPSILON_100)+0.5f);
+  // Clamp the resolution to handle the overlapping stops
+  if( resolution > MAXIMUM_TEXTURE_RESOLUTION )
+  {
+    return MAXIMUM_TEXTURE_RESOLUTION;
+  }
+
+  return resolution;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient.h b/dali-toolkit/internal/controls/renderers/gradient/gradient.h
new file mode 100644 (file)
index 0000000..82b58cb
--- /dev/null
@@ -0,0 +1,173 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_GRADIENT_H__
+#define __DALI_TOOLKIT_INTERNAL_GRADIENT_H__
+
+/*
+ * 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.
+ *
+ */
+
+//EXTERNAL INCLUDES
+#include <dali/public-api/math/matrix3.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/images/buffer-image.h>
+
+namespace Dali
+{
+
+class Vector4;
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Gradients consist of continuously smooth color transitions along a vector from one color to another,
+ * possibly followed by additional transitions along the same vector to other colors.
+ */
+class Gradient : public RefObject
+{
+public:
+  /**
+   * Defines the coordinate system of the attributes
+   *     (start and end position for linear gradient, circle center and radius for radial gradient)
+   */
+  enum GradientUnits
+  {
+    USER_SPACE_ON_USE,
+    OBJECT_BOUNDING_BOX
+  };
+
+  /**
+   * Indicates what happens if the gradient starts or ends inside the bounds of the object being painted by the gradient.
+   */
+  enum SpreadMethod
+  {
+    PAD,      // use the terminal colors of the gradient to fill the remainder of the target region
+    REPEAT,   // reflect the gradient pattern start-to-end, end-to-start, start-to-end, etc. continuously until the target rectangle is filled
+    REFLECT   // repeat the gradient pattern start-to-end, start-to-end, start-to-end, etc. continuously until the target region is filled
+  };
+
+  /**
+   * The stop node tells the gradient what color it should be at certain position.
+   */
+  struct GradientStop
+  {
+    GradientStop( float offset, const Vector4& color )
+    : mOffset( offset ), mStopColor( color )
+    {}
+
+    bool operator<(const GradientStop& rhs) const
+    {
+      return mOffset < rhs.mOffset;
+    }
+
+    float   mOffset;     // A value ranging from 0 to 1 to indicate where the gradient stop is placed.
+    Vector4 mStopColor;  // The color to use at this gradient stop
+  };
+
+public:
+
+  /**
+   * Add a gradient stop.
+   *
+   * @param[in] offset The position to place the stop.
+   * @param[in] color  The color to use at this stop.
+   */
+  void AddStop(float offset, const Vector4& color);
+
+  /**
+   * 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.
+   */
+  void SetGradientUnits( GradientUnits gradientUnits );
+
+  /**
+   * Get the coordinate system used by the gradient attributes.
+   * @return USER_SPACE_ON_USE or OBJECT_BOUNDING_BOX
+   */
+  GradientUnits GetGradientUnits() const;
+
+  /**
+   * Indicates what happens if the gradient starts or ends inside the bounds of the target rectangle.
+   * If not specified, the effect is as if a value of 'pad' were specified
+   *
+   * @param[in] spread The method to fill the remainder of target region which is outside the gradient bounds
+   */
+  void SetSpreadMethod( SpreadMethod spread );
+
+  /**
+   * Get the filling method for the the remainder of target region which is outside the gradient boun.
+   * @return PAD, REFLECT or REPEAT
+   */
+  SpreadMethod GetSpreadMethod() const;
+
+  /**
+   * Get the transformation matrix to align the vertices with the gradient line/circle
+   * @ return the aligning transformation matrix
+   */
+  const Matrix3& GetAlignmentTransform() const;
+
+  /**
+   * Generate the lookup texture with the gradient stops.
+   * @return the lookup texture which transit smoothly between stops.
+   */
+  BufferImage GenerateLookupTexture();
+
+private:
+
+  /**
+   * Estimate the resolution of the lookup texture.
+   * Note: Only call this function after the gradient stops are sorted in order.
+   */
+  unsigned int EstimateTextureResolution();
+
+protected:
+
+  /**
+   * Construct a new Gradient object
+   * Called in the constructor of subclasses
+   */
+  Gradient();
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~Gradient();
+
+  // Undefined
+  Gradient( const Gradient& gradient );
+
+  // Undefined
+  Gradient& operator=( const Gradient& handle );
+
+protected:
+
+  Vector<GradientStop>      mGradientStops;
+  Matrix3                   mAlignmentTransform;
+  GradientUnits             mGradientUnits;
+  SpreadMethod              mSpreadMethod;
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.cpp
new file mode 100644 (file)
index 0000000..d1453a6
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+
+#include "linear-gradient.h"
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+LinearGradient::LinearGradient( const Vector2& startPosition, const Vector2& endPosition )
+: Gradient()
+{
+  SetStartAndEndPosition( startPosition, endPosition );
+}
+
+LinearGradient::~LinearGradient()
+{}
+
+void LinearGradient::SetStartAndEndPosition( const Vector2& startPosition, const Vector2& endPosition )
+{
+  mStartPosition = startPosition;
+  mEndPosition = endPosition;
+
+  // Calculate the transform aligning to the gradient line
+  float dx = mEndPosition.x - mStartPosition.x;
+  float dy = mEndPosition.y - mStartPosition.y;
+  Matrix3 alignMatrix( dy, -dx, 0.f, dx, dy, 0.f, mStartPosition.x, mStartPosition.y, 1.f );
+  alignMatrix.Invert();
+
+  mAlignmentTransform = alignMatrix;
+}
+
+const Vector2& LinearGradient::GetStartPosition() const
+{
+  return mStartPosition;
+}
+
+const Vector2& LinearGradient::GetEndPosition() const
+{
+  return mEndPosition;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h b/dali-toolkit/internal/controls/renderers/gradient/linear-gradient.h
new file mode 100644 (file)
index 0000000..099e9bf
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__
+#define __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__
+
+/*
+ * 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.
+ *
+ */
+
+#include <dali-toolkit/internal/controls/renderers/gradient/gradient.h>
+
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Linear gradients change color evenly along a straight line.
+ * The gradient is defined by an axis (the gradient line) at any specified angles.
+ */
+class LinearGradient : public Gradient
+{
+public:
+
+  /**
+   * Constructor.
+   * @param[in] startPosition The starting point onto which the 0% gradient stops are mapped.
+   * @param[in] endPosition The ending point r onto which the 100% gradient stops are mapped.
+   */
+  LinearGradient( const Vector2& startPosition, const Vector2& endPosition );
+
+  /**
+   * Destructor.
+   */
+  virtual ~LinearGradient();
+
+  /**
+   * Set the starting and ending points of the vector onto which the gradient stops are mapped.
+   * @param[in] startPosition The starting point of the gradient vector.
+   * @param[in] endPosition The ending point of the gradient vector.
+   */
+  void SetStartAndEndPosition( const Vector2& startPosition, const Vector2& endPosition );
+
+  /**
+   * Get the stating point of the gradient vector.
+   * @return The stating point of the gradient vector.
+   */
+  const Vector2& GetStartPosition() const;
+
+  /**
+   * Get the ending point of the gradient vector.
+   * @return The ending point of the gradient vector.
+   */
+  const Vector2& GetEndPosition() const;
+
+private:
+
+  // Undefined
+  LinearGradient( const LinearGradient& gradient );
+
+  // Undefined
+  LinearGradient& operator=( const LinearGradient& handle );
+
+private:
+
+  Vector2 mStartPosition;
+  Vector2 mEndPosition;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_LINEAR_GRADIENT_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.cpp
new file mode 100644 (file)
index 0000000..e986612
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ *
+ */
+
+#include "radial-gradient.h"
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+RadialGradient::RadialGradient( const Vector2& center, float radius )
+: Gradient()
+{
+  SetCenterAndRadius( center, radius );
+}
+
+RadialGradient::~RadialGradient()
+{}
+
+void RadialGradient::SetCenterAndRadius( const Vector2& center, float radius )
+{
+  mCenter = center;
+  mRadius = radius;
+
+  // Calculate the transform aligning to the circle
+  Matrix3 alignMatrix( mRadius, 0.f, 0.f, 0.f, mRadius, 0.f, mCenter.x, mCenter.y, 1.f );
+  alignMatrix.Invert();
+
+  mAlignmentTransform = alignMatrix;
+}
+
+const Vector2& RadialGradient::GetCenter() const
+{
+  return mCenter;
+}
+
+float RadialGradient::GetRadius() const
+{
+  return mRadius;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h b/dali-toolkit/internal/controls/renderers/gradient/radial-gradient.h
new file mode 100644 (file)
index 0000000..f2f2135
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__
+#define __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__
+
+/*
+ * 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.
+ *
+ */
+
+#include <dali-toolkit/internal/controls/renderers/gradient/gradient.h>
+
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Radial gradients change color circularly.
+ * The color transition starts from the center of the circle and distribute outwardly.
+ */
+class RadialGradient : public Gradient
+{
+public:
+
+  /**
+   * Contructor.
+   * @param[in] center The center of the gradient circle onto which the 0% gradient stop is mapped.
+   * @param[in] radius The radius of the outmost circle onto which the 100% gradient stop is mapped.
+   */
+  RadialGradient( const Vector2& center, float radius );
+
+  /**
+   * Destructor.
+   */
+  virtual ~RadialGradient();
+
+  /**
+   * Set the center and radius of the outermost circle for the radial gradient.
+   * @param[in] center The center of the gradient circle onto which the 0% gradient stop is mapped.
+   * @param[in] radius The radius of the outmost circle onto which the 100% gradient stop is mapped.
+   */
+  void SetCenterAndRadius( const Vector2& center, float radius );
+
+  /**
+   * Get the center of the gradient circle.
+   * @return The center of the gradient circle.
+   */
+  const Vector2& GetCenter() const;
+
+  /**
+   * Get the radius of the outmost gradient circle.
+   * @return The radius of the outmost gradient circle.
+   */
+  float GetRadius() const;
+
+private:
+
+  // Undefined
+  RadialGradient( const RadialGradient& gradient );
+
+  // Undefined
+  RadialGradient& operator=( const RadialGradient& handle );
+
+private:
+
+  Vector2 mCenter;
+  float   mRadius;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_RADIAL_GRADIENT_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
new file mode 100644 (file)
index 0000000..3a2da25
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * 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 "image-renderer.h"
+
+#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 Toolkit
+{
+
+namespace Internal
+{
+
+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");
+
+std::string TEXTURE_UNIFORM_NAME = "sTexture";
+
+#define MAKE_SHADER(A)#A
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  varying mediump vec2 vTexCoord;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = aPosition + vec2(0.5);\n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform lowp vec4 uColor;\n
+  \n
+  void main()\n
+  {\n
+    gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+  }\n
+);
+
+} //unnamed namespace
+
+ImageRenderer::ImageRenderer()
+: ControlRenderer(),
+  mDesiredSize(),
+  mFittingMode( FittingMode::DEFAULT ),
+  mSamplingMode( SamplingMode::DEFAULT )
+{
+}
+
+ImageRenderer::~ImageRenderer()
+{
+}
+
+void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
+{
+  Initialize(factoryCache);
+
+  Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
+  if( imageURLValue )
+  {
+    imageURLValue->Get( mImageUrl );
+
+    Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE );
+    if( fittingValue )
+    {
+      std::string fitting;
+      fittingValue->Get( fitting );
+
+      mFittingMode = FittingMode::DEFAULT;
+      if( fitting == "shrink-to-fit" )
+      {
+        mFittingMode = FittingMode::SHRINK_TO_FIT;
+      }
+      else if( fitting == "scale-to-fill" )
+      {
+        mFittingMode = FittingMode::SCALE_TO_FILL;
+      }
+      else if( fitting == "fit-width" )
+      {
+        mFittingMode = FittingMode::FIT_WIDTH;
+      }
+      else if( fitting == "fit-height" )
+      {
+        mFittingMode = FittingMode::FIT_HEIGHT;
+      }
+      else if( fitting == "default" )
+      {
+        mFittingMode = FittingMode::DEFAULT;
+      }
+      else
+      {
+        DALI_ASSERT_ALWAYS("Unknown fitting mode");
+      }
+    }
+
+    Property::Value* samplingValue = propertyMap.Find( IMAGE_SAMPLING_MODE );
+    if( samplingValue )
+    {
+      std::string sampling;
+      samplingValue->Get( sampling );
+
+      mSamplingMode = SamplingMode::DEFAULT;
+      if( sampling == "box" )
+      {
+        mSamplingMode = SamplingMode::BOX;
+      }
+      else if( sampling == "nearest" )
+      {
+        mSamplingMode = SamplingMode::NEAREST;
+      }
+      else if( sampling == "linear" )
+      {
+        mSamplingMode = SamplingMode::LINEAR;
+      }
+      else if( sampling == "box-then-nearest" )
+      {
+        mSamplingMode = SamplingMode::BOX_THEN_NEAREST;
+      }
+      else if( sampling == "box-then-linear" )
+      {
+        mSamplingMode = SamplingMode::BOX_THEN_LINEAR;
+      }
+      else if( sampling == "no-filter" )
+      {
+        mSamplingMode = SamplingMode::NO_FILTER;
+      }
+      else if( sampling == "dont-care" )
+      {
+        mSamplingMode = SamplingMode::DONT_CARE;
+      }
+      else if( sampling == "default" )
+      {
+        mSamplingMode = SamplingMode::DEFAULT;
+      }
+      else
+      {
+        DALI_ASSERT_ALWAYS("Unknown sampling mode");
+      }
+    }
+
+    int desiredWidth = 0;
+    Property::Value* desiredWidthValue = propertyMap.Find( IMAGE_DESIRED_WIDTH );
+    if( desiredWidthValue )
+    {
+      desiredWidthValue->Get( desiredWidth );
+    }
+
+    int desiredHeight = 0;
+    Property::Value* desiredHeightValue = propertyMap.Find( IMAGE_DESIRED_HEIGHT );
+    if( desiredHeightValue )
+    {
+      desiredHeightValue->Get( desiredHeight );
+    }
+
+    mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
+  }
+
+  mImage.Reset();
+}
+
+void ImageRenderer::SetSize( const Vector2& size )
+{
+  ControlRenderer::SetSize( size );
+  // ToDo: renderer responds to the size change
+}
+
+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 )
+{
+  if( !mImageUrl.empty() && !mImage )
+  {
+    mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+  }
+
+  ApplyImageToSampler();
+}
+
+void ImageRenderer::DoSetOffStage( Actor& actor )
+{
+  //If we own the image then make sure we release it when we go off stage
+  if( !mImageUrl.empty() )
+  {
+    mImage.Reset();
+  }
+
+  ControlRenderer::SetOffStage( actor );
+}
+
+void ImageRenderer::Initialize( RendererFactoryCache& factoryCache )
+{
+  mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
+  if( !(mImpl->mGeometry) )
+  {
+    mImpl->mGeometry =  factoryCache.CreateQuadGeometry();
+    factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
+  }
+
+  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 );
+  }
+
+  mDesiredSize = ImageDimensions();
+  mFittingMode = FittingMode::DEFAULT;
+  mSamplingMode = SamplingMode::DEFAULT;
+  mImageUrl.clear();
+}
+
+void ImageRenderer::SetImage( const std::string& imageUrl )
+{
+  SetImage( imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT );
+}
+
+void ImageRenderer::SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
+{
+  if( mImageUrl != imageUrl )
+  {
+    mImageUrl = imageUrl;
+    mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
+    mFittingMode = fittingMode;
+    mSamplingMode = samplingMode;
+
+    if( !mImageUrl.empty() && mImpl->mIsOnStage )
+    {
+      mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+      ApplyImageToSampler();
+    }
+    else
+    {
+      mImage.Reset();
+    }
+  }
+}
+
+void ImageRenderer::SetImage( Image image )
+{
+  if( mImage != image )
+  {
+    mImageUrl.clear();
+    mDesiredSize = ImageDimensions();
+    mFittingMode = FittingMode::DEFAULT;
+    mSamplingMode = SamplingMode::DEFAULT;
+    mImage = image;
+
+    if( mImage && mImpl->mIsOnStage )
+    {
+      ApplyImageToSampler();
+    }
+  }
+}
+
+void ImageRenderer::ApplyImageToSampler()
+{
+  if( mImage )
+  {
+    Material material = mImpl->mRenderer.GetMaterial();
+    if( material )
+    {
+      for( std::size_t i = 0; i < material.GetNumberOfSamplers(); ++i )
+      {
+        Sampler sampler = material.GetSamplerAt( i );
+        if( sampler.GetUniformName() == TEXTURE_UNIFORM_NAME )
+        {
+          sampler.SetImage( mImage );
+          return;
+        }
+      }
+
+      Sampler sampler = Sampler::New( mImage, TEXTURE_UNIFORM_NAME );
+      material.AddSampler( sampler );
+    }
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.h b/dali-toolkit/internal/controls/renderers/image/image-renderer.h
new file mode 100644 (file)
index 0000000..e3a60a0
--- /dev/null
@@ -0,0 +1,177 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_IMAGE_RENDERER_H__
+#define __DALI_TOOLKIT_INTERNAL_IMAGE_RENDERER_H__
+
+/*
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/images/image.h>
+#include <dali/public-api/images/image-operations.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class ImageRenderer;
+typedef IntrusivePtr< ImageRenderer > ImageRendererPtr;
+
+/**
+ * The renderer which renders an image to the control's quad
+ *
+ * The following properties are optional
+ *
+ * | %Property Name            | Type             |
+ * |---------------------------|------------------|
+ * | image-url                 | STRING           |
+ * | image-fitting-mode        | STRING           |
+ * | image-sampling-mode       | STRING           |
+ * | image-desired-width       | INT              |
+ * | image-desired-height      | INT              |
+ *
+ * where image-fitting-mode should be one of the following fitting modes:
+ *   "shrink-to-fit"
+ *   "scale-to-fill"
+ *   "fit-width"
+ *   "fit-height"
+ *   "default"
+ *
+ * where image-sampling-mode should be one of the following sampling modes:
+ *   "box"
+ *   "nearest"
+ *   "linear"
+ *   "box-then-nearest"
+ *   "box-then-linear"
+ *   "no-filter"
+ *   "dont-care"
+ *   "default"
+ *
+ */
+class ImageRenderer: public ControlRenderer
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  ImageRenderer();
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  ~ImageRenderer();
+
+public:  // from ControlRenderer
+
+  /**
+   * @copydoc ControlRenderer::Initialize
+   */
+  virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc ControlRenderer::SetSize
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc ControlRenderer::SetClipRect
+   */
+  virtual void SetClipRect( const Rect<int>& clipRect );
+
+  /**
+   * @copydoc ControlRenderer::SetOffset
+   */
+  virtual void SetOffset( const Vector2& offset );
+
+protected:
+  /**
+   * @copydoc ControlRenderer::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+  /**
+   * @copydoc ControlRenderer::DoSetOffStage
+   */
+  virtual void DoSetOffStage( Actor& actor );
+
+public:
+
+  /**
+   * Request the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   *
+   * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
+   */
+  void Initialize( RendererFactoryCache& factoryCache );
+
+  /**
+   * @brief Sets the image of this renderer to the resource at imageUrl
+   * The renderer will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] imageUrl The URL to to image resource to use
+   */
+  void SetImage( const std::string& imageUrl );
+
+  /**
+   * @brief Sets the image of this renderer to the resource at imageUrl
+   * The renderer will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] imageUrl The URL to to image resource to use
+   * @param[in] desiredWidth The desired width of the resource to load
+   * @param[in] desiredHeight The desired height of the resource to load
+   * @param[in] fittingMode The FittingMode of the resource to load
+   * @param[in] samplingMode The SamplingMode of the resource to load
+   */
+  void SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode );
+
+  /**
+   * @brief Sets the image of this renderer to use
+   *
+   * @param[in] image The image to use
+   */
+  void SetImage( Image image );
+
+private:
+
+  /**
+   * @brief Applies this renderer's image to the sampler to the material used for this renderer
+   */
+  void ApplyImageToSampler();
+
+private:
+  Image mImage;
+
+  std::string mImageUrl;
+  Dali::ImageDimensions mDesiredSize;
+  Dali::FittingMode::Type mFittingMode;
+  Dali::SamplingMode::Type mSamplingMode;
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_IMAGE_RENDERER_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp
new file mode 100644 (file)
index 0000000..462e29c
--- /dev/null
@@ -0,0 +1,115 @@
+ /*
+ * 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 "renderer-factory-cache.h"
+
+// Internal HEADER
+#include <dali-toolkit/internal/controls/renderers/color/color-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+RendererFactoryCache::RendererFactoryCache()
+{
+}
+
+RendererFactoryCache::~RendererFactoryCache()
+{
+  for( int i=0; i<= SHADER_TYPE_MAX; i++)
+  {
+    if(mShader[i])
+    {
+      mShader[i].Reset();
+    }
+  }
+
+  for( int i=0; i<= GEOMETRY_TYPE_MAX; i++)
+  {
+    if(mGeometry[i])
+    {
+      mGeometry[i].Reset();
+    }
+  }
+}
+
+
+Geometry RendererFactoryCache::GetGeometry( GeometryType type )
+{
+  return mGeometry[type];
+}
+
+void RendererFactoryCache::SaveGeometry( GeometryType type, Geometry geometry)
+{
+  mGeometry[type] = geometry;
+}
+
+Shader RendererFactoryCache::GetShader( ShaderType type )
+{
+  return mShader[type];
+}
+
+void RendererFactoryCache::SaveShader( ShaderType type, Shader shader )
+{
+  mShader[type] = shader;
+}
+
+Geometry RendererFactoryCache::CreateQuadGeometry()
+{
+  const float halfWidth = 0.5f;
+  const float halfHeight = 0.5f;
+  struct QuadVertex { Vector2 position;};
+  QuadVertex quadVertexData[4] =
+  {
+      { Vector2(-halfWidth, -halfHeight) },
+      { Vector2( halfWidth, -halfHeight) },
+      { Vector2(-halfWidth, halfHeight)  },
+      { Vector2( halfWidth, halfHeight)  }
+  };
+
+  Property::Map quadVertexFormat;
+  quadVertexFormat["aPosition"] = Property::VECTOR2;
+  PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat, 4 );
+  quadVertices.SetData(quadVertexData);
+
+  // Create indices
+  //TODO: replace with triangle strip when Geometry supports it
+  unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 };
+  Property::Map indexFormat;
+  indexFormat["indices"] = Property::INTEGER;
+  PropertyBuffer indices = PropertyBuffer::New( indexFormat, 6 );
+  indices.SetData(indexData);
+
+  // Create the geometry object
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer( quadVertices );
+  geometry.SetIndexBuffer( indices );
+
+  return geometry;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h
new file mode 100644 (file)
index 0000000..e6c8d88
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__
+#define __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__
+
+/*
+ * 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.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/ref-object.h>
+#include <dali/devel-api/rendering/geometry.h>
+#include <dali/devel-api/rendering/shader.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Caches shaders and geometries. Owned by RenderFactory.
+ */
+class RendererFactoryCache : public RefObject
+{
+public:
+
+  /**
+   * Type of shader for caching.
+   */
+  enum ShaderType
+  {
+    COLOR_SHADER,
+    BORDER_SHADER,
+    GRADIENT_SHADER_LINEAR,
+    GRADIENT_SHADER_RADIAL,
+    IMAGE_SHADER,
+    N_PATCH_SHADER,
+    SVG_SHADER,
+    SHADER_TYPE_MAX = SVG_SHADER
+  };
+
+  /**
+   * Type of geometry for caching.
+   */
+  enum GeometryType
+  {
+    QUAD_GEOMETRY,
+    NINE_PATCH_GEOMETRY,
+    GEOMETRY_TYPE_MAX = NINE_PATCH_GEOMETRY
+  };
+
+public:
+
+  /**
+   * @brief Constructor
+   */
+  RendererFactoryCache();
+
+  /**
+   * Request geometry of the given type.
+   * @return The geometry of the required type if it exist in the cache. Otherwise, an empty handle is returned.
+   */
+  Geometry GetGeometry( GeometryType type );
+
+  /**
+   * Cache the geometry of the give type.
+   * @param[in] type The geometry type.
+   * @param[in] geometry The geometry for caching.
+   */
+  void SaveGeometry( GeometryType type, Geometry geometry);
+
+  /**
+   * Request shader of the given type.
+   * @return The shader of the required type if it exist in the cache. Otherwise, an empty handle is returned.
+   */
+  Shader GetShader( ShaderType type );
+
+  /**
+   * Cache the geometry of the give type.
+   * @param[in] type The geometry type.
+   * @param[in] geometry The geometry for caching.
+   */
+  void SaveShader( ShaderType type, Shader shader );
+
+  /*
+   * Greate the quad geometry.
+   * Quad geometry is shared by multiple kind of Renderer, so implement it in the factory-cache.
+   */
+  static Geometry CreateQuadGeometry();
+
+protected:
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~RendererFactoryCache();
+
+  /**
+   * Undefined copy constructor.
+   */
+  RendererFactoryCache(const RendererFactoryCache&);
+
+  /**
+   * Undefined assignment operator.
+   */
+  RendererFactoryCache& operator=(const RendererFactoryCache& rhs);
+
+private:
+
+  // ToDo: test whether using the WeakHandle could improve the performance
+  //       With WeakHandle, the resource would be released automatically when no control is using it
+
+  Geometry mGeometry[GEOMETRY_TYPE_MAX+1];
+  Shader mShader[SHADER_TYPE_MAX+1];
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /*__DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ */
diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp
new file mode 100644 (file)
index 0000000..1320436
--- /dev/null
@@ -0,0 +1,174 @@
+ /*
+ * 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 "renderer-factory-impl.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/images/image.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+
+// Internal HEADER
+#include <dali-toolkit/internal/controls/renderers/color/color-renderer.h>
+#include <dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h>
+#include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
+#include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
+
+namespace
+{
+const char * const RENDERER_TYPE_NAME( "renderer-type" );
+const char * const COLOR_RENDERER("color-renderer");
+const char * const GRADIENT_RENDERER("gradient-renderer");
+const char * const IMAGE_RENDERER("image-renderer");
+}
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+BaseHandle Create()
+{
+  BaseHandle handle = Toolkit::RendererFactory::Get();
+
+  return handle;
+}
+
+DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::RendererFactory, Dali::BaseHandle, Create, true )
+DALI_TYPE_REGISTRATION_END()
+
+} // namespace
+
+RendererFactory::RendererFactory()
+{
+}
+
+RendererFactory::~RendererFactory()
+{
+}
+
+Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap )
+{
+  ControlRenderer* rendererPtr = NULL;
+
+  Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
+  std::string typeValue ;
+  if( type && type->Get( typeValue ))
+  {
+    if( typeValue ==  COLOR_RENDERER )
+    {
+      rendererPtr = new ColorRenderer();
+    }
+    else if( typeValue ==  GRADIENT_RENDERER )
+    {
+      rendererPtr = new GradientRenderer();
+    }
+    else if( typeValue ==  IMAGE_RENDERER )
+    {
+      rendererPtr = new ImageRenderer();
+    }
+  }
+
+  if( rendererPtr )
+  {
+    if( !mFactoryCache )
+    {
+      mFactoryCache = new RendererFactoryCache();
+    }
+    rendererPtr->Initialize( *( mFactoryCache.Get() ), propertyMap );
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Renderer type unknown" );
+  }
+
+  return Toolkit::ControlRenderer(rendererPtr);
+}
+
+Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color )
+{
+  ColorRenderer* rendererPtr = new ColorRenderer();
+
+  if( !mFactoryCache )
+  {
+    mFactoryCache = new RendererFactoryCache();
+  }
+  rendererPtr->Initialize( *( mFactoryCache.Get() ) );
+
+  rendererPtr->SetColor(color);
+
+  return Toolkit::ControlRenderer(rendererPtr);
+}
+
+bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color )
+{
+  ColorRenderer* rendererPtr = dynamic_cast<ColorRenderer*>(&GetImplementation(renderer));
+  if( rendererPtr )
+  {
+    rendererPtr->SetColor(color);
+    return false;
+  }
+  else
+  {
+    renderer = GetControlRenderer(color);
+    return true;
+  }
+}
+
+Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Image& image )
+{
+  ImageRenderer* rendererPtr = new ImageRenderer();
+  if( !mFactoryCache )
+  {
+    mFactoryCache = new RendererFactoryCache();
+  }
+  rendererPtr->Initialize( *( mFactoryCache.Get() ) );
+  rendererPtr->SetImage( image );
+
+  return Toolkit::ControlRenderer(rendererPtr);
+}
+
+bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image )
+{
+  ImageRenderer* rendererPtr = dynamic_cast<ImageRenderer*>(&GetImplementation(renderer));
+  if( rendererPtr )
+  {
+    rendererPtr->SetImage(image);
+    return false;
+  }
+  else
+  {
+    renderer = GetControlRenderer(image);
+    return true;
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h
new file mode 100644 (file)
index 0000000..93cbc3c
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__
+#define __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__
+
+/*
+ * 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.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.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>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class RendererFactoryCache;
+typedef IntrusivePtr<RendererFactoryCache> RendererFactoryCachePtr;
+
+/**
+ * @copydoc Toolkit::RendererFactory
+ */
+class RendererFactory : public BaseObject
+{
+
+public:
+
+  /**
+   * @brief Constructor
+   */
+  RendererFactory();
+
+  /**
+   * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Property::Map& )
+   */
+  Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap  );
+
+  /**
+   * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Vector4& )
+   */
+  Toolkit::ControlRenderer GetControlRenderer( const Vector4& color );
+
+  /**
+   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Vector4& )
+   */
+  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color );
+
+  /**
+   * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Image& )
+   */
+  Toolkit::ControlRenderer GetControlRenderer( const Image& image );
+
+  /**
+   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Image& )
+   */
+  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image );
+
+protected:
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~RendererFactory();
+
+private:
+
+  /**
+   * Undefined copy constructor.
+   */
+  RendererFactory(const RendererFactory&);
+
+  /**
+   * Undefined assignment operator.
+   */
+  RendererFactory& operator=(const RendererFactory& rhs);
+
+private:
+
+  RendererFactoryCachePtr mFactoryCache;
+};
+
+} // namespace Internal
+
+inline const Internal::RendererFactory& GetImplementation(const Toolkit::RendererFactory& factory)
+{
+  DALI_ASSERT_ALWAYS( factory && "RendererFactory handle is empty" );
+
+  const BaseObject& handle = factory.GetBaseObject();
+
+  return static_cast<const Internal::RendererFactory&>(handle);
+}
+
+inline Internal::RendererFactory& GetImplementation(Toolkit::RendererFactory& factory)
+{
+  DALI_ASSERT_ALWAYS( factory && "RendererFactory handle is empty" );
+
+  BaseObject& handle = factory.GetBaseObject();
+
+  return static_cast<Internal::RendererFactory&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_RENDERER_FACTORY_IMPL_H__ */
index 0b0517c..6351be0 100644 (file)
@@ -12,6 +12,15 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/json-parser-impl.cpp \
    $(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/renderer-factory-cache.cpp \
+   $(toolkit_src_dir)/controls/renderers/renderer-factory-impl.cpp \
+   $(toolkit_src_dir)/controls/renderers/color/color-renderer.cpp \
+   $(toolkit_src_dir)/controls/renderers/image/image-renderer.cpp \
+   $(toolkit_src_dir)/controls/renderers/gradient/gradient.cpp \
+   $(toolkit_src_dir)/controls/renderers/gradient/linear-gradient.cpp \
+   $(toolkit_src_dir)/controls/renderers/gradient/radial-gradient.cpp \
+   $(toolkit_src_dir)/controls/renderers/gradient/gradient-renderer.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
    $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
    $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
index 2936d4d..8ada007 100644 (file)
@@ -290,6 +290,14 @@ struct Controller::Impl
     return ( mEventData && mEventData->mIsShowingPlaceholderText );
   }
 
+  /**
+   * @brief Helper to check whether active place-holder text is available.
+   */
+  bool IsFocusedPlaceholderAvailable() const
+  {
+    return ( mEventData && !mEventData->mPlaceholderTextActive.empty() );
+  }
+
   bool IsShowingRealText() const
   {
     return ( !IsShowingPlaceholderText() &&
index ef10a3f..f9979df 100644 (file)
@@ -1256,7 +1256,7 @@ void Controller::KeyboardFocusLostEvent()
     {
       mImpl->ChangeState( EventData::INACTIVE );
 
-      if( mImpl->IsShowingPlaceholderText() )
+      if( !mImpl->IsShowingRealText() )
       {
         // Revert to regular placeholder-text when not editing
         ShowPlaceholderText();
@@ -1523,6 +1523,11 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y )
       else if( EventData::EDITING                  != mImpl->mEventData->mState &&
                EventData::EDITING_WITH_GRAB_HANDLE != mImpl->mEventData->mState )
       {
+        if( mImpl->IsShowingPlaceholderText() &&  ! mImpl->IsFocusedPlaceholderAvailable() )
+        {
+          // Hide placeholder text
+          ResetText();
+        }
         // Show cursor on first tap
         mImpl->ChangeState( EventData::EDITING );
         relayoutNeeded = true;
@@ -1606,6 +1611,9 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y  )
       }
       else
       {
+        // Reset the imf manger to commit the pre-edit before selecting the text.
+        mImpl->ResetImfManager();
+
         SelectEvent( x, y, false );
       }
     }
index b4b9cdb..af2f4ca 100644 (file)
@@ -22,7 +22,6 @@
 #include <cstring> // for strcmp
 #include <limits>
 #include <stack>
-#include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/devel-api/styling/style-manager.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
+#include <dali-toolkit/internal/controls/renderers/color/color-renderer.h>
+#include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
 
 namespace Dali
 {
@@ -162,127 +164,96 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do
 
 DALI_TYPE_REGISTRATION_END()
 
+
+const char * const BACKGROUND_COLOR_NAME("color");
+
 /**
  * Structure which holds information about the background of a control
  */
 struct Background
 {
-  Actor actor;   ///< Background actor
-  Vector4 color; ///< The color of the actor.
+  //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(),
-    color( Color::WHITE )
+    controlRenderer(),
+    image(),
+    color( Color::TRANSPARENT )
   {
   }
 };
 
-unsigned int gQuadIndex[6] = { 0, 2, 1, 1, 2, 3 };
+//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 );
 
-Vector2 gQuad[] = {
-                   Vector2( -0.5f, -0.5f ),
-                   Vector2(  0.5f, -0.5f ),
-                   Vector2( -0.5f,  0.5f ),
-                   Vector2(  0.5f,  0.5f )
-};
+  //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();
 
-const char* VERTEX_SHADER_COLOR = DALI_COMPOSE_SHADER(
-    attribute mediump vec2 aPosition;\n
-    uniform mediump mat4 uMvpMatrix;\n
-    void main()\n
-    {\n
-      gl_Position = uMvpMatrix * vec4( aPosition, 0.0, 1.0 );\n
-    }\n
-);
+  background.image.Reset();
+  background.color = color;
 
-const char* FRAGMENT_SHADER_COLOR = DALI_COMPOSE_SHADER(
-    uniform lowp vec4 uBackgroundColor;\n
-    uniform lowp vec4 uColor;\n
-    void main()\n
-    {\n
-      gl_FragColor = uBackgroundColor * uColor;\n
-    }\n
-);
+ // 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] color The background color
- * @param[in] image If a valid image is supplied this will be the texture used by the background
- *
- * @return An actor which will render the background
- *
+ * @param[in] image The background image
  */
-Actor CreateBackground( Actor parent, const Vector4& color, Image image = Image() )
+void CreateBackground( Background& background, const Image& image )
 {
-  if( !image )
-  {
-    PropertyBuffer vertexBuffer;
-    Shader shader;
-    Material material;
-
-    Property::Map vertexFormat;
-    vertexFormat["aPosition"] = Property::VECTOR2;
-
-    //Create a vertex buffer for vertex positions
-    vertexBuffer = PropertyBuffer::New( vertexFormat, 4u );
-    vertexBuffer.SetData( gQuad );
-
-    shader = Shader::New( VERTEX_SHADER_COLOR, FRAGMENT_SHADER_COLOR );
-    material = Material::New( shader );
-
-    //Create the index buffer
-    Property::Map indexFormat;
-    indexFormat["indices"] = Property::INTEGER;
-    PropertyBuffer indexBuffer = PropertyBuffer::New( indexFormat, 6u );
-    indexBuffer.SetData(gQuadIndex);
-
-    //Create the geometry
-    Geometry mesh = Geometry::New();
-    mesh.AddVertexBuffer( vertexBuffer );
-    mesh.SetIndexBuffer( indexBuffer );
-
-    //Add uniforms to the shader
-    shader.RegisterProperty( "uBackgroundColor", color );
-
-    //Create the renderer
-    Renderer renderer = Renderer::New( mesh, material );
-    renderer.SetDepthIndex( parent.GetHierarchyDepth() + BACKGROUND_DEPTH_INDEX );
-
-    //Create the actor
-    Actor meshActor = Actor::New();
-    meshActor.SetSize( Vector3::ONE );
-    meshActor.AddRenderer( renderer );
-    meshActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
-    meshActor.SetColorMode( USE_PARENT_COLOR );
-
-    //Constraint scale of the mesh actor to the size of the control
-    Constraint constraint = Constraint::New<Vector3>( meshActor,
-                                                      Actor::Property::SCALE,
-                                                      EqualToConstraint() );
-    constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
-    constraint.Apply();
-
-    return meshActor;
-  }
-  else
-  {
-    ImageActor imageActor = ImageActor::New( image );
-    imageActor.SetColor( color );
-    imageActor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
-    imageActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
-    imageActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
-    imageActor.SetSortModifier( parent.GetHierarchyDepth() + BACKGROUND_DEPTH_INDEX );
-
-    return imageActor;
-  }
+  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
@@ -379,25 +350,28 @@ public:
           controlImpl.SetStyleName( value.Get< std::string >() );
           break;
         }
-
-        case Toolkit::Control::Property::BACKGROUND_COLOR:
-        {
-          controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
-          break;
-        }
-
-        case Toolkit::Control::Property::BACKGROUND_IMAGE:
+        case Toolkit::Control::Property::BACKGROUND:
         {
           Image image = Scripting::NewImage( value );
           if ( image )
           {
             controlImpl.SetBackgroundImage( image );
+            break;
           }
-          else
+          const Property::Map* map = value.GetMap();
+          if( map )
           {
-            // An empty map means the background is no longer required
-            controlImpl.ClearBackground();
+            const Property::Value* colorValue = map->Find( BACKGROUND_COLOR_NAME );
+            Vector4 color;
+            if( colorValue && colorValue->Get(color))
+            {
+              controlImpl.SetBackgroundColor( color );
+              break;
+            }
           }
+
+          // The background is neither an valid image nor a valid color, so it is no longer required
+          controlImpl.ClearBackground();
           break;
         }
 
@@ -441,35 +415,20 @@ public:
           break;
         }
 
-        case Toolkit::Control::Property::BACKGROUND_COLOR:
-        {
-          value = controlImpl.GetBackgroundColor();
-          break;
-        }
-
-        case Toolkit::Control::Property::BACKGROUND_IMAGE:
+        case Toolkit::Control::Property::BACKGROUND:
         {
           Property::Map map;
 
           Background* back = controlImpl.mImpl->mBackground;
-          if ( back && back->actor )
+          if ( back && back->actor)
           {
-            if( back->actor.GetRendererCount() > 0 && back->actor.GetRendererAt(0).GetMaterial().GetNumberOfSamplers() > 0 )
+            if( back->image )
             {
-              Image image = back->actor.GetRendererAt(0).GetMaterial().GetSamplerAt(0).GetImage();
-              if ( image )
-              {
-                Scripting::CreatePropertyMap( image, map );
-              }
+              Scripting::CreatePropertyMap( back->image, map );
             }
             else
             {
-              ImageActor imageActor = ImageActor::DownCast( back->actor );
-              if ( imageActor )
-              {
-                Image image = imageActor.GetImage();
-                Scripting::CreatePropertyMap( image, map );
-              }
+              map[BACKGROUND_COLOR_NAME] = back->color;
             }
           }
 
@@ -513,14 +472,12 @@ public:
   static PropertyRegistration PROPERTY_1;
   static PropertyRegistration PROPERTY_2;
   static PropertyRegistration PROPERTY_3;
-  static PropertyRegistration PROPERTY_4;
 };
 
 // Properties registered without macro to use specific member variables.
-PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name",       Toolkit::Control::Property::STYLE_NAME,       Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background-color", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "background-image", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "key-input-focus",  Toolkit::Control::Property::KEY_INPUT_FOCUS,  Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "style-name",      Toolkit::Control::Property::STYLE_NAME,      Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "background",      Toolkit::Control::Property::BACKGROUND,      Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "key-input-focus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 
 Toolkit::Control Control::New()
 {
@@ -566,30 +523,28 @@ void Control::SetBackgroundColor( const Vector4& color )
 {
   Background& background( mImpl->GetBackground() );
 
-  if ( background.actor )
+  // 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( background.actor.GetRendererCount() > 0 )
-    {
-      Shader shader = background.actor.GetRendererAt(0).GetMaterial().GetShader();
-      shader.SetProperty( shader.GetPropertyIndex("uBackgroundColor"), color );
-    }
-    else
-    {
-      background.actor.SetColor( color );
-    }
+    background.color = color;
   }
   else
   {
-    // Create Mesh Actor
-    Actor actor = CreateBackground(Self(), color );
-    background.actor = actor;
+    // 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( actor );
+    Self().Add( background.actor );
     mImpl->mAddRemoveBackgroundChild = false;
   }
-
-  background.color = color;
 }
 
 Vector4 Control::GetBackgroundColor() const
@@ -605,23 +560,28 @@ void Control::SetBackgroundImage( Image image )
 {
   Background& background( mImpl->GetBackground() );
 
-   if ( background.actor )
-   {
-     // Remove Current actor, unset AFTER removal
-     mImpl->mAddRemoveBackgroundChild = true;
-     Self().Remove( background.actor );
-     mImpl->mAddRemoveBackgroundChild = false;
-     background.actor.Reset();
-   }
-
-   Actor actor = CreateBackground(Self(), background.color, image);
-
-   // Set the background actor before adding so that we do not inform derived classes
-   background.actor = actor;
-   mImpl->mAddRemoveBackgroundChild = true;
-   // The actor does not need to be inserted to guarantee order.
-   Self().Add( actor );
-   mImpl->mAddRemoveBackgroundChild = false;
+  // 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 ) ) )
+  {
+    background.image = image;
+  }
+  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;
+  }
 }
 
 void Control::ClearBackground()
@@ -968,25 +928,9 @@ void Control::OnStageConnection( int depth )
     }
   }
 
-  if( mImpl->mBackground )
+  if( mImpl->mBackground && mImpl->mBackground->controlRenderer)
   {
-    if(mImpl->mBackground->actor.GetRendererCount() > 0 )
-    {
-      Renderer backgroundRenderer = mImpl->mBackground->actor.GetRendererAt( 0 );
-      if(backgroundRenderer)
-      {
-        backgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth );
-      }
-    }
-    else
-    {
-
-      ImageActor imageActor = ImageActor::DownCast( mImpl->mBackground->actor );
-      if ( imageActor )
-      {
-        imageActor.SetSortModifier( BACKGROUND_DEPTH_INDEX+depth );
-      }
-    }
+    mImpl->mBackground->controlRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX+depth );
   }
 }
 
index 35587f9..74f7fa8 100644 (file)
@@ -89,8 +89,7 @@ public:
     enum
     {
       STYLE_NAME = PROPERTY_START_INDEX,       ///< name "style-name",       @see SetStyleName,       type std::string
-      BACKGROUND_COLOR,                        ///< name "background-color", @see SetBackgroundColor, type Vector4
-      BACKGROUND_IMAGE,                        ///< name "background-image", @see SetBackgroundImage, type Map
+      BACKGROUND,                              ///< name "background",       @see SetBackgroundImage, type Map
       KEY_INPUT_FOCUS,                         ///< name "key-input-focus",  @see SetKeyInputFocus,   type bool
     };
   };
@@ -271,6 +270,8 @@ public:
   /**
    * @brief Retrieves the background color of the control.
    *
+   * @deprecated DALi 1.1.3 API removed.
+   *
    * @return The background color of the control.
    */
   Vector4 GetBackgroundColor() const;
index 56709e4..44b947a 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 2;
+const unsigned int TOOLKIT_MICRO_VERSION = 3;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 5ae4f93..5340ef9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.1.2
+Version:    1.1.3
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0, BSD-2.0, MIT