[dali_1.1.18] Merge branch 'devel/master' 80/57780/1
authorRichard Huang <r.huang@samsung.com>
Fri, 22 Jan 2016 13:29:33 +0000 (13:29 +0000)
committerRichard Huang <r.huang@samsung.com>
Fri, 22 Jan 2016 13:29:34 +0000 (13:29 +0000)
Change-Id: Idc8340a9cb1ad1c05594b3b1cbcdce5195061e2f

86 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp
automated-tests/src/dali-toolkit/utc-Dali-JsonParser.cpp
automated-tests/src/dali-toolkit/utc-Dali-ScrollView.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp [new file with mode: 0644]
build/tizen/configure.ac
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/controls/text-controls/text-editor.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/text-controls/text-editor.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/builder/builder-impl.cpp
dali-toolkit/internal/builder/json-parser-state.cpp
dali-toolkit/internal/builder/tree-node-manipulator.cpp
dali-toolkit/internal/builder/tree-node-manipulator.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.h
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
dali-toolkit/internal/controls/renderers/image/image-renderer.h
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h
dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/text-controls/text-editor-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/styling/style-manager-impl.cpp
dali-toolkit/internal/styling/style-manager-impl.h
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/controls/image-view/image-view.h
dali-toolkit/public-api/controls/scrollable/item-view/item-view.h
dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h
dali-toolkit/public-api/controls/scrollable/scrollable.h
dali-toolkit/public-api/controls/text-controls/text-field.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/480x800/dali-toolkit-default-theme.json
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
docs/content/images/item-view/list.png [new file with mode: 0755]
docs/content/main.md
docs/content/shared-javascript-and-cpp-documentation/copy-and-paste.md [new file with mode: 0644]
docs/content/shared-javascript-and-cpp-documentation/input-style.md [new file with mode: 0644]
docs/content/shared-javascript-and-cpp-documentation/text-editor.md [new file with mode: 0644]
docs/content/shared-javascript-and-cpp-documentation/text-field.md
node-addon/binding.gyp
node-addon/build/tizen/CMakeLists.txt
node-addon/examples/images/icon-0.png [new file with mode: 0755]
node-addon/examples/images/icon-1.png [new file with mode: 0755]
node-addon/examples/images/icon-2.png [new file with mode: 0755]
node-addon/examples/images/image-1.jpg [moved from node-addon/image-1.jpg with 100% similarity]
node-addon/examples/images/image-2.jpg [moved from node-addon/image-2.jpg with 100% similarity]
node-addon/examples/item-view.js [new file with mode: 0644]
node-addon/examples/line-mesh.js [moved from node-addon/line-mesh.js with 98% similarity]
node-addon/examples/mesh-morph.js [moved from node-addon/mesh-morph.js with 99% similarity]
node-addon/examples/point-mesh.js [moved from node-addon/point-mesh.js with 98% similarity]
node-addon/examples/scripts/item-template.json [new file with mode: 0644]
node-addon/examples/texture-mesh.js [moved from node-addon/texture-mesh.js with 98% similarity]
node-addon/item-template.json [new file with mode: 0644]
packaging/dali-addon.spec
packaging/dali-toolkit.spec
plugins/dali-script-v8/docs/content/constants.js
plugins/dali-script-v8/docs/content/item-factory.js [new file with mode: 0644]
plugins/dali-script-v8/docs/content/item-view.js [new file with mode: 0644]
plugins/dali-script-v8/file.list
plugins/dali-script-v8/src/actors/actor-api.cpp
plugins/dali-script-v8/src/actors/actor-api.h
plugins/dali-script-v8/src/actors/actor-wrapper.cpp
plugins/dali-script-v8/src/actors/actor-wrapper.h
plugins/dali-script-v8/src/constants/constants-wrapper.cpp
plugins/dali-script-v8/src/controls/control-wrapper.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/control-wrapper.h [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-factory-wrapper.h [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-view-api.cpp [new file with mode: 0644]
plugins/dali-script-v8/src/controls/item-view-api.h [new file with mode: 0644]
plugins/dali-script-v8/src/dali-wrapper.cpp
plugins/dali-script-v8/src/object/handle-wrapper.cpp
plugins/dali-script-v8/src/object/handle-wrapper.h
plugins/dali-script-v8/src/shared/base-wrapped-object.h
plugins/dali-script-v8/src/utils/v8-utils.cpp
plugins/dali-script-v8/src/utils/v8-utils.h

index 9ebbcf4..1ce796d 100644 (file)
@@ -40,7 +40,7 @@ LIST(APPEND TC_SOURCES
 
 PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali-core
-    dali
+    dali-adaptor
     dali-toolkit
 )
 
index 5951546..e0e2601 100644 (file)
@@ -27,6 +27,7 @@ SET(TC_SOURCES
    utc-Dali-ShadowView.cpp
    utc-Dali-Slider.cpp
    utc-Dali-TableView.cpp
+   utc-Dali-TextEditor.cpp
    utc-Dali-TextField.cpp
    utc-Dali-TextLabel.cpp
    utc-Dali-TextSelectionPopup.cpp
@@ -83,7 +84,7 @@ LIST(APPEND TC_SOURCES
 
 PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali-core
-    dali
+    dali-adaptor
     dali-toolkit
 )
 
index 2feeee2..cc62d54 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/devel-api/scripting/scripting.h>
+#include <dali/devel-api/rendering/material.h>
+#include <dali/devel-api/rendering/renderer.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -246,6 +248,90 @@ int UtcDaliImageViewSetGetProperty01(void)
   END_TEST;
 }
 
+int UtcDaliImageViewSetGetProperty02(void)
+{
+  ToolkitTestApplication application;
+
+  Image image = CreateBufferImage( 10, 10, Color::WHITE );
+  ImageView imageView = ImageView::New(image);
+  Vector4 fullImageRect( 0.f, 0.f, 1.f, 1.f );
+
+  Stage::GetCurrent().Add( imageView );
+
+  application.SendNotification();
+  application.Render();
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+
+  Vector4 pixelAreaUniform;
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "pixelArea", pixelAreaUniform ) );
+  DALI_TEST_EQUALS( pixelAreaUniform, fullImageRect, TEST_LOCATION );
+
+  Property::Value value = imageView.GetProperty( ImageView::Property::PIXEL_AREA );
+  Vector4 pixelAreaValue;
+  DALI_TEST_CHECK( value.Get(pixelAreaValue) );
+  DALI_TEST_EQUALS( pixelAreaValue, fullImageRect, TEST_LOCATION );
+
+  Vector4 pixelAreaSet( 0.2f, 0.2f, 0.3f, 0.3f );
+  imageView.SetProperty( ImageView::Property::PIXEL_AREA, pixelAreaSet);
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView.GetProperty( ImageView::Property::PIXEL_AREA );
+  value.Get(pixelAreaValue);
+  DALI_TEST_EQUALS( pixelAreaValue, pixelAreaSet, TEST_LOCATION );
+
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "pixelArea", pixelAreaUniform ) );
+  DALI_TEST_EQUALS( pixelAreaUniform, pixelAreaSet, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewSetGetProperty03(void)
+{
+  ToolkitTestApplication application;
+
+  Image image = CreateBufferImage( 10, 10, Color::WHITE );
+  ImageView imageView = ImageView::New(image);
+  Stage::GetCurrent().Add( imageView );
+  application.SendNotification();
+  application.Render();
+
+ // conventional alpha blending
+  Material material = imageView.GetRendererAt( 0 ).GetMaterial();
+  BlendingFactor::Type srcFactorRgb;
+  BlendingFactor::Type destFactorRgb;
+  BlendingFactor::Type srcFactorAlpha;
+  BlendingFactor::Type destFactorAlpha;
+  material.GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
+  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+
+  float alphaBlendingUniform;
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uAlphaBlending", alphaBlendingUniform ) );
+  DALI_TEST_EQUALS( alphaBlendingUniform, 1.f, TEST_LOCATION );
+
+  // pre-multiplied alpha blending
+  imageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
+  application.SendNotification();
+  application.Render();
+
+  material.GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
+  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::ONE );
+  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
+
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uAlphaBlending", alphaBlendingUniform ) );
+  DALI_TEST_EQUALS( alphaBlendingUniform, 0.f, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliImageViewSizeWithBackground(void)
 {
   ToolkitTestApplication application;
index 2c49895..2cbd51b 100644 (file)
@@ -837,3 +837,92 @@ int UtcDaliItemViewLayoutActivatedSignalP(void)
 
   END_TEST;
 }
+
+int UtcDaliItemViewSetGetProperty(void)
+{
+  ToolkitTestApplication application;
+
+  // Create the ItemView actor
+  TestItemFactory factory;
+  ItemView view = ItemView::New(factory);
+  DALI_TEST_CHECK(view);
+
+  // Event side properties
+
+  // Test "minimumSwipeSpeed" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("minimumSwipeSpeed") == ItemView::Property::MINIMUM_SWIPE_SPEED  );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_SPEED).Get<float>(), view.GetMinimumSwipeSpeed(), TEST_LOCATION );
+  view.SetProperty( ItemView::Property::MINIMUM_SWIPE_SPEED, 2.5f );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_SPEED).Get<float>(), 2.5f, TEST_LOCATION );
+
+  // Test "minimumSwipeDistance" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("minimumSwipeDistance") == ItemView::Property::MINIMUM_SWIPE_DISTANCE  );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_DISTANCE).Get<float>(), view.GetMinimumSwipeDistance(), TEST_LOCATION );
+  view.SetProperty( ItemView::Property::MINIMUM_SWIPE_DISTANCE, 8.725f );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_DISTANCE).Get<float>(), 8.725f, TEST_LOCATION );
+
+  // Test "wheelScrollDistanceStep" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("wheelScrollDistanceStep") == ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP  );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<float>(), view.GetWheelScrollDistanceStep(), TEST_LOCATION );
+  view.SetProperty( ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP, 5.0f );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<float>(), 5.0f, TEST_LOCATION );
+
+  // Test "snapToItemEnabled" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("snapToItemEnabled") == ItemView::Property::SNAP_TO_ITEM_ENABLED  );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SNAP_TO_ITEM_ENABLED).Get<bool>(), view.GetAnchoring(), TEST_LOCATION );
+  view.SetProperty( ItemView::Property::SNAP_TO_ITEM_ENABLED, true );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SNAP_TO_ITEM_ENABLED).Get<bool>(), true, TEST_LOCATION );
+
+  // Test "refreshInterval" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("refreshInterval") == ItemView::Property::REFRESH_INTERVAL  );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::REFRESH_INTERVAL).Get<float>(), view.GetRefreshInterval(), TEST_LOCATION );
+  view.SetProperty( ItemView::Property::REFRESH_INTERVAL, 11.0f );
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::REFRESH_INTERVAL).Get<float>(), 11.0f, TEST_LOCATION );
+
+  // Test "overshootEnabled" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("overshootEnabled") == Scrollable::Property::OVERSHOOT_ENABLED  );
+  DALI_TEST_EQUALS( view.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), view.IsOvershootEnabled(), TEST_LOCATION );
+  view.SetProperty( Scrollable::Property::OVERSHOOT_ENABLED, false );
+  DALI_TEST_EQUALS( view.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+  // Animatable properties
+
+  // Test "layoutPosition" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("layoutPosition") == ItemView::Property::LAYOUT_POSITION  );
+  view.SetProperty( ItemView::Property::LAYOUT_POSITION, 20.5f );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::LAYOUT_POSITION).Get<float>(), 20.5f, TEST_LOCATION );
+
+  // Test "scrollSpeed" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("scrollSpeed") == ItemView::Property::SCROLL_SPEED  );
+  view.SetProperty( ItemView::Property::SCROLL_SPEED, 3.35f );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_SPEED).Get<float>(), 3.35f, TEST_LOCATION );
+
+  // Test "overshoot" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("overshoot") == ItemView::Property::OVERSHOOT  );
+  view.SetProperty( ItemView::Property::OVERSHOOT, 0.15f );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::OVERSHOOT).Get<float>(), 0.15f, TEST_LOCATION );
+
+  // Test "scrollDirection" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("scrollDirection") == ItemView::Property::SCROLL_DIRECTION  );
+  view.SetProperty( ItemView::Property::SCROLL_DIRECTION, Vector2(0.85f, 0.5f) );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_DIRECTION).Get<Vector2>(), Vector2(0.85f, 0.5f), TEST_LOCATION );
+
+  // Test "layoutOrientation" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("layoutOrientation") == ItemView::Property::LAYOUT_ORIENTATION  );
+  view.SetProperty( ItemView::Property::LAYOUT_ORIENTATION, 2 );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::LAYOUT_ORIENTATION).Get<int>(), 2, TEST_LOCATION );
+
+  // Test "scrollContentSize" property
+  DALI_TEST_CHECK( view.GetPropertyIndex("scrollContentSize") == ItemView::Property::SCROLL_CONTENT_SIZE  );
+  view.SetProperty( ItemView::Property::SCROLL_CONTENT_SIZE, 250.0f );
+  Wait(application);
+  DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_CONTENT_SIZE).Get<float>(), 250.0f, TEST_LOCATION );
+
+  END_TEST;
+}
+
index 1f2c667..1fafb16 100644 (file)
@@ -722,3 +722,37 @@ int UtcDaliJsonParserMethod11(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+
+int UtcDaliJsonParserMerge1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("JSON tree merge");
+
+  std::string s1( ReplaceQuotes("                                       \
+{                                                                       \
+  'styles':                                                             \
+  {                                                                     \
+    'button':                                                           \
+    {                                                                   \
+      'backgroundColor':[0.8, 0.0, 1.0, 1.0],                           \
+      'foregroundColor':[1, 1, 1, 1]                                    \
+    }                                                                   \
+  }                                                                     \
+}                                                                       \
+"));
+
+  JsonParser parser = JsonParser::New();
+  JsonParser testParser = JsonParser::New();
+
+  testParser.Parse( s1 );
+
+  parser.Parse( s1 );
+  parser.Parse( s1 ); // Merge the tree into itself. The value array should not grow.
+
+  DALI_TEST_CHECK(parser.GetRoot());
+
+  CompareTrees( *parser.GetRoot(), *testParser.GetRoot() );
+
+  END_TEST;
+}
index 3f9879e..61fba59 100644 (file)
@@ -2347,3 +2347,166 @@ int UtcDaliToolkitScrollViewGesturePageLimit(void)
 
   END_TEST;
 }
+
+int UtcDaliScrollViewSetGetProperty(void)
+{
+  ToolkitTestApplication application;
+
+  // Create the ScrollView actor
+  ScrollView scrollView = ScrollView::New();
+  DALI_TEST_CHECK(scrollView);
+
+  // Event side properties
+
+  // Test "wrapEnabled" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("wrapEnabled") == ScrollView::Property::WRAP_ENABLED );
+  scrollView.SetProperty( ScrollView::Property::WRAP_ENABLED, true );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WRAP_ENABLED).Get<bool>(), true, TEST_LOCATION );
+
+  // Test "panningEnabled" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("panningEnabled") == ScrollView::Property::PANNING_ENABLED );
+  scrollView.SetProperty( ScrollView::Property::PANNING_ENABLED, false );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::PANNING_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+  // Test "axisAutoLockEnabled" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("axisAutoLockEnabled") == ScrollView::Property::AXIS_AUTO_LOCK_ENABLED );
+  scrollView.SetProperty( ScrollView::Property::AXIS_AUTO_LOCK_ENABLED, false );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::AXIS_AUTO_LOCK_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+  // Test "wheelScrollDistanceStep" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("wheelScrollDistanceStep") == ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP );
+  scrollView.SetProperty( ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP, Vector2(100.0f, 50.0f) );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<Vector2>(), Vector2(100.0f, 50.0f), TEST_LOCATION );
+
+  // Test "overshootEnabled" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootEnabled") == Scrollable::Property::OVERSHOOT_ENABLED  );
+  DALI_TEST_EQUALS( scrollView.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), scrollView.IsOvershootEnabled(), TEST_LOCATION );
+  scrollView.SetProperty( Scrollable::Property::OVERSHOOT_ENABLED, false );
+  DALI_TEST_EQUALS( scrollView.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+  // Animatable properties
+
+  // Test "scrollPosition" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPosition") == ScrollView::Property::SCROLL_POSITION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_POSITION, Vector2(320.0f, 550.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_POSITION).Get<Vector2>(), Vector2(320.0f, 550.0f), TEST_LOCATION );
+
+  // Test "scrollPrePosition", "scrollPrePositionX" and "scrollPrePositionY" properties
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePosition") == ScrollView::Property::SCROLL_PRE_POSITION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION, Vector2(300.0f, 500.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector2>(), Vector2(300.0f, 500.0f), TEST_LOCATION );
+
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionX") == ScrollView::Property::SCROLL_PRE_POSITION_X );
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionY") == ScrollView::Property::SCROLL_PRE_POSITION_Y );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_X).Get<float>(), 300.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_Y).Get<float>(), 500.0f, TEST_LOCATION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_X, 400.0f );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_Y, 600.0f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_X).Get<float>(), 400.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_Y).Get<float>(), 600.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector2>(), Vector2(400.0f, 600.0f), TEST_LOCATION );
+
+  // Test "scrollPrePositionMax", "scrollPrePositionMaxX" and "scrollPrePositionMaxY" properties
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMax") == ScrollView::Property::SCROLL_PRE_POSITION_MAX );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX, Vector2(100.0f, 200.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX).Get<Vector2>(), Vector2(100.0f, 200.0f), TEST_LOCATION );
+
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMaxX") == ScrollView::Property::SCROLL_PRE_POSITION_MAX_X );
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMaxY") == ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_X).Get<float>(), 100.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y).Get<float>(), 200.0f, TEST_LOCATION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX_X, 300.0f );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y, 400.0f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_X).Get<float>(), 300.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y).Get<float>(), 400.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX).Get<Vector2>(), Vector2(300.0f, 400.0f), TEST_LOCATION );
+
+  // Test "overshootX" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootX") == ScrollView::Property::OVERSHOOT_X );
+  scrollView.SetProperty( ScrollView::Property::OVERSHOOT_X, 0.8f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::OVERSHOOT_X).Get<float>(), 0.8f, TEST_LOCATION );
+
+  // Test "overshootY" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootY") == ScrollView::Property::OVERSHOOT_Y );
+  scrollView.SetProperty( ScrollView::Property::OVERSHOOT_Y, 0.8f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::OVERSHOOT_Y).Get<float>(), 0.8f, TEST_LOCATION );
+
+  // Test "scrollFinal", "scrollFinalX" and "scrollFinalY" properties
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinal") == ScrollView::Property::SCROLL_FINAL );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL, Vector2(200.0f, 300.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL).Get<Vector2>(), Vector2(200.0f, 300.0f), TEST_LOCATION );
+
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinalX") == ScrollView::Property::SCROLL_FINAL_X );
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinalY") == ScrollView::Property::SCROLL_FINAL_Y );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_X).Get<float>(), 200.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_Y).Get<float>(), 300.0f, TEST_LOCATION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL_X, 500.0f );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL_Y, 600.0f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_X).Get<float>(), 500.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_Y).Get<float>(), 600.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL).Get<Vector2>(), Vector2(500.0f, 600.0f), TEST_LOCATION );
+
+  // Test "wrap" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("wrap") == ScrollView::Property::WRAP );
+  scrollView.SetProperty( ScrollView::Property::WRAP, false );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WRAP).Get<bool>(), false, TEST_LOCATION );
+
+  // Test "panning" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("panning") == ScrollView::Property::PANNING );
+  scrollView.SetProperty( ScrollView::Property::PANNING, true );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::PANNING).Get<bool>(), true, TEST_LOCATION );
+
+  // Test "scrolling" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrolling") == ScrollView::Property::SCROLLING );
+  scrollView.SetProperty( ScrollView::Property::SCROLLING, false );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLLING).Get<bool>(), false, TEST_LOCATION );
+
+  // Test "scrollDomainSize", "scrollDomainSizeX" and "scrollDomainSizeY" properties
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSize") == ScrollView::Property::SCROLL_DOMAIN_SIZE );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE, Vector2(1200.0f, 1300.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE).Get<Vector2>(), Vector2(1200.0f, 1300.0f), TEST_LOCATION );
+
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSizeX") == ScrollView::Property::SCROLL_DOMAIN_SIZE_X );
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSizeY") == ScrollView::Property::SCROLL_DOMAIN_SIZE_Y );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_X).Get<float>(), 1200.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_Y).Get<float>(), 1300.0f, TEST_LOCATION );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE_X, 1500.0f );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE_Y, 1600.0f );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_X).Get<float>(), 1500.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_Y).Get<float>(), 1600.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE).Get<Vector2>(), Vector2(1500.0f, 1600.0f), TEST_LOCATION );
+
+  // Test "scrollDomainOffset" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainOffset") == ScrollView::Property::SCROLL_DOMAIN_OFFSET );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_OFFSET, Vector2(500.0f, 200.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_OFFSET).Get<Vector2>(), Vector2(500.0f, 200.0f), TEST_LOCATION );
+
+  // Test "scrollPositionDelta" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPositionDelta") == ScrollView::Property::SCROLL_POSITION_DELTA );
+  scrollView.SetProperty( ScrollView::Property::SCROLL_POSITION_DELTA, Vector2(10.0f, 30.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_POSITION_DELTA).Get<Vector2>(), Vector2(10.0f, 30.0f), TEST_LOCATION );
+
+  // Test "startPagePosition" property
+  DALI_TEST_CHECK( scrollView.GetPropertyIndex("startPagePosition") == ScrollView::Property::START_PAGE_POSITION );
+  scrollView.SetProperty( ScrollView::Property::START_PAGE_POSITION, Vector3(50.0f, 100.0f, 20.0f) );
+  Wait(application);
+  DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::START_PAGE_POSITION).Get<Vector3>(), Vector3(50.0f, 100.0f, 20.0f), TEST_LOCATION );
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
new file mode 100644 (file)
index 0000000..fc49de9
--- /dev/null
@@ -0,0 +1,710 @@
+/*
+ * Copyright (c) 2016 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/devel-api/rendering/renderer.h>
+#include <dali/integration-api/events/key-event-integ.h>
+#include <dali/integration-api/events/tap-gesture-event.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-editor.h> ///< @todo to be removed when text-editor is added to the dali-toolkit.h
+#include <dali-toolkit/devel-api/styling/style-manager.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void dali_texteditor_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void dali_texteditor_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+const char* const PROPERTY_NAME_RENDERING_BACKEND                    = "renderingBackend";
+const char* const PROPERTY_NAME_TEXT                                 = "text";
+const char* const PROPERTY_NAME_TEXT_COLOR                           = "textColor";
+const char* const PROPERTY_NAME_FONT_FAMILY                          = "fontFamily";
+const char* const PROPERTY_NAME_FONT_STYLE                           = "fontStyle";
+const char* const PROPERTY_NAME_POINT_SIZE                           = "pointSize";
+const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT                 = "horizontalAlignment";
+const char* const PROPERTY_NAME_SCROLL_THRESHOLD                     = "scrollThreshold";
+const char* const PROPERTY_NAME_SCROLL_SPEED                         = "scrollSpeed";
+const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR                 = "primaryCursorColor";
+const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR               = "secondaryCursorColor";
+const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK                  = "enableCursorBlink";
+const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL                = "cursorBlinkInterval";
+const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION                = "cursorBlinkDuration";
+const char* const PROPERTY_NAME_CURSOR_WIDTH                         = "cursorWidth";
+const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE                    = "grabHandleImage";
+const char* const PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE            = "grabHandlePressedImage";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT          = "selectionHandleImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT         = "selectionHandleImageRight";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT  = "selectionHandlePressedImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT = "selectionHandlePressedImageRight";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_LEFT   = "selectionHandleMarkerImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_RIGHT  = "selectionHandleMarkerImageRight";
+const char* const PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR            = "selectionHighlightColor";
+const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX              = "decorationBoundingBox";
+const char* const PROPERTY_NAME_ENABLE_MARKUP                        = "enableMarkup";
+const char* const PROPERTY_NAME_INPUT_COLOR                          = "inputColor";
+const char* const PROPERTY_NAME_INPUT_FONT_FAMILY                    = "inputFontFamily";
+const char* const PROPERTY_NAME_INPUT_FONT_STYLE                     = "inputFontStyle";
+const char* const PROPERTY_NAME_INPUT_POINT_SIZE                     = "inputPointSize";
+
+const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+
+const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color.
+
+const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
+const float TO_MILLISECONDS = 1000.f;
+const float TO_SECONDS = 1.f / TO_MILLISECONDS;
+
+const float SCROLL_THRESHOLD = 10.f;
+const float SCROLL_SPEED = 300.f;
+
+static bool gTextChangedCallBackCalled;
+
+static void TestTextChangedCallback( TextEditor control )
+{
+  tet_infoline(" TestTextChangedCallback");
+
+  gTextChangedCallBackCalled = true;
+}
+
+// Generate a TapGestureEvent to send to Core.
+Integration::TapGestureEvent GenerateTap(
+    Gesture::State state,
+    unsigned int numberOfTaps,
+    unsigned int numberOfTouches,
+    Vector2 point)
+{
+  Integration::TapGestureEvent tap( state );
+
+  tap.numberOfTaps = numberOfTaps;
+  tap.numberOfTouches = numberOfTouches;
+  tap.point = point;
+
+  return tap;
+}
+
+// Generate a KeyEvent to send to Core.
+Integration::KeyEvent GenerateKey( const std::string& keyName,
+                                   const std::string& keyString,
+                                   int keyCode,
+                                   int keyModifier,
+                                   unsigned long timeStamp,
+                                   const Integration::KeyEvent::State& keyState )
+{
+  return Integration::KeyEvent( keyName,
+                                keyString,
+                                keyCode,
+                                keyModifier,
+                                timeStamp,
+                                keyState );
+}
+
+} // namespace
+
+int UtcDaliToolkitTextEditorConstructorP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorConstructorP");
+  TextEditor textEditor;
+  DALI_TEST_CHECK( !textEditor );
+  END_TEST;
+}
+
+int UtcDaliToolkitTextEditorNewP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorNewP");
+  TextEditor textEditor = TextEditor::New();
+  DALI_TEST_CHECK( textEditor );
+  END_TEST;
+}
+
+int UtcDaliToolkitTextEditorDownCastP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorDownCastP");
+  TextEditor textEditor1 = TextEditor::New();
+  BaseHandle object( textEditor1 );
+
+  TextEditor textEditor2 = TextEditor::DownCast( object );
+  DALI_TEST_CHECK( textEditor2 );
+
+  TextEditor textEditor3 = DownCast< TextEditor >( object );
+  DALI_TEST_CHECK( textEditor3 );
+  END_TEST;
+}
+
+int UtcDaliToolkitTextEditorDownCastN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorDownCastN");
+  BaseHandle uninitializedObject;
+  TextEditor textEditor1 = TextEditor::DownCast( uninitializedObject );
+  DALI_TEST_CHECK( !textEditor1 );
+
+  TextEditor textEditor2 = DownCast< TextEditor >( uninitializedObject );
+  DALI_TEST_CHECK( !textEditor2 );
+  END_TEST;
+}
+
+int UtcDaliToolkitTextEditorCopyConstructorP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorCopyConstructorP");
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+
+  TextEditor copy( textEditor );
+  DALI_TEST_CHECK( copy );
+  DALI_TEST_CHECK( copy.GetProperty<std::string>( TextLabel::Property::TEXT ) == textEditor.GetProperty<std::string>( TextLabel::Property::TEXT ) );
+  END_TEST;
+}
+
+int UtcDaliToolkitTextEditorAssignmentOperatorP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorAssignmentOperatorP");
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+
+  TextEditor copy = textEditor;
+  DALI_TEST_CHECK( copy );
+  DALI_TEST_CHECK( copy.GetProperty<std::string>( TextEditor::Property::TEXT ) == textEditor.GetProperty<std::string>( TextEditor::Property::TEXT ) );
+  END_TEST;
+}
+
+int UtcDaliTextEditorNewP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorNewP");
+  TextEditor textEditor = TextEditor::New();
+  DALI_TEST_CHECK( textEditor );
+  END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliTextEditorGetPropertyP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorGetPropertyP");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  // Check Property Indices are correct
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_RENDERING_BACKEND ) == TextEditor::Property::RENDERING_BACKEND );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_TEXT ) == TextEditor::Property::TEXT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_TEXT_COLOR ) == TextEditor::Property::TEXT_COLOR );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_FONT_FAMILY ) == TextEditor::Property::FONT_FAMILY );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_FONT_STYLE ) == TextEditor::Property::FONT_STYLE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_POINT_SIZE ) == TextEditor::Property::POINT_SIZE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextEditor::Property::HORIZONTAL_ALIGNMENT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_THRESHOLD ) == TextEditor::Property::SCROLL_THRESHOLD );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_SPEED ) == TextEditor::Property::SCROLL_SPEED );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PRIMARY_CURSOR_COLOR ) == TextEditor::Property::PRIMARY_CURSOR_COLOR );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SECONDARY_CURSOR_COLOR ) == TextEditor::Property::SECONDARY_CURSOR_COLOR );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_CURSOR_BLINK ) == TextEditor::Property::ENABLE_CURSOR_BLINK );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_INTERVAL ) == TextEditor::Property::CURSOR_BLINK_INTERVAL );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_DURATION ) == TextEditor::Property::CURSOR_BLINK_DURATION );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_WIDTH ) == TextEditor::Property::CURSOR_WIDTH );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_IMAGE ) == TextEditor::Property::GRAB_HANDLE_IMAGE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE ) == TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR ) == TextEditor::Property::SELECTION_HIGHLIGHT_COLOR );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_DECORATION_BOUNDING_BOX ) == TextEditor::Property::DECORATION_BOUNDING_BOX );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP ) == TextEditor::Property::ENABLE_MARKUP );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_COLOR ) == TextEditor::Property::INPUT_COLOR );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_FAMILY ) == TextEditor::Property::INPUT_FONT_FAMILY );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_STYLE ) == TextEditor::Property::INPUT_FONT_STYLE );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_POINT_SIZE ) == TextEditor::Property::INPUT_POINT_SIZE );
+  END_TEST;
+}
+
+bool SetPropertyMapRetrieved( TextEditor& editor, const Property::Index property, const std::string mapKey, const std::string mapValue )
+{
+  bool result = false;
+  Property::Map imageMap;
+  imageMap[mapKey] =mapValue;
+
+  editor.SetProperty( property , imageMap );
+  Property::Value propValue = editor.GetProperty( property );
+  Property::Map* resultMap = propValue.GetMap();
+
+  if ( resultMap->Find( mapKey )->Get< std::string>() == mapValue )
+  {
+    result = true;
+  }
+
+  return result;
+}
+
+// Positive test case for a method
+int UtcDaliTextEditorSetPropertyP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorSetPropertyP");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+  Stage::GetCurrent().Add( editor );
+
+  // Note - we can't check the defaults since the stylesheets are platform-specific
+
+  // Check the render backend property.
+  editor.SetProperty( TextEditor::Property::RENDERING_BACKEND, Text::RENDERING_SHARED_ATLAS );
+  DALI_TEST_EQUALS( (Text::RenderingType)editor.GetProperty<int>( TextEditor::Property::RENDERING_BACKEND ), Text::RENDERING_SHARED_ATLAS, TEST_LOCATION );
+
+  // Check text property.
+  editor.SetProperty( TextEditor::Property::TEXT, "Setting Text" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("Setting Text"), TEST_LOCATION );
+
+  // Check text's color property
+  editor.SetProperty( TextEditor::Property::TEXT_COLOR, Color::WHITE );
+  DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::TEXT_COLOR ), Color::WHITE, TEST_LOCATION );
+
+  // Check font properties.
+  editor.SetProperty( TextEditor::Property::FONT_FAMILY, "Setting font family" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::FONT_FAMILY ), std::string("Setting font family"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::FONT_STYLE, "Setting font style" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::FONT_STYLE ), std::string("Setting font style"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Check that the Alignment properties can be correctly set
+  editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "END" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::HORIZONTAL_ALIGNMENT ), "END", TEST_LOCATION );
+
+  // Check scroll properties.
+  editor.SetProperty( TextEditor::Property::SCROLL_THRESHOLD, 1.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::SCROLL_THRESHOLD ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::SCROLL_SPEED, 100.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::SCROLL_SPEED ), 100.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Check cursor properties
+  editor.SetProperty( TextEditor::Property::PRIMARY_CURSOR_COLOR, Color::RED );
+  DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
+  DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
+
+  editor.SetProperty( TextEditor::Property::ENABLE_CURSOR_BLINK, false );
+  DALI_TEST_EQUALS( editor.GetProperty<bool>( TextEditor::Property::ENABLE_CURSOR_BLINK ), false, TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::CURSOR_BLINK_INTERVAL, 1.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::CURSOR_BLINK_INTERVAL ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::CURSOR_BLINK_DURATION, 10.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::CURSOR_BLINK_DURATION ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::CURSOR_WIDTH, 1 );
+  DALI_TEST_EQUALS( editor.GetProperty<int>( TextEditor::Property::CURSOR_WIDTH ), 1, TEST_LOCATION );
+
+  // Check handle images
+  editor.SetProperty( TextEditor::Property::GRAB_HANDLE_IMAGE, "image1" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::GRAB_HANDLE_IMAGE ), "image1", TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE, "image2" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE ), "image2", TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT, "image3" );
+
+  // Check handle images
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT, "filename", "leftHandleImage" )  );
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT, "filename", "rightHandleImage" )  );
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT, "filename", "leftHandleImagePressed" )  );
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, "filename", "rightHandleImagePressed" )  );
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT, "filename", "leftHandleMarkerImage" )  );
+  DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT, "filename", "rightHandleMarkerImage" )  );
+
+  // Check the highlight color
+  editor.SetProperty( TextEditor::Property::SELECTION_HIGHLIGHT_COLOR, Color::GREEN );
+  DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::SELECTION_HIGHLIGHT_COLOR ), Color::GREEN, TEST_LOCATION );
+
+  // Decoration bounding box
+  editor.SetProperty( TextEditor::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
+  DALI_TEST_EQUALS( editor.GetProperty<Rect <int > >( TextEditor::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
+
+  // Check the enable markup property.
+  DALI_TEST_CHECK( !editor.GetProperty<bool>( TextEditor::Property::ENABLE_MARKUP ) );
+  editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true );
+  DALI_TEST_CHECK( editor.GetProperty<bool>( TextEditor::Property::ENABLE_MARKUP ) );
+
+  // Check input color property.
+  editor.SetProperty( TextEditor::Property::INPUT_COLOR, Color::YELLOW );
+  DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::INPUT_COLOR ), Color::YELLOW, TEST_LOCATION );
+
+  // Check input font properties.
+  editor.SetProperty( TextEditor::Property::INPUT_FONT_FAMILY, "Setting input font family" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, "Setting input font style" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_FONT_STYLE ), "Setting input font style", TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::INPUT_POINT_SIZE, 12.f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  END_TEST;
+}
+
+// Positive Atlas Text Renderer test
+int utcDaliTextEditorAtlasRenderP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorAtlasRenderP");
+  StyleManager styleManager = StyleManager::Get();
+  styleManager.RequestDefaultTheme();
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  Stage::GetCurrent().Add( editor );
+
+  try
+  {
+    // Render some text with the shared atlas backend
+    editor.SetProperty( TextEditor::Property::RENDERING_BACKEND, Text::RENDERING_SHARED_ATLAS );
+    application.SendNotification();
+    application.Render();
+  }
+  catch( ... )
+  {
+    tet_result(TET_FAIL);
+  }
+  END_TEST;
+}
+
+// Positive test for the textChanged signal.
+int utcDaliTextEditorTextChangedP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorTextChangedP");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.TextChangedSignal().Connect(&TestTextChangedCallback);
+
+  gTextChangedCallBackCalled = false;
+  editor.SetProperty( TextEditor::Property::TEXT, "ABC" );
+  DALI_TEST_CHECK( gTextChangedCallBackCalled );
+
+  application.SendNotification();
+
+  editor.SetKeyInputFocus();
+
+  gTextChangedCallBackCalled = false;
+  application.ProcessEvent( GenerateKey( "D", "D", 0, 0, 0, Integration::KeyEvent::Down ) );
+  DALI_TEST_CHECK( gTextChangedCallBackCalled );
+
+  END_TEST;
+}
+
+int utcDaliTextEditorEvent01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorEvent01");
+
+  // Creates a tap event. After creating a tap event the text editor should
+  // have the focus and add text with key events should be possible.
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.SetSize( 300.f, 50.f );
+  editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Add a key event but as the text editor has not the focus it should do nothing.
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string(""), TEST_LOCATION );
+
+  // Create a tap event to touch the text editor.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Now the text editor has the focus, so it can handle the key events.
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+  // Create a second text editor and send key events to it.
+  TextEditor editor2 = TextEditor::New();
+
+  editor2.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor2.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  editor2.SetSize( 100.f, 100.f );
+  editor2.SetPosition( 100.f, 100.f );
+
+  Stage::GetCurrent().Add( editor2 );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Create a tap event on the second text editor.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // The second text editor has the focus. It should handle the key events.
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Check the text has been added to the second text editor.
+  DALI_TEST_EQUALS( editor2.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int utcDaliTextEditorEvent02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorEvent02");
+
+  // Checks if the right number of actors are created.
+
+  TextEditor editor = TextEditor::New();
+  editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.SetSize( 300.f, 50.f );
+  editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image actor
+  DALI_TEST_EQUALS( editor.GetChildCount(), 3u, TEST_LOCATION );
+
+  Actor layer = editor.GetChildAt( 0u );
+  DALI_TEST_CHECK( layer.IsLayer() );
+
+  Actor offscreenRoot = editor.GetChildAt( 1u );
+  DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+  DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+  Actor offscreenImage = editor.GetChildAt( 2u );
+  ImageActor imageActor = ImageActor::DownCast( offscreenImage );
+  DALI_TEST_CHECK( imageActor );
+
+  // Create a tap event to touch the text editor.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+  DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+  // Now the text editor has the focus, so it can handle the key events.
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Checks the cursor and the renderer have been created.
+  DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+  DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 2u, TEST_LOCATION ); // The camera actor and the renderer
+
+  Control cursor = Control::DownCast( layer.GetChildAt( 0u ) );
+  DALI_TEST_CHECK( cursor );
+
+  CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+  DALI_TEST_CHECK( camera );
+
+  Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  // Move the cursor and check the position changes.
+  Vector3 position1 = cursor.GetCurrentPosition();
+
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector3 position2 = cursor.GetCurrentPosition();
+
+  DALI_TEST_CHECK( position2.x < position1.x );
+
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector3 position3 = cursor.GetCurrentPosition();
+
+  DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1.
+
+  // Send some taps and check the cursor positions.
+
+  // Try to tap at the beginning.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Cursor position should be the same than position1.
+  Vector3 position4 = cursor.GetCurrentPosition();
+
+  DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2.
+
+  // Tap away from the start position.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 16.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 16.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Vector3 position5 = cursor.GetCurrentPosition();
+
+  DALI_TEST_CHECK( position5.x > position4.x );
+
+  // Remove all the text.
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+  editor.SetProperty( TextEditor::Property::TEXT, "" );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Cursor position should be the same than position2.
+  Vector3 position6 = cursor.GetCurrentPosition();
+
+  DALI_TEST_EQUALS( position2, position6, TEST_LOCATION );// Should be in the same position2.
+
+  // Should not be a renderer.
+  DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor only.
+
+  END_TEST;
+}
+
+int utcDaliTextEditorEvent03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorEvent03");
+
+  // Checks if the highlight actor is created.
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.SetProperty( TextEditor::Property::TEXT, "This is a long text for the size of the text-editor." );
+  editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+  editor.SetSize( 30.f, 50.f );
+  editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Tap first to get the focus.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Double tap to select a word.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor.
+  Actor offscreenRoot = editor.GetChildAt( 1u );
+  DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+
+  CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+  DALI_TEST_CHECK( camera );
+
+  Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  Renderer highlight = offscreenRoot.GetChildAt( 2u ).GetRendererAt( 0u );
+  DALI_TEST_CHECK( highlight );
+
+  END_TEST;
+}
index 77c33f0..1fa0845 100644 (file)
@@ -29,7 +29,6 @@ DALI_TOOLKIT_VERSION=dali_version
 AC_SUBST(DALI_TOOLKIT_VERSION)
 
 PKG_CHECK_MODULES(DALICORE, dali-core)
-PKG_CHECK_MODULES(DALI, dali)
 
 DALI_TOOLKIT_CFLAGS=-DPLATFORM_TIZEN
 
index 833348a..0e36158 100644 (file)
@@ -68,14 +68,12 @@ libdali_toolkit_la_CXXFLAGS = -DDALI_COMPILATION \
                       -I../../../ \
                       $(DALI_TOOLKIT_CFLAGS) \
                       $(DALICORE_CFLAGS) \
-                      $(DALI_CFLAGS) \
                       $(DLOG_CFLAGS) \
                       $(FRIBIDI_CFLAGS) \
                       $(HTMLCXX_CFLAGS)
 
 libdali_toolkit_la_LIBADD = \
                       $(DALICORE_LIBS) \
-                      $(DALI_LIBS) \
                       $(DLOG_LIBS) \
                       $(FRIBIDI_LIBS) \
                       $(HTMLCXX_LIBS)
diff --git a/dali-toolkit/devel-api/controls/text-controls/text-editor.cpp b/dali-toolkit/devel-api/controls/text-controls/text-editor.cpp
new file mode 100644 (file)
index 0000000..70dc1f4
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 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 <dali-toolkit/devel-api/controls/text-controls/text-editor.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+TextEditor TextEditor::New()
+{
+  return Internal::TextEditor::New();
+}
+
+TextEditor::TextEditor()
+{
+}
+
+TextEditor::TextEditor( const TextEditor& handle )
+: Control( handle )
+{
+}
+
+TextEditor& TextEditor::operator=( const TextEditor& handle )
+{
+  if( &handle != this )
+  {
+    Control::operator=( handle );
+  }
+  return *this;
+}
+
+TextEditor::~TextEditor()
+{
+}
+
+TextEditor TextEditor::DownCast( BaseHandle handle )
+{
+  return Control::DownCast<TextEditor, Internal::TextEditor>( handle );
+}
+
+TextEditor::TextChangedSignalType& TextEditor::TextChangedSignal()
+{
+  return Dali::Toolkit::GetImpl( *this ).TextChangedSignal();
+}
+
+TextEditor::TextEditor( Internal::TextEditor& implementation )
+: Control( implementation )
+{
+}
+
+TextEditor::TextEditor( Dali::Internal::CustomActor* internal )
+: Control( internal )
+{
+  VerifyCustomActorPointer<Internal::TextEditor>( internal );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/text-controls/text-editor.h b/dali-toolkit/devel-api/controls/text-controls/text-editor.h
new file mode 100644 (file)
index 0000000..0e1f9bb
--- /dev/null
@@ -0,0 +1,187 @@
+#ifndef __DALI_TOOLKIT_TEXT_EDITOR_H__
+#define __DALI_TOOLKIT_TEXT_EDITOR_H__
+
+/*
+ * Copyright (c) 2016 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/public-api/controls/control.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TextEditor;
+}
+/**
+ * @addtogroup dali_toolkit_controls_text_controls
+ * @{
+ */
+
+/**
+ * @brief A control which provides a multi-line editable text editor.
+ *
+ *  * Signals
+ * | %Signal Name         | Method                                              |
+ * |----------------------|-----------------------------------------------------|
+ * | textChanged          | @ref TextChangedSignal()                            |
+ *
+ */
+class DALI_IMPORT_API TextEditor : public Control
+{
+public:
+
+  /**
+   * @brief The start and end property ranges for this control.
+   */
+  enum PropertyRange
+  {
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000              ///< Reserve property indices
+  };
+
+  /**
+   * @brief An enumeration of properties belonging to the TextEditor class.
+   */
+  struct Property
+  {
+    enum
+    {
+      RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend",                    The type or rendering e.g. bitmap-based,                                         type INT
+      TEXT,                                     ///< name "text",                                The text to display in UTF-8 format,                                             type STRING
+      TEXT_COLOR,                               ///< name "textColor",                           The text color,                                                                  type VECTOR4
+      FONT_FAMILY,                              ///< name "fontFamily",                          The requested font family,                                                       type STRING
+      FONT_STYLE,                               ///< name "fontStyle",                           The requested font style,                                                        type STRING
+      POINT_SIZE,                               ///< name "pointSize",                           The size of font in points,                                                      type FLOAT
+      HORIZONTAL_ALIGNMENT,                     ///< name "horizontalAlignment",                 The text horizontal alignment,                                                   type STRING,  values "BEGIN", "CENTER", "END"
+      SCROLL_THRESHOLD,                         ///< name "scrollThreshold"                      Vertical scrolling will occur if the cursor is this close to the control border, type FLOAT
+      SCROLL_SPEED,                             ///< name "scrollSpeed"                          The scroll speed in pixels per second,                                           type FLOAT
+      PRIMARY_CURSOR_COLOR,                     ///< name "primaryCursorColor",                  The color to apply to the primary cursor,                                        type VECTOR4
+      SECONDARY_CURSOR_COLOR,                   ///< name "secondaryCursorColor",                The color to apply to the secondary cursor,                                      type VECTOR4
+      ENABLE_CURSOR_BLINK,                      ///< name "enableCursorBlink",                   Whether the cursor should blink or not,                                          type BOOLEAN
+      CURSOR_BLINK_INTERVAL,                    ///< name "cursorBlinkInterval",                 The time interval in seconds between cursor on/off states,                       type FLOAT
+      CURSOR_BLINK_DURATION,                    ///< name "cursorBlinkDuration",                 The cursor will stop blinking after this number of seconds (if non-zero),        type FLOAT
+      CURSOR_WIDTH,                             ///< name "cursorWidth",                         The cursor width,                                                                type INTEGER
+      GRAB_HANDLE_IMAGE,                        ///< name "grabHandleImage",                     The image to display for the grab handle,                                        type STRING
+      GRAB_HANDLE_PRESSED_IMAGE,                ///< name "grabHandlePressedImage",              The image to display when the grab handle is pressed,                            type STRING
+      SELECTION_HANDLE_IMAGE_LEFT,              ///< name "selectionHandleImageLeft",            The image to display for the left selection handle,                              type MAP
+      SELECTION_HANDLE_IMAGE_RIGHT,             ///< name "selectionHandleImageRight",           The image to display for the right selection handle,                             type MAP
+      SELECTION_HANDLE_PRESSED_IMAGE_LEFT,      ///< name "selectionHandlePressedImageLeft",     The image to display when the left selection handle is pressed,                  type MAP
+      SELECTION_HANDLE_PRESSED_IMAGE_RIGHT,     ///< name "selectionHandlePressedImageRight",    The image to display when the right selection handle is pressed,                 type MAP
+      SELECTION_HANDLE_MARKER_IMAGE_LEFT,       ///< name "selectionHandleMarkerImageLeft",      The image to display for the left selection handle marker,                       type MAP
+      SELECTION_HANDLE_MARKER_IMAGE_RIGHT,      ///< name "selectionHandleMarkerImageRight",     The image to display for the right selection handle marker,                      type MAP
+      SELECTION_HIGHLIGHT_COLOR,                ///< name "selectionHighlightColor",             The color of the selection highlight,                                            type VECTOR4
+      DECORATION_BOUNDING_BOX,                  ///< name "decorationBoundingBox",               The decorations (handles etc) will positioned within this area on-screen,        type RECTANGLE
+      ENABLE_MARKUP,                            ///< name "enableMarkup",                        Whether the mark-up processing is enabled.                                       type BOOLEAN
+      INPUT_COLOR,                              ///< name "inputColor",                          The color of the new input text,                                                 type VECTOR4
+      INPUT_FONT_FAMILY,                        ///< name "inputFontFamily",                     The font's family of the new input text,                                         type STRING
+      INPUT_FONT_STYLE,                         ///< name "inputFontStyle",                      The font's style of the new input text,                                          type STRING
+      INPUT_POINT_SIZE                          ///< name "inputPointSize",                      The font's size of the new input text in points,                                 type FLOAT
+    };
+  };
+
+  // Type Defs
+
+  /// @brief Text changed signal type.
+  typedef Signal<void ( TextEditor ) > TextChangedSignalType;
+
+  /**
+   * @brief Create the TextEditor control.
+   * @return A handle to the TextEditor control.
+   */
+  static TextEditor New();
+
+  /**
+   * @brief Creates an empty handle.
+   */
+  TextEditor();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] handle The handle to copy from.
+   */
+  TextEditor( const TextEditor& handle );
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle The handle to copy from.
+   * @return A reference to this.
+   */
+  TextEditor& operator=( const TextEditor& handle );
+
+  /**
+   * @brief Destructor.
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~TextEditor();
+
+  /**
+   * @brief Downcast a handle to TextEditor.
+   *
+   * If the BaseHandle points is a TextEditor the downcast returns a valid handle.
+   * If not the returned handle is left empty.
+   *
+   * @param[in] handle Handle to an object.
+   * @return handle to a TextEditor or an empty handle.
+   */
+  static TextEditor DownCast( BaseHandle handle );
+
+  // Signals
+
+  /**
+   * @brief This signal is emitted when the text changes.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( TextEditor textEditor );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  TextChangedSignalType& TextChangedSignal();
+
+public: // Not intended for application developers
+
+  /**
+   * @brief Creates a handle using the Toolkit::Internal implementation.
+   *
+   * @param[in] implementation The Control implementation.
+   */
+  DALI_INTERNAL TextEditor( Internal::TextEditor& implementation );
+
+  /**
+   * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+   *
+   * @param[in]  internal  A pointer to the internal CustomActor.
+   */
+  explicit DALI_INTERNAL TextEditor( Dali::Internal::CustomActor* internal );
+};
+
+/**
+ * @}
+ */
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_EDITOR_H__
index 953c478..ff91aa7 100755 (executable)
@@ -15,6 +15,7 @@ devel_api_src_files = \
   $(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 \
+  $(devel_api_src_dir)/controls/text-controls/text-editor.cpp \
   $(devel_api_src_dir)/controls/text-controls/text-selection-popup.cpp \
   $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \
   $(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
@@ -103,6 +104,7 @@ devel_api_super_blur_view_header_files = \
   $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.h
 
 devel_api_text_controls_header_files = \
+  $(devel_api_src_dir)/controls/text-controls/text-editor.h \
   $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h \
   $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.h
 
index 1535eeb..de40d44 100644 (file)
@@ -1117,7 +1117,6 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
                       parser.GetErrorDescription().c_str() );
 
     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
-
   }
   else
   {
@@ -1155,7 +1154,6 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
   }
 
   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
-
 }
 
 void Builder::AddConstants( const Property::Map& map )
@@ -1359,9 +1357,9 @@ Builder::Builder()
   mParser = Dali::Toolkit::JsonParser::New();
 
   Property::Map defaultDirs;
-  defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ]  = DALI_IMAGE_DIR;
-  defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ]  = DALI_SOUND_DIR;
-  defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ] = DALI_STYLE_DIR;
+  defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ]       = DALI_IMAGE_DIR;
+  defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ]       = DALI_SOUND_DIR;
+  defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ]       = DALI_STYLE_DIR;
   defaultDirs[ TOKEN_STRING(DALI_STYLE_IMAGE_DIR) ] = DALI_STYLE_IMAGE_DIR;
 
   AddConstants( defaultDirs );
index afa9e59..3691838 100644 (file)
@@ -318,8 +318,13 @@ TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type)
       TreeNodeManipulator modify(node);
 
       modify.SetName(name);
-      // Set the type of the existing node, this may remove children where necessary
-      // (changing from container type to value type)
+
+      // Set the type of the existing node.
+      // Where the new type is different, then any children of this node will
+      // be deleted.
+      // When the type is an array of numbers, then this will also remove any children
+      // When the type is an object or other array, then the children will not be removed,
+      // but will instead follow these replace rules.
       modify.SetType(type);
 
       mCurrent = modify;
index 3e10edd..4357cb8 100644 (file)
@@ -36,16 +36,37 @@ namespace Internal
 namespace
 {
 
-void Indent(std::ostream& o, int indent)
+void Indent(std::ostream& o, int level, int indentWidth)
 {
-  for (int i = 0; i < indent; ++i)
+  for (int i = 0; i < level*indentWidth; ++i)
   {
     o << " ";
   }
 }
 
+std::string EscapeQuotes( const char* aString)
+{
+  std::string escapedString;
+  int length = strlen(aString);
+  escapedString.reserve(length);
+
+  const char* end = aString+length;
+  for( const char* iter = aString; iter != end ; ++iter)
+  {
+    if(*iter != '\"')
+    {
+      escapedString.push_back(*iter);
+    }
+    else
+    {
+      escapedString.append("\\\"");
+    }
+  }
+  return escapedString;
 }
 
+} // anonymous namespace
+
 TreeNodeManipulator::TreeNodeManipulator(TreeNode* node)
   : mNode(node)
 {
@@ -270,6 +291,19 @@ void TreeNodeManipulator::SetType( TreeNode::NodeType type)
       }
     }
   }
+  else if( TreeNode::ARRAY == mNode->mType )
+  {
+    if( mNode->mFirstChild != NULL )
+    {
+      TreeNode::NodeType type = mNode->mFirstChild->GetType();
+
+      if( TreeNode::FLOAT == type || TreeNode::INTEGER == type )
+      {
+        // Arrays of numbers should be replaced, not appended to.
+        RemoveChildren();
+      }
+    }
+  }
 }
 
 void TreeNodeManipulator::SetName( const char* name )
@@ -327,14 +361,17 @@ void TreeNodeManipulator::SetBoolean( bool b )
 void TreeNodeManipulator::Write(std::ostream& output, int indent) const
 {
   DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
-  DoWrite(mNode, output, indent);
+  DoWrite(mNode, output, 0, indent, false);
 }
 
-void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, int indent) const
+void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, int level, int indentWidth, bool groupChildren) const
 {
   DALI_ASSERT_DEBUG(value && "Operation on NULL JSON node");
 
-  Indent(output, indent);
+  if(!groupChildren)
+  {
+    Indent(output, level, indentWidth);
+  }
 
   if (value->GetName())
   {
@@ -348,9 +385,9 @@ void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, i
       output << "null";
       if(NULL != value->mNextSibling)
       {
-        output << ",";
+        output << ", ";
       }
-      if(indent)
+      if( !groupChildren )
       {
         output << std::endl;
       }
@@ -359,58 +396,89 @@ void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, i
     case TreeNode::OBJECT:
     case TreeNode::ARRAY:
     {
+      bool groupMyChildren = false;
+
+      if( TreeNode::ARRAY == value->GetType() &&
+          ( TreeNode::INTEGER == value->mFirstChild->GetType() ||
+            TreeNode::FLOAT   == value->mFirstChild->GetType() ) )
+      {
+        groupMyChildren = true;
+      }
+
       if( value->GetType() == TreeNode::OBJECT)
       {
+        output << std::endl;
+        Indent(output, level, indentWidth);
         output << "{";
-        if(indent)
-        {
-          output << std::endl;
-        }
       }
       else
       {
-        output << "[";
-        if(indent)
+        if( !groupMyChildren )
         {
           output << std::endl;
+          Indent(output, level, indentWidth);
         }
+        output << "[";
+      }
+
+      if( groupMyChildren )
+      {
+        output << " ";
+      }
+      else
+      {
+        output << std::endl;
       }
 
       for (TreeNode::ConstIterator it = value->CBegin(); it != value->CEnd(); ++it)
       {
-        DoWrite( &((*it).second), output, indent + 1);
+        DoWrite( &((*it).second), output, level+1, indentWidth, groupMyChildren );
       }
-      Indent(output, indent);
+
+      if( !groupMyChildren )
+      {
+        Indent(output, level, indentWidth);
+      }
+
       if( value->GetType() == TreeNode::OBJECT )
       {
         output << "}";
-        if(indent)
-        {
-          output << std::endl;
-        }
       }
       else
       {
         output << "]";
-        if(indent)
-        {
-          output << std::endl;
-        }
       }
+
+      if( NULL != value->mNextSibling )
+      {
+        output << ",";
+      }
+
+      if( !groupChildren )
+      {
+        output << std::endl;
+      }
+
+      groupChildren = false;
       break;
     }
     case TreeNode::STRING:
     {
-      output << "\"" << value->GetString() << "\"";
+      std::string escapedString = EscapeQuotes(value->GetString());
+      output << "\"" << escapedString << "\"";
       if(NULL != value->mNextSibling)
       {
         output << ",";
       }
-      if(indent)
+
+      if( groupChildren )
+      {
+        output << " ";
+      }
+      else
       {
         output << std::endl;
       }
-
       break;
     }
     case TreeNode::INTEGER:
@@ -420,11 +488,15 @@ void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, i
       {
         output << ",";
       }
-      if(indent)
+
+      if( groupChildren )
+      {
+        output << " ";
+      }
+      else
       {
         output << std::endl;
       }
-
       break;
     }
     case TreeNode::FLOAT:
@@ -436,7 +508,12 @@ void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, i
       {
         output << ",";
       }
-      if(indent)
+
+      if( groupChildren )
+      {
+        output << " ";
+      }
+      else
       {
         output << std::endl;
       }
@@ -452,11 +529,17 @@ void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, i
       {
         output << "false";
       }
+
       if(NULL != value->mNextSibling)
       {
         output << ",";
       }
-      if(indent)
+
+      if( groupChildren )
+      {
+        output << " ";
+      }
+      else
       {
         output << std::endl;
       }
@@ -520,4 +603,3 @@ char *CopyString( const char *fromString, VectorCharIter& iter, const VectorChar
 } // namespace Toolkit
 
 } // namespace Dali
-
index 838c2cb..f900350 100644 (file)
@@ -191,7 +191,7 @@ private:
   /*
    * Do write to string stream
    */
-  void DoWrite(const TreeNode *value, std::ostream& output, int ident) const;
+  void DoWrite(const TreeNode *value, std::ostream& output, int level, int ident, bool groupChildren) const;
 
 };
 
index e98f539..aecb859 100644 (file)
@@ -35,6 +35,9 @@ BaseHandle Create()
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create );
 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resourceUrl", STRING, RESOURCE_URL )
 DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "preMultipliedAlpha", BOOLEAN, PRE_MULTIPLIED_ALPHA )
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA )
 DALI_TYPE_REGISTRATION_END()
 
 } // anonymous namespace
@@ -42,7 +45,8 @@ DALI_TYPE_REGISTRATION_END()
 using namespace Dali;
 
 ImageView::ImageView()
-: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
+: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
+  mPremultipledAlphaEnabled( false )
 {
 }
 
@@ -143,9 +147,32 @@ void ImageView::SetImage( const std::string& url, ImageDimensions size )
   }
 }
 
+void ImageView::EnablePreMultipliedAlpha( bool preMultipled )
+{
+  mPremultipledAlphaEnabled = preMultipled;
+
+  if( mRenderer )
+  {
+    ControlRenderer& rendererImpl = GetImplementation( mRenderer );
+    if (&typeid( rendererImpl ) == &typeid(ImageRenderer) )
+    {
+      ImageRenderer* imageRenderer = static_cast<ImageRenderer*>( &rendererImpl );
+      imageRenderer->EnablePreMultipliedAlpha( preMultipled );
+    }
+  }
+}
+
+bool ImageView::IsPreMultipliedAlphaEnabled() const
+{
+  return mPremultipledAlphaEnabled;
+}
+
 void ImageView::SetDepthIndex( int depthIndex )
 {
-  mRenderer.SetDepthIndex( depthIndex );
+  if( mRenderer )
+  {
+    mRenderer.SetDepthIndex( depthIndex );
+  }
 }
 
 Vector3 ImageView::GetNaturalSize()
@@ -154,10 +181,10 @@ Vector3 ImageView::GetNaturalSize()
 
   size.x = mImageSize.GetWidth();
   size.y = mImageSize.GetHeight();
-  size.z = std::min(size.x, size.y);
 
   if( size.x > 0 && size.y > 0 )
   {
+    size.z = std::min(size.x, size.y);
     return size;
   }
   else
@@ -191,6 +218,7 @@ float ImageView::GetWidthForHeight( float height )
   }
 }
 
+
 ///////////////////////////////////////////////////////////
 //
 // Private methods
@@ -218,7 +246,6 @@ void ImageView::OnStageDisconnection()
   Control::OnStageDisconnection();
 }
 
-
 ///////////////////////////////////////////////////////////
 //
 // Properties
@@ -261,6 +288,16 @@ void ImageView::SetProperty( BaseObject* object, Property::Index index, const Pr
 
         break;
       }
+
+      case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
+      {
+        bool IsPre;
+        if( value.Get( IsPre ) )
+        {
+          GetImpl(imageView).EnablePreMultipliedAlpha( IsPre );
+        }
+        break;
+      }
     }
   }
 }
@@ -273,11 +310,11 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop
 
   if ( imageview )
   {
+    ImageView& impl = GetImpl( imageview );
     switch ( propertyIndex )
     {
       case Toolkit::ImageView::Property::RESOURCE_URL:
       {
-        ImageView& impl = GetImpl( imageview );
         if ( !impl.mUrl.empty() )
         {
           value = impl.mUrl;
@@ -287,7 +324,6 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop
 
       case Toolkit::ImageView::Property::IMAGE:
       {
-        ImageView& impl = GetImpl( imageview );
         if ( !impl.mUrl.empty() )
         {
           value = impl.mUrl;
@@ -304,6 +340,12 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop
         }
         break;
       }
+
+      case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
+      {
+        value = impl.IsPreMultipliedAlphaEnabled();
+        break;
+      }
     }
   }
 
index 86437ff..2b31bf9 100644 (file)
@@ -38,7 +38,7 @@ namespace Internal
 {
 class ImageView : public Control
 {
- protected:
+protected:
 
   /**
    * Construct a new ImageView.
@@ -50,8 +50,6 @@ class ImageView : public Control
    */
   virtual ~ImageView();
 
-
-
 public:
   /**
    * Create a new ImageView.
@@ -77,6 +75,20 @@ public:
    */
   void SetImage( const std::string& imageUrl, ImageDimensions size );
 
+  /**
+   * @brief Set whether the Pre-multiplied Alpha Blending is required
+   *
+   * @param[in] preMultipled whether alpha is pre-multiplied.
+   */
+  void EnablePreMultipliedAlpha( bool preMultipled );
+
+  /**
+   * @brief Query whether alpha is pre-multiplied.
+   *
+   * @return True is alpha is pre-multiplied, false otherwise.
+   */
+  bool IsPreMultipliedAlphaEnabled() const;
+
   // Properties
   /**
    * Called when a property of an object of this type is set.
@@ -131,14 +143,6 @@ private: // From Control
   virtual float GetWidthForHeight( float height );
 
 private:
-  /**
-   * Attaches mImage member to the renderer, creating the renderers, samplers, meshes and materials if needed
-   *
-   * @pre mImage has been initialised
-   */
-  void AttachImage();
-
-private:
   // Undefined
   ImageView( const ImageView& );
   ImageView& operator=( const ImageView& );
@@ -150,6 +154,8 @@ private:
   std::string      mUrl;          ///< the url for the image if the image came from a URL, empty otherwise
   Image            mImage;        ///< the Image if the image came from a Image, null otherwise
   Property::Map    mPropertyMap;  ///< the Property::Map if the image came from a Property::Map, empty otherwise
+
+  bool             mPremultipledAlphaEnabled; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
 };
 
 } // namespace Internal
index da77f95..7862d53 100644 (file)
@@ -71,15 +71,21 @@ const char * const NO_FILTER("noFilter");
 const char * const DONT_CARE("dontCare");
 
 const std::string TEXTURE_UNIFORM_NAME = "sTexture";
-const std::string TEXTURE_RECT_UNIFORM_NAME = "uTextureRect";
+const std::string ATLAS_RECT_UNIFORM_NAME = "uAtlasRect";
+const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea";
+
+// Set this uniform to 1.0 for conventional alpha blending; if pre-multiplied alpha blending, set this uniform to 0.0
+const std::string ALPHA_BLENDING_UNIFORM_NAME = "uAlphaBlending";
+
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
 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
-  uniform mediump vec4 uTextureRect;\n
+  uniform mediump vec4 uAtlasRect;\n
+  uniform mediump vec4 pixelArea;
+  varying mediump vec2 vTexCoord;\n
   \n
   void main()\n
   {\n
@@ -87,7 +93,7 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
     vertexPosition.xyz *= uSize;\n
     vertexPosition = uMvpMatrix * vertexPosition;\n
     \n
-    vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5));\n
+    vTexCoord = mix( uAtlasRect.xy, uAtlasRect.zw, pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) ) );\n
     gl_Position = vertexPosition;\n
   }\n
 );
@@ -96,10 +102,11 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   varying mediump vec2 vTexCoord;\n
   uniform sampler2D sTexture;\n
   uniform lowp vec4 uColor;\n
+  uniform lowp float uAlphaBlending; // Set to 1.0 for conventional alpha blending; if pre-multiplied alpha blending, set to 0.0
   \n
   void main()\n
   {\n
-    gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+    gl_FragColor = texture2D( sTexture, vTexCoord ) * vec4( uColor.rgb*max( uAlphaBlending, uColor.a ), uColor.a );\n
   }\n
 );
 
@@ -197,10 +204,10 @@ Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gri
 ImageRenderer::ImageRenderer( RendererFactoryCache& factoryCache, ImageAtlasManager& atlasManager )
 : ControlRenderer( factoryCache ),
   mAtlasManager( atlasManager ),
-  mTextureRect( FULL_TEXTURE_RECT ),
   mDesiredSize(),
   mFittingMode( FittingMode::DEFAULT ),
-  mSamplingMode( SamplingMode::DEFAULT )
+  mSamplingMode( SamplingMode::DEFAULT ),
+  mIsAlphaPreMultiplied( false )
 {
 }
 
@@ -397,6 +404,12 @@ Renderer ImageRenderer::CreateRenderer() const
       shader  = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader,
                              mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader,
                              mImpl->mCustomShader->mHints );
+      if( mImpl->mCustomShader->mVertexShader.empty() )
+      {
+        shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
+      }
     }
   }
 
@@ -421,20 +434,19 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
     mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl );
     if( !mImpl->mRenderer )
     {
-      Material material = mAtlasManager.Add(mTextureRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+      Vector4 atlasRect;
+      Material material = mAtlasManager.Add(atlasRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
       if( material )
       {
         Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
         mImpl->mRenderer = Renderer::New( geometry, material );
-        SetTextureRectUniform(mTextureRect);
+        mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
       }
       else // big image, atlasing is not applied
       {
         mImpl->mRenderer = CreateRenderer();
-        mTextureRect = FULL_TEXTURE_RECT;
-        SetTextureRectUniform(mTextureRect);
 
-        ResourceImage image = Dali::ResourceImage::New( imageUrl );
+        ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
         image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
         Material material = mImpl->mRenderer.GetMaterial();
         material.AddTexture( image, TEXTURE_UNIFORM_NAME );
@@ -442,11 +454,7 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
 
       mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer );
     }
-    else
-    {
-      Property::Value textureRect = mImpl->mRenderer.GetProperty( mImpl->mRenderer.GetPropertyIndex(TEXTURE_RECT_UNIFORM_NAME) );
-      textureRect.Get( mTextureRect );
-    }
+
     mImpl->mFlags |= Impl::IS_FROM_CACHE;
   }
   else
@@ -458,15 +466,6 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
     ResourceImage resourceImage = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
     resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
     ApplyImageToSampler( resourceImage );
-
-    // custom vertex shader does not need texture rect uniform
-    if( mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty() )
-    {
-      return;
-    }
-
-    mTextureRect = FULL_TEXTURE_RECT;
-    SetTextureRectUniform( mTextureRect );
   }
 }
 
@@ -480,13 +479,6 @@ void ImageRenderer::InitializeRenderer( const Image& image )
   {
     ApplyImageToSampler( image );
   }
-
-  // default shader or custom shader with the default image vertex shader
-  if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty() )
-  {
-    mTextureRect = FULL_TEXTURE_RECT;
-    SetTextureRectUniform( mTextureRect );
-  }
 }
 
 
@@ -500,6 +492,8 @@ void ImageRenderer::DoSetOnStage( Actor& actor )
   {
     InitializeRenderer( mImage );
   }
+
+  EnablePreMultipliedAlpha( mIsAlphaPreMultiplied );
 }
 
 void ImageRenderer::DoSetOffStage( Actor& actor )
@@ -622,6 +616,9 @@ Shader ImageRenderer::GetImageShader( RendererFactoryCache& factoryCache )
   {
     shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
     factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, shader );
+    shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+    shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
   }
   return shader;
 }
@@ -709,6 +706,37 @@ void ImageRenderer::SetImage( Actor& actor, const Image& image )
   }
 }
 
+void ImageRenderer::EnablePreMultipliedAlpha( bool preMultipled )
+{
+  mIsAlphaPreMultiplied = preMultipled;
+  if( mImpl->mRenderer )
+  {
+    Material material = mImpl->mRenderer.GetMaterial();
+
+    if( preMultipled )
+    {
+      material.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+                             BlendingFactor::ONE, BlendingFactor::ONE );
+      if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty())
+      {
+        material.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 0.f );
+      }
+    }
+    else
+    {
+      // using default blend func
+      material.SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+                              BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
+
+      Property::Index index = material.GetPropertyIndex( ALPHA_BLENDING_UNIFORM_NAME );
+      if( index != Property::INVALID_INDEX ) // only set value when the property already exist on the Material
+      {
+        material.SetProperty( index, 1.f );
+      }
+    }
+  }
+}
+
 void ImageRenderer::ApplyImageToSampler( const Image& image )
 {
   if( image )
@@ -740,22 +768,22 @@ void ImageRenderer::OnImageLoaded( ResourceImage image )
   }
 }
 
-void ImageRenderer::SetTextureRectUniform( const Vector4& textureRect )
+void ImageRenderer::CleanCache(const std::string& url)
 {
-  if( mImpl->mRenderer )
+  Material material = mImpl->mRenderer.GetMaterial();
+
+  Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
+  Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
+  if( index != Property::INVALID_INDEX )
   {
-    // Register/Set property.
-    mImpl->mRenderer.RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect );
+    Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
+    atlasRectValue.Get( atlasRect );
   }
-}
 
-void ImageRenderer::CleanCache(const std::string& url)
-{
-  Material material = mImpl->mRenderer.GetMaterial();
   mImpl->mRenderer.Reset();
-  if( mFactoryCache.CleanRendererCache( url ) )
+  if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
   {
-    mAtlasManager.Remove( material, mTextureRect );
+    mAtlasManager.Remove( material, atlasRect );
   }
 }
 
index c11c6b0..4b73fc6 100644 (file)
@@ -162,6 +162,13 @@ public:
    */
   void SetImage( Actor& actor, const Image& image );
 
+  /**
+   * @brief Set whether the Pre-multiplied Alpha Blending is required
+   *
+   * @param[in] preMultipled whether alpha is pre-multiplied.
+   */
+  void EnablePreMultipliedAlpha(  bool preMultipled );
+
 private:
 
   /**
@@ -212,12 +219,12 @@ private:
 private:
   Image mImage;
   ImageAtlasManager& mAtlasManager;
-  Vector4 mTextureRect;
 
   std::string mImageUrl;
   Dali::ImageDimensions mDesiredSize;
   Dali::FittingMode::Type mFittingMode;
   Dali::SamplingMode::Type mSamplingMode;
+  bool mIsAlphaPreMultiplied;
 
 };
 
index aa6443d..9403c8a 100644 (file)
@@ -42,21 +42,6 @@ using namespace Dali;
 namespace // Unnamed namespace
 {
 
-//Type registration
-
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
-
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition",      FLOAT,    LAYOUT_POSITION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed",         FLOAT,    SCROLL_SPEED)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot",           FLOAT,    OVERSHOOT)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection",     VECTOR2,  SCROLL_DIRECTION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation",   INTEGER,  LAYOUT_ORIENTATION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize",   FLOAT,    SCROLL_CONTENT_SIZE)
-
-DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layoutActivated",     LAYOUT_ACTIVATED_SIGNAL )
-
-DALI_TYPE_REGISTRATION_END()
-
 const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f;
 const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f;
 const float DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f;
@@ -256,6 +241,27 @@ namespace Internal
 namespace // unnamed namespace
 {
 
+//Type registration
+
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
+
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeSpeed",          FLOAT,     MINIMUM_SWIPE_SPEED          )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeDistance",       FLOAT,     MINIMUM_SWIPE_DISTANCE       )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "wheelScrollDistanceStep",    FLOAT,     WHEEL_SCROLL_DISTANCE_STEP   )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled",          BOOLEAN,   SNAP_TO_ITEM_ENABLED         )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval",            FLOAT,     REFRESH_INTERVAL             )
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition",      FLOAT,    LAYOUT_POSITION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed",         FLOAT,    SCROLL_SPEED)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot",           FLOAT,    OVERSHOOT)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection",     VECTOR2,  SCROLL_DIRECTION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation",   INTEGER,  LAYOUT_ORIENTATION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize",   FLOAT,    SCROLL_CONTENT_SIZE)
+
+DALI_SIGNAL_REGISTRATION(              Toolkit, ItemView, "layoutActivated",     LAYOUT_ACTIVATED_SIGNAL )
+
+DALI_TYPE_REGISTRATION_END()
+
 bool FindById( const ItemContainer& items, ItemId id )
 {
   for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
@@ -1692,6 +1698,86 @@ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface*
   return connected;
 }
 
+void ItemView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+  if( itemView )
+  {
+    ItemView& itemViewImpl( GetImpl( itemView ) );
+    switch( index )
+    {
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+      {
+        itemViewImpl.SetMinimumSwipeSpeed( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+      {
+        itemViewImpl.SetMinimumSwipeDistance( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        itemViewImpl.SetWheelScrollDistanceStep( value.Get<float>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+      {
+        itemViewImpl.SetAnchoring( value.Get<bool>() );
+        break;
+      }
+      case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+      {
+        itemViewImpl.SetRefreshInterval( value.Get<float>() );
+        break;
+      }
+    }
+  }
+}
+
+Property::Value ItemView::GetProperty( BaseObject* object, Property::Index index )
+{
+  Property::Value value;
+
+  Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+  if( itemView )
+  {
+    ItemView& itemViewImpl( GetImpl( itemView ) );
+    switch( index )
+    {
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+      {
+        value = itemViewImpl.GetMinimumSwipeSpeed();
+        break;
+      }
+      case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+      {
+        value = itemViewImpl.GetMinimumSwipeDistance();
+        break;
+      }
+      case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        value = itemViewImpl.GetWheelScrollDistanceStep();
+        break;
+      }
+      case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+      {
+        value = itemViewImpl.GetAnchoring();
+        break;
+      }
+      case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+      {
+        value = itemViewImpl.GetRefreshInterval();
+        break;
+      }
+    }
+  }
+
+  return value;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index a18618d..2b3a52f 100644 (file)
@@ -308,6 +308,24 @@ public:
    */
   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
 
+  //properties
+
+  /**
+   * Called when a property of an object of this type is set.
+   * @param[in] object The object whose property is set.
+   * @param[in] index The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+  /**
+   * Called to retrieve a property of an object of this type.
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] index The property index.
+   * @return The current value of the property.
+   */
+  static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
 private:
 
   /**
index 0bda5ea..82df8cc 100644 (file)
@@ -244,6 +244,11 @@ BaseHandle Create()
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollView, Toolkit::Scrollable, Create )
 
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrapEnabled",                BOOLEAN,   WRAP_ENABLED                )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panningEnabled",             BOOLEAN,   PANNING_ENABLED             )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "axisAutoLockEnabled",        BOOLEAN,   AXIS_AUTO_LOCK_ENABLED      )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wheelScrollDistanceStep",    VECTOR2,   WHEEL_SCROLL_DISTANCE_STEP  )
+
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPosition",  VECTOR2, SCROLL_POSITION)
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPrePosition",   VECTOR2, SCROLL_PRE_POSITION)
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionX",    SCROLL_PRE_POSITION_X, SCROLL_PRE_POSITION, 0)
@@ -966,6 +971,11 @@ void ScrollView::UpdatePropertyDomain()
   }
 }
 
+bool ScrollView::GetScrollSensitive()
+{
+  return mSensitive;
+}
+
 void ScrollView::SetScrollSensitive(bool sensitive)
 {
   Actor self = Self();
@@ -1011,11 +1021,21 @@ void ScrollView::SetSnapOvershootAlphaFunction(AlphaFunction alpha)
   mSnapOvershootAlphaFunction = alpha;
 }
 
+float ScrollView::GetSnapOvershootDuration()
+{
+  return mSnapOvershootDuration;
+}
+
 void ScrollView::SetSnapOvershootDuration(float duration)
 {
   mSnapOvershootDuration = duration;
 }
 
+bool ScrollView::GetActorAutoSnap()
+{
+  return mActorAutoSnapEnabled;
+}
+
 void ScrollView::SetActorAutoSnap(bool enable)
 {
   mActorAutoSnapEnabled = enable;
@@ -2821,6 +2841,76 @@ void ScrollView::SetInternalConstraints()
   ApplyConstraintToBoundActors(constraint);
 }
 
+void ScrollView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+  if( scrollView )
+  {
+    ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+    switch( index )
+    {
+      case Toolkit::ScrollView::Property::WRAP_ENABLED:
+      {
+        scrollViewImpl.SetWrapMode( value.Get<bool>() );
+        break;
+      }
+      case Toolkit::ScrollView::Property::PANNING_ENABLED:
+      {
+        scrollViewImpl.SetScrollSensitive( value.Get<bool>() );
+        break;
+      }
+      case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+      {
+        scrollViewImpl.SetAxisAutoLock( value.Get<bool>() );
+        break;
+      }
+      case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        scrollViewImpl.SetWheelScrollDistanceStep( value.Get<Vector2>() );
+        break;
+      }
+    }
+  }
+}
+
+Property::Value ScrollView::GetProperty( BaseObject* object, Property::Index index )
+{
+  Property::Value value;
+
+  Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+  if( scrollView )
+  {
+    ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+    switch( index )
+    {
+      case Toolkit::ScrollView::Property::WRAP_ENABLED:
+      {
+        value = scrollViewImpl.GetWrapMode();
+        break;
+      }
+      case Toolkit::ScrollView::Property::PANNING_ENABLED:
+      {
+        value = scrollViewImpl.GetScrollSensitive();
+        break;
+      }
+      case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+      {
+        value = scrollViewImpl.GetAxisAutoLock();
+        break;
+      }
+      case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+      {
+        value = scrollViewImpl.GetWheelScrollDistanceStep();
+        break;
+      }
+    }
+  }
+
+  return value;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 082a046..b9db77d 100644 (file)
@@ -191,6 +191,13 @@ public:
   void SetRulerY(RulerPtr ruler);
 
   /**
+   * Retrieve the touch sensitivity.
+   *
+   * @return whether the touch sensitivity is true or false.
+   */
+  bool GetScrollSensitive();
+
+  /**
    * @copydoc Toolkit::ScrollView::SetScrollSensitive
    */
   void SetScrollSensitive(bool sensitive);
@@ -206,11 +213,25 @@ public:
   void SetSnapOvershootAlphaFunction(AlphaFunction alpha);
 
   /**
+   * Retrieve the duartion of Snap Overshoot animation
+   *
+   * @return the duration.
+   */
+  float GetSnapOvershootDuration();
+
+  /**
    * @copydoc Toolkit::ScrollView::SetSnapOvershootDuration
    */
   void SetSnapOvershootDuration(float duration);
 
   /**
+   * Retrieve whether Actor Auto-Snap mode is enabled or not.
+   *
+   * @return Actor Auto-Snap mode Enabled flag.
+   */
+  bool GetActorAutoSnap();
+
+  /**
    * @copydoc Toolkit::ScrollView::SetActorAutoSnap
    */
   void SetActorAutoSnap(bool enable);
@@ -482,6 +503,24 @@ public:
    */
   void SetOvershootEffectColor( const Vector4& color );
 
+  //properties
+
+  /**
+   * Called when a property of an object of this type is set.
+   * @param[in] object The object whose property is set.
+   * @param[in] index The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+  /**
+   * Called to retrieve a property of an object of this type.
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] index The property index.
+   * @return The current value of the property.
+   */
+  static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
 public: //Signals
 
   /**
index 98ab55b..e1f79ca 100644 (file)
@@ -48,7 +48,8 @@ DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Scrollable, Toolkit::Control, Create );
 
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEffectColor",      VECTOR4, OVERSHOOT_EFFECT_COLOR    )
 DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootAnimationSpeed",   FLOAT,   OVERSHOOT_ANIMATION_SPEED )
-const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ANIMATION_SPEED + 1; // OVERSHOOT_SIZE is not public yet
+DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEnabled",          BOOLEAN, OVERSHOOT_ENABLED )
+const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ENABLED + 1; // OVERSHOOT_SIZE is not public yet
 Dali::PropertyRegistration p1( typeRegistration, "overshootSize",  OVERSHOOT_SIZE, Property::VECTOR2, Dali::Toolkit::Internal::Scrollable::SetProperty, Dali::Toolkit::Internal::Scrollable::GetProperty );
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Scrollable, "scrollRelativePosition",   VECTOR2, SCROLL_RELATIVE_POSITION)
@@ -194,6 +195,11 @@ void Scrollable::SetProperty( BaseObject* object, Property::Index index, const P
         scrollableImpl.SetOvershootAnimationSpeed( value.Get<float>() );
         break;
       }
+      case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+      {
+        scrollableImpl.SetOvershootEnabled( value.Get<bool>() );
+        break;
+      }
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         Vector2 input;
@@ -229,6 +235,11 @@ Property::Value Scrollable::GetProperty( BaseObject* object, Property::Index ind
         value = scrollableImpl.GetOvershootAnimationSpeed();
         break;
       }
+      case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+      {
+        value = scrollableImpl.IsOvershootEnabled();
+        break;
+      }
       case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
       {
         value = scrollableImpl.mOvershootSize;
diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
new file mode 100644 (file)
index 0000000..a029c83
--- /dev/null
@@ -0,0 +1,1178 @@
+/*
+ * Copyright (c) 2016 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 <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+
+// EXTERNAL INCLUDES
+#include <cstring>
+#include <limits>
+#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/styling/style-manager-impl.h>
+
+using namespace Dali::Toolkit::Text;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace // unnamed namespace
+{
+
+#if defined(DEBUG_ENABLED)
+  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
+  const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+} // unnamed namespace
+
+namespace
+{
+
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+// Type registration
+BaseHandle Create()
+{
+  return Toolkit::TextEditor::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextEditor, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "renderingBackend",                     INTEGER,   RENDERING_BACKEND                    )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "text",                                 STRING,    TEXT                                 )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "textColor",                            VECTOR4,   TEXT_COLOR                           )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontFamily",                           STRING,    FONT_FAMILY                          )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontStyle",                            STRING,    FONT_STYLE                           )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "pointSize",                            FLOAT,     POINT_SIZE                           )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalAlignment",                  STRING,    HORIZONTAL_ALIGNMENT                 )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollThreshold",                      FLOAT,     SCROLL_THRESHOLD                     )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollSpeed",                          FLOAT,     SCROLL_SPEED                         )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkInterval",                  FLOAT,     CURSOR_BLINK_INTERVAL                )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkDuration",                  FLOAT,     CURSOR_BLINK_DURATION                )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorWidth",                          INTEGER,   CURSOR_WIDTH                         )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandleImage",                      STRING,    GRAB_HANDLE_IMAGE                    )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandlePressedImage",               STRING,    GRAB_HANDLE_PRESSED_IMAGE            )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageLeft",             MAP,       SELECTION_HANDLE_IMAGE_LEFT          )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageRight",            MAP,       SELECTION_HANDLE_IMAGE_RIGHT         )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageLeft",      MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageRight",     MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageLeft",       MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT   )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageRight",      MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT  )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHighlightColor",              VECTOR4,   SELECTION_HIGHLIGHT_COLOR            )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "decorationBoundingBox",                RECTANGLE, DECORATION_BOUNDING_BOX              )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontFamily",                      STRING,    INPUT_FONT_FAMILY                    )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontStyle",                       STRING,    INPUT_FONT_STYLE                     )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputPointSize",                       FLOAT,     INPUT_POINT_SIZE                     )
+
+DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
+
+DALI_TYPE_REGISTRATION_END()
+
+} // namespace
+
+Toolkit::TextEditor TextEditor::New()
+{
+  // Create the implementation, temporarily owned by this handle on stack
+  IntrusivePtr< TextEditor > impl = new TextEditor();
+
+  // Pass ownership to CustomActor handle
+  Toolkit::TextEditor handle( *impl );
+
+  // Second-phase init of the implementation
+  // This can only be done after the CustomActor connection has been made...
+  impl->Initialize();
+
+  return handle;
+}
+
+void TextEditor::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor SetProperty\n");
+
+
+  if( textEditor )
+  {
+    TextEditor& impl( GetImpl( textEditor ) );
+
+    switch( index )
+    {
+      case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+      {
+        int backend = value.Get< int >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
+
+        if( impl.mRenderingBackend != backend )
+        {
+          impl.mRenderingBackend = backend;
+          impl.mRenderer.Reset();
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::TEXT:
+      {
+        if( impl.mController )
+        {
+          const std::string text = value.Get< std::string >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
+
+          impl.mController->SetText( text );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::TEXT_COLOR:
+      {
+        if( impl.mController )
+        {
+          const Vector4 textColor = value.Get< Vector4 >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+          if( impl.mController->GetTextColor() != textColor )
+          {
+            impl.mController->SetTextColor( textColor );
+            impl.mController->SetInputColor( textColor );
+            impl.mRenderer.Reset();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          const std::string fontFamily = value.Get< std::string >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+          impl.mController->SetDefaultFontFamily( fontFamily );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::FONT_STYLE:
+      {
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextEditor::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          const float pointSize = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+
+          if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
+          {
+            impl.mController->SetDefaultPointSize( pointSize );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          const std::string alignStr = value.Get< std::string >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
+
+          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+          if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                              alignment ) )
+          {
+            impl.mController->SetHorizontalAlignment( alignment );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+      {
+        const float threshold = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
+
+        if( impl.mDecorator )
+        {
+          impl.mDecorator->SetScrollThreshold( threshold );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SCROLL_SPEED:
+      {
+        const float speed = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
+
+        if( impl.mDecorator )
+        {
+          impl.mDecorator->SetScrollSpeed( speed );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+      {
+        if( impl.mDecorator )
+        {
+          const Vector4 color = value.Get< Vector4 >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+          impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+      {
+        if( impl.mDecorator )
+        {
+          const Vector4 color = value.Get< Vector4 >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+          impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+      {
+        if( impl.mController )
+        {
+          const bool enable = value.Get< bool >();
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
+
+          impl.mController->SetEnableCursorBlink( enable );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+      {
+        if( impl.mDecorator )
+        {
+          const float interval = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
+
+          impl.mDecorator->SetCursorBlinkInterval( interval );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+      {
+        if( impl.mDecorator )
+        {
+          const float duration = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
+
+          impl.mDecorator->SetCursorBlinkDuration( duration );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+      {
+        if( impl.mDecorator )
+        {
+          const int width = value.Get< int >();
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
+
+          impl.mDecorator->SetCursorWidth( width );
+          impl.mController->GetLayoutEngine().SetCursorWidth( width );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+      {
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
+
+        if( impl.mDecorator )
+        {
+          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+      {
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
+
+        if( impl.mDecorator )
+        {
+          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+      {
+        const Image image = Scripting::NewImage( value );
+
+        if( impl.mDecorator && image )
+        {
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+      {
+        const Vector4 color = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+        if( impl.mDecorator )
+        {
+          impl.mDecorator->SetHighlightColor( color );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+      {
+        if( impl.mDecorator )
+        {
+          const Rect<int> box = value.Get< Rect<int> >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
+
+          impl.mDecorator->SetBoundingBox( box );
+          impl.RequestTextRelayout();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+      {
+        if( impl.mController )
+        {
+          const bool enableMarkup = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
+
+          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_COLOR:
+      {
+        if( impl.mController )
+        {
+          const Vector4 inputColor = value.Get< Vector4 >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
+
+          impl.mController->SetInputColor( inputColor );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          const std::string fontFamily = value.Get< std::string >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+          impl.mController->SetInputFontFamily( fontFamily );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+      {
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          const float pointSize = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+          impl.mController->SetInputFontPointSize( pointSize );
+        }
+        break;
+      }
+    } // switch
+  } // texteditor
+}
+
+Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index index )
+{
+  Property::Value value;
+
+  Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
+
+  if( textEditor )
+  {
+    TextEditor& impl( GetImpl( textEditor ) );
+
+    switch( index )
+    {
+      case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+      {
+        value = impl.mRenderingBackend;
+        break;
+      }
+      case Toolkit::TextEditor::Property::TEXT:
+      {
+        if( impl.mController )
+        {
+          std::string text;
+          impl.mController->GetText( text );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str() );
+          value = text;
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::TEXT_COLOR:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetTextColor();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::FONT_STYLE:
+      {
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+        break;
+      }
+      case Toolkit::TextEditor::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultPointSize();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+      {
+        if( impl.mController )
+        {
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+          if( name )
+          {
+            value = std::string( name );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetScrollThreshold();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SCROLL_SPEED:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetScrollSpeed();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+      {
+        value = impl.mController->GetEnableCursorBlink();
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetCursorBlinkInterval();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetCursorBlinkDuration();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetCursorWidth();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+      {
+        if( impl.mDecorator )
+        {
+          ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
+          if( image )
+          {
+            value = image.GetUrl();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+      {
+        if( impl.mDecorator )
+        {
+          ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
+          if( image )
+          {
+            value = image.GetUrl();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+      {
+        impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+      {
+        impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+      {
+        impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+      {
+        impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+      {
+        impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+      {
+        impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
+        break;
+      }
+      case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+      {
+        if( impl.mDecorator )
+        {
+          value = impl.mDecorator->GetHighlightColor();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+      {
+        if( impl.mDecorator )
+        {
+          Rect<int> boundingBox;
+          impl.mDecorator->GetBoundingBox( boundingBox );
+          value = boundingBox;
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsMarkupProcessorEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_COLOR:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputColor();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+      {
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+        break;
+      }
+      case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputFontPointSize();
+        }
+        break;
+      }
+    } //switch
+  }
+
+  return value;
+}
+
+bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+  Dali::BaseHandle handle( object );
+
+  bool connected( true );
+  Toolkit::TextEditor editor = Toolkit::TextEditor::DownCast( handle );
+
+  if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
+  {
+    editor.TextChangedSignal().Connect( tracker, functor );
+  }
+  else
+  {
+    // signalName does not match any signal
+    connected = false;
+  }
+
+  return connected;
+}
+
+Toolkit::TextEditor::TextChangedSignalType& TextEditor::TextChangedSignal()
+{
+  return mTextChangedSignal;
+}
+
+void TextEditor::OnInitialize()
+{
+  Actor self = Self();
+
+  mController = Text::Controller::New( *this );
+
+  mDecorator = Text::Decorator::New( *mController,
+                                     *mController );
+
+  mController->GetLayoutEngine().SetLayout( LayoutEngine::MULTI_LINE_BOX );
+
+  mController->EnableTextInput( mDecorator );
+
+  mController->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
+
+  // Forward input events to controller
+  EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
+  GetTapGestureDetector().SetMaximumTapsRequired( 2 );
+
+  self.TouchedSignal().Connect( this, &TextEditor::OnTouched );
+
+  // Set BoundingBox to stage size if not already set.
+  Rect<int> boundingBox;
+  mDecorator->GetBoundingBox( boundingBox );
+
+  if( boundingBox.IsEmpty() )
+  {
+    Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
+    mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
+  }
+
+  // Flip vertically the 'left' selection handle
+  mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
+
+  // Fill-parent area by default
+  self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+  self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
+  self.OnStageSignal().Connect( this, &TextEditor::OnStageConnect );
+}
+
+void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
+
+   switch ( change )
+   {
+     case StyleChange::DEFAULT_FONT_CHANGE:
+     {
+       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange DEFAULT_FONT_CHANGE\n");
+       std::string newFont = styleManager.GetDefaultFontFamily();
+       // Property system did not set the font so should update it.
+       mController->UpdateAfterFontChange( newFont );
+       break;
+     }
+
+     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
+     {
+       DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
+
+       if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
+       {
+         // Property system did not set the PointSize so should update it.
+         // todo instruct text-controller to update model
+       }
+       break;
+     }
+     case StyleChange::THEME_CHANGE:
+     {
+       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+       break;
+     }
+   }
+}
+
+Vector3 TextEditor::GetNaturalSize()
+{
+  return mController->GetNaturalSize();
+}
+
+float TextEditor::GetHeightForWidth( float width )
+{
+  return mController->GetHeightForWidth( width );
+}
+
+void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
+
+  if( mController->Relayout( size ) ||
+      !mRenderer )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get() );
+
+    if( mDecorator )
+    {
+      mDecorator->Relayout( size );
+    }
+
+    if( !mRenderer )
+    {
+      mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+    }
+
+    EnableClipping( true, size );
+    RenderText();
+  }
+}
+
+void TextEditor::RenderText()
+{
+  Actor self = Self();
+  Actor renderableActor;
+  if( mRenderer )
+  {
+    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
+  }
+
+  if( renderableActor != mRenderableActor )
+  {
+    UnparentAndReset( mRenderableActor );
+    mRenderableActor = renderableActor;
+  }
+
+  if( mRenderableActor )
+  {
+    const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
+
+    mRenderableActor.SetPosition( offset.x, offset.y );
+
+    Actor clipRootActor;
+    if( mClipper )
+    {
+      clipRootActor = mClipper->GetRootActor();
+    }
+
+    for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
+           endIt = mClippingDecorationActors.end();
+         it != endIt;
+         ++it )
+    {
+      Actor actor = *it;
+
+      if( clipRootActor )
+      {
+        clipRootActor.Add( actor );
+      }
+      else
+      {
+        self.Add( actor );
+      }
+    }
+    mClippingDecorationActors.clear();
+
+    // Make sure the actor is parented correctly with/without clipping
+    if( clipRootActor )
+    {
+      clipRootActor.Add( mRenderableActor );
+    }
+    else
+    {
+      self.Add( mRenderableActor );
+    }
+  }
+}
+
+void TextEditor::OnKeyInputFocusGained()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
+
+  VirtualKeyboard::StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
+
+  ImfManager imfManager = ImfManager::Get();
+
+  if ( imfManager )
+  {
+    imfManager.EventReceivedSignal().Connect( this, &TextEditor::OnImfEvent );
+
+    // Notify that the text editing start.
+    imfManager.Activate();
+
+    // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
+    imfManager.SetRestoreAfterFocusLost( true );
+  }
+
+   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+
+   if ( notifier )
+   {
+      notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
+   }
+
+  mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
+
+  EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
+}
+
+void TextEditor::OnKeyInputFocusLost()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get() );
+
+  VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
+
+  ImfManager imfManager = ImfManager::Get();
+  if ( imfManager )
+  {
+    // The text editing is finished. Therefore the imf manager don't have restore activation.
+    imfManager.SetRestoreAfterFocusLost( false );
+
+    // Notify that the text editing finish.
+    imfManager.Deactivate();
+
+    imfManager.EventReceivedSignal().Disconnect( this, &TextEditor::OnImfEvent );
+  }
+
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+
+  if ( notifier )
+  {
+    notifier.ContentSelectedSignal().Disconnect( this, &TextEditor::OnClipboardTextSelected );
+  }
+
+  mController->KeyboardFocusLostEvent();
+
+  EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
+}
+
+void TextEditor::OnTap( const TapGesture& gesture )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
+
+  // Show the keyboard if it was hidden.
+  if (!VirtualKeyboard::IsVisible())
+  {
+    VirtualKeyboard::Show();
+  }
+
+  // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
+  mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
+
+  SetKeyInputFocus();
+}
+
+void TextEditor::OnPan( const PanGesture& gesture )
+{
+  mController->PanEvent( gesture.state, gesture.displacement );
+}
+
+void TextEditor::OnLongPress( const LongPressGesture& gesture )
+{
+  // Show the keyboard if it was hidden.
+  if (!VirtualKeyboard::IsVisible())
+  {
+    VirtualKeyboard::Show();
+  }
+
+  mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
+
+  SetKeyInputFocus();
+}
+
+bool TextEditor::OnKeyEvent( const KeyEvent& event )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
+
+  if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+  {
+    ClearKeyInputFocus();
+    return true;
+  }
+
+  return mController->KeyEvent( event );
+}
+
+void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
+{
+  if( actor )
+  {
+    if( needsClipping )
+    {
+      mClippingDecorationActors.push_back( actor );
+    }
+    else
+    {
+      Self().Add( actor );
+    }
+  }
+}
+
+void TextEditor::RequestTextRelayout()
+{
+  RelayoutRequest();
+}
+
+void TextEditor::TextChanged()
+{
+  Dali::Toolkit::TextEditor handle( GetOwner() );
+  mTextChangedSignal.Emit( handle );
+}
+
+void TextEditor::MaxLengthReached()
+{
+  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+}
+
+void TextEditor::OnStageConnect( Dali::Actor actor )
+{
+  if ( mHasBeenStaged )
+  {
+    RenderText();
+  }
+  else
+  {
+    mHasBeenStaged = true;
+  }
+}
+
+ImfManager::ImfCallbackData TextEditor::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
+  return mController->OnImfEvent( imfManager, imfEvent );
+}
+
+void TextEditor::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
+{
+  if( mDecorator )
+  {
+    ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
+
+    if ( image )
+    {
+      Property::Map map;
+      Scripting::CreatePropertyMap( image, map );
+      value = map;
+    }
+  }
+}
+
+void TextEditor::EnableClipping( bool clipping, const Vector2& size )
+{
+  if( clipping )
+  {
+    // Not worth to created clip actor if width or height is equal to zero.
+    if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
+    {
+      if( !mClipper )
+      {
+        Actor self = Self();
+
+        mClipper = Clipper::New( size );
+        self.Add( mClipper->GetRootActor() );
+        self.Add( mClipper->GetImageActor() );
+      }
+      else if ( mClipper )
+      {
+        mClipper->Refresh( size );
+      }
+    }
+  }
+  else
+  {
+    // Note - this will automatically remove the root & image actors
+    mClipper.Reset();
+  }
+}
+
+void TextEditor::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
+{
+  mController->PasteClipboardItemEvent();
+}
+
+void TextEditor::KeyboardStatusChanged(bool keyboardShown)
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
+
+  // Just hide the grab handle when keyboard is hidden.
+  if (!keyboardShown )
+  {
+    mController->KeyboardFocusLostEvent();
+  }
+  else
+  {
+    mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
+  }
+}
+
+void TextEditor::OnStageConnection( int depth )
+{
+  // Call the Control::OnStageConnection() to set the depth of the background.
+  Control::OnStageConnection( depth );
+
+  // Sets the depth to the renderers inside the text's decorator.
+  mDecorator->SetTextDepth( depth );
+
+  // The depth of the text renderer is set in the RenderText() called from OnRelayout().
+}
+
+bool TextEditor::OnTouched( Actor actor, const TouchEvent& event )
+{
+  return true;
+}
+
+TextEditor::TextEditor()
+: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+  mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
+  mHasBeenStaged( false )
+{
+}
+
+TextEditor::~TextEditor()
+{
+  mClipper.Reset();
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h
new file mode 100644 (file)
index 0000000..b10b78b
--- /dev/null
@@ -0,0 +1,283 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+
+/*
+ * Copyright (c) 2016 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/public-api/controls/control-impl.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-editor.h>
+#include <dali-toolkit/internal/text/clipping/text-clipper.h>
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief A control which renders a long text string with styles.
+ */
+class TextEditor : public Control, public Text::ControlInterface
+{
+public:
+
+  /**
+   * @copydoc Dali::Toollkit::TextEditor::New()
+   */
+  static Toolkit::TextEditor New();
+
+  // Properties
+
+  /**
+   * @brief Called when a property of an object of this type is set.
+   *
+   * @param[in] object The object whose property is set.
+   * @param[in] index The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+  /**
+   * @brief Called to retrieve a property of an object of this type.
+   *
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] index The property index.
+   * @return The current value of the property.
+   */
+  static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
+  /**
+   * Connects a callback function with the object's signals.
+   * @param[in] object The object providing the signal.
+   * @param[in] tracker Used to disconnect the signal.
+   * @param[in] signalName The signal to connect to.
+   * @param[in] functor A newly allocated FunctorDelegate.
+   * @return True if the signal was connected.
+   * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+   */
+  static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+
+  /**
+   * @copydoc TextEditor::TextChangedSignal()
+   */
+  Toolkit::TextEditor::TextChangedSignalType&  TextChangedSignal();
+
+private: // From Control
+
+  /**
+   * @copydoc Control::OnInitialize()
+   */
+  virtual void OnInitialize();
+
+  /**
+   * @copydoc Control::OnStyleChange()
+   */
+  virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change );
+
+  /**
+   * @copydoc Control::GetNaturalSize()
+   */
+  virtual Vector3 GetNaturalSize();
+
+  /**
+   * @copydoc Control::GetHeightForWidth()
+   */
+  virtual float GetHeightForWidth( float width );
+
+  /**
+   * @copydoc Control::OnInitialize()
+   */
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
+
+  /**
+   * @copydoc Control::OnKeyInputFocusGained()
+   */
+  virtual void OnKeyInputFocusGained();
+
+  /**
+   * @copydoc Control::OnKeyInputFocusLost()
+   */
+  virtual void OnKeyInputFocusLost();
+
+  /**
+   * @copydoc Control::OnTap()
+   */
+  virtual void OnTap( const TapGesture& tap );
+
+  /**
+   * @copydoc Control::OnPan()
+   */
+  virtual void OnPan( const PanGesture& gesture );
+
+  /**
+   * @copydoc Control::OnLongPress()
+   */
+  virtual void OnLongPress( const LongPressGesture& gesture );
+
+  /**
+   * @copydoc Control::OnStageConnection()
+   */
+  virtual void OnStageConnection( int depth );
+
+  /**
+   * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
+   */
+  virtual bool OnKeyEvent(const KeyEvent& event);
+
+// From ControlInterface
+
+  /**
+   * @copydoc Text::ControlInterface::AddDecoration()
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping );
+
+  /**
+   * @copydoc Text::ControlInterface::RequestTextRelayout()
+   */
+  virtual void RequestTextRelayout();
+
+  /**
+   * @copydoc Text::ControlInterface::TextChanged()
+   */
+  virtual void TextChanged();
+
+  /**
+   * @copydoc Text::ControlInterface::MaxLengthReached()
+   */
+  virtual void MaxLengthReached();
+
+private: // Implementation
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+   */
+  ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+
+  /**
+   * @brief Callback when Clipboard signals an item should be pasted
+   * @param[in] clipboard handle to Clipboard Event Notifier
+   */
+  void OnClipboardTextSelected( ClipboardEventNotifier& clipboard );
+
+  /**
+   * @brief Get a Property Map for the image used for the required Handle Image
+   * @param[out] value the returned image property
+   * @param[in] handleType the type of handle
+   * @param[in] handleImageType the type of image for the given handleType
+   */
+  void GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType );
+
+  /**
+   * @brief Enable or disable clipping.
+   *
+   * @param[in] clipping True if clipping should be enabled.
+   * @param[in] size The area to clip within.
+   */
+  void EnableClipping( bool clipping, const Vector2& size );
+
+  /**
+   * @brief Callback when keyboard is shown/hidden.
+   *
+   * @param[in] keyboardShown True if keyboard is shown.
+   */
+  void KeyboardStatusChanged( bool keyboardShown );
+
+  /**
+   * @brief Callback when TextEditor is touched
+   *
+   * @param[in] actor TextEditor touched
+   * @param[in] event TouchEvent information
+   */
+  bool OnTouched( Actor actor, const TouchEvent& event );
+
+  /**
+   * Construct a new TextEditor.
+   */
+  TextEditor();
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~TextEditor();
+
+  // Undefined copy constructor and assignment operators
+  TextEditor(const TextEditor&);
+  TextEditor& operator=(const TextEditor& rhs);
+
+  /**
+   * @brief Render view, create and attach actor(s) to this text editor.
+   */
+  void RenderText();
+
+  // Connection needed to re-render text, when a text editor returns to the stage.
+  void OnStageConnect( Dali::Actor actor );
+
+private: // Data
+
+  // Signals
+  Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal;
+
+  Text::ControllerPtr mController;
+  Text::RendererPtr mRenderer;
+  Text::DecoratorPtr mDecorator;
+  Text::ClipperPtr mClipper;
+  std::vector<Actor> mClippingDecorationActors;   ///< Decoration actors which need clipping.
+
+  Actor mRenderableActor;
+
+  int mRenderingBackend;
+  bool mHasBeenStaged:1;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::TextEditor& GetImpl( Toolkit::TextEditor& textEditor )
+{
+  DALI_ASSERT_ALWAYS(textEditor);
+
+  Dali::RefObject& handle = textEditor.GetImplementation();
+
+  return static_cast<Toolkit::Internal::TextEditor&>(handle);
+}
+
+inline const Toolkit::Internal::TextEditor& GetImpl( const Toolkit::TextEditor& textEditor )
+{
+  DALI_ASSERT_ALWAYS(textEditor);
+
+  const Dali::RefObject& handle = textEditor.GetImplementation();
+
+  return static_cast<const Toolkit::Internal::TextEditor&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
index 8a59577..91d757b 100644 (file)
@@ -154,6 +154,8 @@ private: // From Control
    */
   virtual bool OnKeyEvent(const KeyEvent& event);
 
+// From ControlInterface
+
   /**
    * @copydoc Text::ControlInterface::AddDecoration()
    */
@@ -174,6 +176,8 @@ private: // From Control
    */
   virtual void MaxLengthReached();
 
+private: // Implementation
+
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
    */
@@ -185,8 +189,6 @@ private: // From Control
    */
   void OnClipboardTextSelected( ClipboardEventNotifier& clipboard );
 
-private: // Implementation
-
   /**
    * @brief Get a Property Map for the image used for the required Handle Image
    * @param[out] value the returned image property
@@ -211,7 +213,7 @@ private: // Implementation
   void KeyboardStatusChanged( bool keyboardShown );
 
   /**
-   * @brief Callback when Textfield is touched
+   * @brief Callback when TextField is touched
    *
    * @param[in] actor TextField touched
    * @param[in] event TouchEvent information
index 345c107..96501dd 100644 (file)
@@ -60,6 +60,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/controls/slider/slider-impl.cpp \
    $(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \
    $(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \
+   $(toolkit_src_dir)/controls/text-controls/text-editor-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
index 2861611..85aa069 100644 (file)
@@ -101,7 +101,6 @@ StyleManager::StyleManager()
 : mOrientationDegrees( 0 ),  // Portrait
   mDefaultFontSize( -1 ),
   mDefaultFontFamily(""),
-  mThemeFile( DEFAULT_THEME ),
   mFeedbackStyle( NULL )
 {
   // Add theme builder constants
@@ -117,7 +116,6 @@ StyleManager::StyleManager()
 
   // Sound & haptic style
   mFeedbackStyle = new FeedbackStyle();
-
 }
 
 StyleManager::~StyleManager()
@@ -132,7 +130,7 @@ void StyleManager::SetOrientationValue( int orientation )
     mOrientationDegrees = orientation;
     // TODO: if orientation changed, apply the new style to all controls
     // dont want to really do the whole load from file again if the bundle contains both portrait & landscape
-    SetTheme();
+    SetTheme( mThemeFile );
   }
 }
 
@@ -156,14 +154,14 @@ void StyleManager::SetOrientation( Orientation orientation )
   }
 }
 
-std::string StyleManager::GetDefaultFontFamily() const
+Orientation StyleManager::GetOrientation()
 {
-  return mDefaultFontFamily;
+  return mOrientation;
 }
 
-Orientation StyleManager::GetOrientation()
+std::string StyleManager::GetDefaultFontFamily() const
 {
-  return mOrientation;
+  return mDefaultFontFamily;
 }
 
 void StyleManager::SetStyleConstant( const std::string& key, const Property::Value& value )
@@ -183,12 +181,120 @@ bool StyleManager::GetStyleConstant( const std::string& key, Property::Value& va
   return false;
 }
 
-void StyleManager::OnOrientationChanged( Orientation orientation )
+void StyleManager::RequestThemeChange( const std::string& themeFile )
 {
-  mOrientation = orientation;
-  // TODO: if orientation changed, apply the new style to all controls
-  // dont want to really do the whole load from file again if the bundle contains both portrait & landscape
-  SetTheme();
+  SetTheme( themeFile );
+}
+
+void StyleManager::RequestDefaultTheme()
+{
+  std::string empty;
+  SetTheme( empty );
+}
+
+void StyleManager::ApplyThemeStyle( Toolkit::Control control )
+{
+  if( !mThemeBuilder )
+  {
+    RequestDefaultTheme();
+  }
+
+  if( mThemeBuilder )
+  {
+    ApplyStyle( mThemeBuilder, control );
+  }
+}
+
+void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
+{
+  ApplyThemeStyle( control );
+
+  if(mFeedbackStyle)
+  {
+    mFeedbackStyle->ObjectCreated( control );
+  }
+}
+
+void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
+{
+  bool builderReady = false;
+
+  // First look in the cache
+  Toolkit::Builder builder = FindCachedBuilder( jsonFileName );
+  if( builder )
+  {
+    builderReady = true;
+  }
+  else
+  {
+    // Merge theme and style constants
+    Property::Map constants( mThemeBuilderConstants );
+    constants.Merge( mStyleBuilderConstants );
+
+    // Create it
+    builder = CreateBuilder( constants );
+
+    if( LoadJSON( builder, jsonFileName ) )
+    {
+      CacheBuilder( builder, jsonFileName );
+      builderReady = true;
+    }
+  }
+
+  // Apply the style to the control
+  if( builderReady )
+  {
+    builder.ApplyStyle( styleName, control );
+  }
+}
+
+Toolkit::StyleManager::StyleChangeSignalType& StyleManager::StyleChangeSignal()
+{
+  return mStyleChangeSignal;
+}
+
+void StyleManager::SetTheme( const std::string& themeFile )
+{
+  bool themeLoaded = false;
+
+  mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
+
+  // Always load the default theme first, then merge in the custom theme if present
+  themeLoaded = LoadJSON( mThemeBuilder, DEFAULT_THEME );
+
+  if( ! themeFile.empty() )
+  {
+    mThemeFile = themeFile;
+    themeLoaded = LoadJSON( mThemeBuilder, mThemeFile );
+  }
+
+  if( themeLoaded )
+  {
+    if(mFeedbackStyle)
+    {
+      mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
+    }
+
+    mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
+  }
+  else
+  {
+    mThemeBuilder.Reset();
+  }
+}
+
+bool StyleManager::LoadFile( const std::string& filename, std::string& stringOut )
+{
+  DALI_ASSERT_DEBUG( 0 != filename.length());
+
+  // as toolkit is platform agnostic, it cannot load files from filesystem
+  // ask style monitor to load the style sheet
+  if( mStyleMonitor )
+  {
+    return mStyleMonitor.LoadThemeFile( filename, stringOut );
+  }
+
+  return false;
 }
 
 Toolkit::Builder StyleManager::CreateBuilder( const Property::Map& constants )
@@ -294,112 +400,14 @@ void StyleManager::ApplyStyle( Toolkit::Builder builder, Toolkit::Control contro
   }
 }
 
-void StyleManager::ApplyThemeStyle( Toolkit::Control control )
-{
-  if( !mThemeBuilder )
-  {
-    RequestDefaultTheme();
-  }
-
-  if( mThemeBuilder )
-  {
-    ApplyStyle( mThemeBuilder, control );
-  }
-}
-
-void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
-{
-  ApplyThemeStyle( control );
-
-  if(mFeedbackStyle)
-  {
-    mFeedbackStyle->ObjectCreated( control );
-  }
-}
-
-void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
-{
-  bool builderReady = false;
-
-  // First look in the cache
-  Toolkit::Builder builder = FindCachedBuilder( jsonFileName );
-  if( builder )
-  {
-    builderReady = true;
-  }
-  else
-  {
-    // Merge theme and style constants
-    Property::Map constants( mThemeBuilderConstants );
-    constants.Merge( mStyleBuilderConstants );
-
-    // Create it
-    builder = CreateBuilder( constants );
-
-    if( LoadJSON( builder, jsonFileName ) )
-    {
-      CacheBuilder( builder, jsonFileName );
-      builderReady = true;
-    }
-  }
-
-  // Apply the style to the control
-  if( builderReady )
-  {
-    builder.ApplyStyle( styleName, control );
-  }
-}
-
-bool StyleManager::LoadFile( const std::string& filename, std::string& stringOut )
-{
-  DALI_ASSERT_DEBUG( 0 != filename.length());
-
-  // as toolkit is platform agnostic, it cannot load files from filesystem
-  // ask style monitor to load the style sheet
-  if( mStyleMonitor )
-  {
-    return mStyleMonitor.LoadThemeFile( filename, stringOut );
-  }
-
-  return false;
-}
-
-Toolkit::StyleManager::StyleChangeSignalType& StyleManager::StyleChangeSignal()
-{
-  return mStyleChangeSignal;
-}
-
-void StyleManager::RequestThemeChange( const std::string& themeFile )
-{
-  mThemeFile = themeFile;
-
-  // need to do style change synchronously as app might create a UI control on the next line
-  SetTheme();
-}
-
-void StyleManager::RequestDefaultTheme()
+void StyleManager::OnOrientationChanged( Orientation orientation )
 {
-  RequestThemeChange( DEFAULT_THEME );
+  mOrientation = orientation;
+  // TODO: if orientation changed, apply the new style to all controls
+  // dont want to really do the whole load from file again if the bundle contains both portrait & landscape
+  SetTheme( mThemeFile );
 }
 
-void StyleManager::SetTheme()
-{
-  mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
-
-  if( LoadJSON( mThemeBuilder, mThemeFile ) )
-  {
-    if(mFeedbackStyle)
-    {
-      mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
-    }
-
-    mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
-  }
-  else
-  {
-    mThemeBuilder.Reset();
-  }
-}
 
 Toolkit::Builder StyleManager::FindCachedBuilder( const std::string& key )
 {
@@ -435,17 +443,7 @@ void StyleManager::StyleMonitorChange( StyleMonitor styleMonitor, StyleChange::T
 
     case StyleChange::THEME_CHANGE:
     {
-      const std::string& newTheme = styleMonitor.GetTheme();
-      if( ! newTheme.empty() )
-      {
-        mThemeFile = newTheme;
-      }
-      else
-      {
-        mThemeFile = DEFAULT_THEME;
-      }
-
-      SetTheme();
+      SetTheme( styleMonitor.GetTheme() );
       break;
     }
   }
index ab5e24d..294e601 100644 (file)
@@ -47,7 +47,6 @@ class FeedbackStyle;
 class StyleManager : public Dali::BaseObject, public ConnectionTracker
 {
 public:
-
   /**
    * Singleton access
    *
@@ -60,6 +59,14 @@ public:
    */
   StyleManager();
 
+protected:
+  /**
+   * @brief Destructor
+   */
+  virtual ~StyleManager();
+
+public: // Public API
+
   /**
    * @copydoc Toolkit::StyleManager::SetOrientationValue
    */
@@ -106,12 +113,6 @@ public:
   void RequestDefaultTheme();
 
   /**
-   * Determine if a theme change has been requested
-   * @return Whether a theme request is pending
-   */
-  bool IsThemeRequestPending();
-
-  /**
    * @brief Apply the theme style to a control.
    *
    * @param[in] control The control to apply style.
@@ -138,24 +139,14 @@ public:
    */
   Toolkit::StyleManager::StyleChangeSignalType& StyleChangeSignal();
 
-protected:
-
-  /**
-   * @brief Destructor
-   */
-  virtual ~StyleManager();
-
-
-public:
+private:
+  typedef std::vector<std::string> StringList;
 
   /**
    * @brief Set the current theme. Called only once per event processing cycle.
+   * @param[in] themeFile The name of the theme file to read.
    */
-  void SetTheme();
-
-private:
-
-  typedef std::vector<std::string> StringList;
+  void SetTheme( const std::string& themeFile );
 
   /**
    * @brief Internal helper method to read a file from file system.
@@ -258,9 +249,7 @@ private:
   int mOrientationDegrees;            ///< Directly set value of orientation
 
   int mDefaultFontSize;               ///< Logical size, not a point-size
-
   std::string mDefaultFontFamily;
-
   std::string mThemeFile;             ///< The full path of the current theme file
 
   Property::Map mThemeBuilderConstants;   ///< Contants to give the theme builder
@@ -299,4 +288,3 @@ inline const Internal::StyleManager& GetImpl( const Dali::Toolkit::StyleManager&
 } // namespace Dali
 
 #endif // __DALI_TOOLKIT_INTERNAL_STYLE_MANAGER_H__
-
index fc3328d..bc27da3 100644 (file)
@@ -659,43 +659,47 @@ struct Decorator::Impl : public ConnectionTracker
     HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
     if( !grabHandle.actor )
     {
-      grabHandle.actor = ImageView::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
-      GetImpl( grabHandle.actor).SetDepthIndex( DepthIndex::DECORATION );
-      grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-      // Area that Grab handle responds to, larger than actual handle so easier to move
-#ifdef DECORATOR_DEBUG
-      grabHandle.actor.SetName( "GrabHandleActor" );
-      if ( Dali::Internal::gLogFilter->IsEnabledFor( Debug::Verbose ) )
-      {
-        grabHandle.grabArea = Control::New();
-        Toolkit::Control control = Toolkit::Control::DownCast( grabHandle.grabArea );
-        control.SetBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) );
-        grabHandle.grabArea.SetName( "GrabArea" );
-      }
-      else
+      if( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] )
       {
-        grabHandle.grabArea = Actor::New();
-        grabHandle.grabArea.SetName( "GrabArea" );
-      }
+        grabHandle.actor = ImageView::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
+        GetImpl( grabHandle.actor).SetDepthIndex( DepthIndex::DECORATION );
+        grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+
+        // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+        grabHandle.actor.SetName( "GrabHandleActor" );
+        if ( Dali::Internal::gLogFilter->IsEnabledFor( Debug::Verbose ) )
+        {
+          grabHandle.grabArea = Control::New();
+          Toolkit::Control control = Toolkit::Control::DownCast( grabHandle.grabArea );
+          control.SetBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) );
+          grabHandle.grabArea.SetName( "GrabArea" );
+        }
+        else
+        {
+          grabHandle.grabArea = Actor::New();
+          grabHandle.grabArea.SetName( "GrabArea" );
+        }
 #else
-      grabHandle.grabArea = Actor::New();
+        grabHandle.grabArea = Actor::New();
 #endif
 
-      grabHandle.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
-      grabHandle.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-      grabHandle.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
-      grabHandle.grabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
-      grabHandle.actor.Add( grabHandle.grabArea );
-      grabHandle.actor.SetColor( mHandleColor );
+        grabHandle.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+        grabHandle.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+        grabHandle.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+        grabHandle.grabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
+        grabHandle.actor.Add( grabHandle.grabArea );
+        grabHandle.actor.SetColor( mHandleColor );
 
-      grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
-      mTapDetector.Attach( grabHandle.grabArea );
-      mPanGestureDetector.Attach( grabHandle.grabArea );
+        grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
+        mTapDetector.Attach( grabHandle.grabArea );
+        mPanGestureDetector.Attach( grabHandle.grabArea );
 
-      mActiveLayer.Add( grabHandle.actor );
+        mActiveLayer.Add( grabHandle.actor );
+      }
     }
 
-    if( !grabHandle.actor.GetParent() )
+    if( grabHandle.actor && !grabHandle.actor.GetParent() )
     {
       mActiveLayer.Add( grabHandle.actor );
     }
@@ -729,33 +733,36 @@ struct Decorator::Impl : public ConnectionTracker
     HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ];
     if( !primary.actor )
     {
-      primary.actor = ImageView::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
+      if( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
+      {
+        primary.actor = ImageView::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
 #ifdef DECORATOR_DEBUG
-      primary.actor.SetName("SelectionHandleOne");
+        primary.actor.SetName("SelectionHandleOne");
 #endif
-      primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
-      GetImpl( primary.actor ).SetDepthIndex( DepthIndex::DECORATION );
-      primary.actor.SetColor( mHandleColor );
+        primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
+        GetImpl( primary.actor ).SetDepthIndex( DepthIndex::DECORATION );
+        primary.actor.SetColor( mHandleColor );
 
-      primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+        primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
 #ifdef DECORATOR_DEBUG
-      primary.grabArea.SetName("SelectionHandleOneGrabArea");
+        primary.grabArea.SetName("SelectionHandleOneGrabArea");
 #endif
-      primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
-      primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
-      primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-      primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+        primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+        primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+        primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+        primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
 
-      mTapDetector.Attach( primary.grabArea );
-      mPanGestureDetector.Attach( primary.grabArea );
-      primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+        mTapDetector.Attach( primary.grabArea );
+        mPanGestureDetector.Attach( primary.grabArea );
+        primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
 
-      primary.actor.Add( primary.grabArea );
+        primary.actor.Add( primary.grabArea );
 
-      CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
+        CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
+      }
     }
 
-    if( !primary.actor.GetParent() )
+    if( primary.actor && !primary.actor.GetParent() )
     {
       mActiveLayer.Add( primary.actor );
     }
@@ -763,33 +770,36 @@ struct Decorator::Impl : public ConnectionTracker
     HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
     if( !secondary.actor )
     {
-      secondary.actor = ImageView::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
+      if( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
+      {
+        secondary.actor = ImageView::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
 #ifdef DECORATOR_DEBUG
-      secondary.actor.SetName("SelectionHandleTwo");
+        secondary.actor.SetName("SelectionHandleTwo");
 #endif
-      secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
-      GetImpl( secondary.actor ).SetDepthIndex( DepthIndex::DECORATION );
-      secondary.actor.SetColor( mHandleColor );
+        secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
+        GetImpl( secondary.actor ).SetDepthIndex( DepthIndex::DECORATION );
+        secondary.actor.SetColor( mHandleColor );
 
-      secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+        secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
 #ifdef DECORATOR_DEBUG
-      secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
+        secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
 #endif
-      secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
-      secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
-      secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-      secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+        secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+        secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+        secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+        secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
 
-      mTapDetector.Attach( secondary.grabArea );
-      mPanGestureDetector.Attach( secondary.grabArea );
-      secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+        mTapDetector.Attach( secondary.grabArea );
+        mPanGestureDetector.Attach( secondary.grabArea );
+        secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
 
-      secondary.actor.Add( secondary.grabArea );
+        secondary.actor.Add( secondary.grabArea );
 
-      CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE  );
+        CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE  );
+      }
     }
 
-    if( !secondary.actor.GetParent() )
+    if( secondary.actor && !secondary.actor.GetParent() )
     {
       mActiveLayer.Add( secondary.actor );
     }
@@ -834,8 +844,11 @@ struct Decorator::Impl : public ConnectionTracker
     // The SetGrabHandleImage() method will change the orientation.
     const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight;
 
-    grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
-                                  yLocalPosition ); // TODO : Fix for multiline.
+    if( grabHandle.actor )
+    {
+      grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
+                                    yLocalPosition ); // TODO : Fix for multiline.
+    }
   }
 
   void SetSelectionHandlePosition( HandleType type )
@@ -891,7 +904,7 @@ struct Decorator::Impl : public ConnectionTracker
 
     if( flipHandle )
     {
-      if( !handle.horizontallyFlipped )
+      if( handle.actor && !handle.horizontallyFlipped )
       {
         // Change the anchor point to flip the image.
         handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT );
@@ -901,7 +914,7 @@ struct Decorator::Impl : public ConnectionTracker
     }
     else
     {
-      if( handle.horizontallyFlipped )
+      if( handle.actor && handle.horizontallyFlipped )
       {
         // Reset the anchor point.
         handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT );
@@ -921,8 +934,11 @@ struct Decorator::Impl : public ConnectionTracker
     // The SetHandleImage() method will change the orientation.
     const float yLocalPosition = handle.verticallyFlipped ? handle.position.y : handle.position.y + handle.lineHeight;
 
-    handle.actor.SetPosition( handle.position.x,
-                              yLocalPosition ); // TODO : Fix for multiline.
+    if( handle.actor )
+    {
+      handle.actor.SetPosition( handle.position.x,
+                                yLocalPosition ); // TODO : Fix for multiline.
+    }
   }
 
   void SetHandleImage( HandleType type )
@@ -1144,7 +1160,10 @@ struct Decorator::Impl : public ConnectionTracker
         mController.DecorationEvent( type, HANDLE_RELEASED, x, y );
       }
 
-      handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+      if( handle.actor )
+      {
+        handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+      }
       handle.pressed = false;
 
       mHandlePanning = false;
index 0a90ef2..c8ea1e2 100644 (file)
@@ -48,6 +48,7 @@ void main()
 );
 
 const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
+uniform lowp    vec4      uColor;
 uniform         sampler2D sTexture;
 varying mediump vec2      vTexCoord;
 varying mediump vec4      vColor;
@@ -55,7 +56,7 @@ varying mediump vec4      vColor;
 void main()
 {
   mediump vec4 color = texture2D( sTexture, vTexCoord );
-  gl_FragColor = vec4( vColor.rgb, vColor.a * color.r );
+  gl_FragColor = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a * color.r );
 }
 );
 
index 3143603..8a500f7 100644 (file)
@@ -282,12 +282,9 @@ void Controller::GetPlaceholderText( PlaceholderType type, std::string& text ) c
   }
 }
 
-void Controller::SetMaximumNumberOfCharacters( int maxCharacters )
+void Controller::SetMaximumNumberOfCharacters( Length maxCharacters )
 {
-  if( maxCharacters >= 0 )
-  {
-    mImpl->mMaximumNumberOfCharacters = maxCharacters;
-  }
+  mImpl->mMaximumNumberOfCharacters = maxCharacters;
 }
 
 int Controller::GetMaximumNumberOfCharacters()
index a9cc0df..d239d13 100644 (file)
@@ -184,7 +184,7 @@ public:
    *
    * @param[in] maxCharacters maximum number of characters to be accepted
    */
-  void SetMaximumNumberOfCharacters( int maxCharacters );
+  void SetMaximumNumberOfCharacters( Length maxCharacters );
 
   /**
    * @brief Sets the maximum number of characters that can be inserted into the TextModel
index efbc884..898fd3f 100644 (file)
@@ -52,7 +52,10 @@ public:
   enum PropertyRange
   {
     PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
-    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000              ///< Reserve property indices
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,              ///< Reserve property indices
+
+    ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,        ///< @since DALi 1.1.18
+    ANIMATABLE_PROPERTY_END_INDEX =   ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000  ///< Reserve animatable property indices, @since DALi 1.1.18
   };
 
   /**
@@ -62,8 +65,13 @@ public:
   {
     enum
     {
+      // Event side properties
       RESOURCE_URL = PROPERTY_START_INDEX, ///< name "resourceUrl",  @deprecated DALi 1.1.16 Use IMAGE instead.  type string
       IMAGE,                               ///< name "image",        @see SetImage(),                            type string if it is a url, map otherwise
+      PRE_MULTIPLIED_ALPHA,                ///< name "preMultipliedAlpha", @since DALi 1.1.18                    type Boolean @pre image must be initialized.
+
+      // Animatable properties
+      PIXEL_AREA = ANIMATABLE_PROPERTY_START_INDEX,  ///< name "pixelArea", @since DALi 1.1.18                   type Vector4, Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].
     };
   };
 
index e790a82..0bb0d1b 100644 (file)
@@ -63,6 +63,9 @@ public:
 
   enum PropertyRange
   {
+    PROPERTY_START_INDEX = Toolkit::Scrollable::PROPERTY_END_INDEX + 1,                        ///< @since DALi 1.1.18
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,                                        ///< Reserve property indices, @since DALi 1.1.18
+
     ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
     ANIMATABLE_PROPERTY_END_INDEX   = ANIMATABLE_PROPERTY_START_INDEX + 1000                   ///< Reserve animatable property indices
   };
@@ -74,12 +77,20 @@ public:
   {
     enum
     {
-      LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition",        type float
-      SCROLL_SPEED,                                      ///< Property, name "scrollSpeed",           type float
-      OVERSHOOT,                                         ///< Property, name "overshoot",             type float
-      SCROLL_DIRECTION,                                  ///< Property, name "scrollDirection",       type Vector2
-      LAYOUT_ORIENTATION,                                ///< Property, name "layoutOrientation",     type integer
-      SCROLL_CONTENT_SIZE                                ///< Property, name "scrollContentSize",     type float
+      // Event side properties
+      MINIMUM_SWIPE_SPEED = PROPERTY_START_INDEX,        ///< Property, name "minimumSwipeSpeed",        @see SetMinimumSwipeSpeed(),       type float,    @since DALi 1.1.18
+      MINIMUM_SWIPE_DISTANCE,                            ///< Property, name "minimumSwipeDistance",     @see SetMinimumSwipeDistance(),    type float,    @since DALi 1.1.18
+      WHEEL_SCROLL_DISTANCE_STEP,                        ///< Property, name "wheelScrollDistanceStep",  @see SetWheelScrollDistanceStep(), type float,    @since DALi 1.1.18
+      SNAP_TO_ITEM_ENABLED,                              ///< Property, name "snapToItemEnabled",        @see SetAnchoring(),               type bool,     @since DALi 1.1.18
+      REFRESH_INTERVAL,                                  ///< Property, name "refreshInterval",          @see SetRefreshInterval(),         type float,    @since DALi 1.1.18
+
+      // Animatable properties
+      LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition",           type float
+      SCROLL_SPEED,                                      ///< Property, name "scrollSpeed",              type float
+      OVERSHOOT,                                         ///< Property, name "overshoot",                type float
+      SCROLL_DIRECTION,                                  ///< Property, name "scrollDirection",          type Vector2
+      LAYOUT_ORIENTATION,                                ///< Property, name "layoutOrientation",        type integer
+      SCROLL_CONTENT_SIZE                                ///< Property, name "scrollContentSize",        type float
     };
   };
 
index 9a66cfc..0e656d4 100644 (file)
@@ -448,6 +448,9 @@ public:
    */
   enum PropertyRange
   {
+    PROPERTY_START_INDEX = Toolkit::Scrollable::PROPERTY_END_INDEX + 1,                        ///< @since DALi 1.1.18
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,                                        ///< Reserve property indices, @since DALi 1.1.18
+
     ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
     ANIMATABLE_PROPERTY_END_INDEX   = ANIMATABLE_PROPERTY_START_INDEX + 1000                   ///< Reserve animatable property indices
   };
@@ -459,6 +462,12 @@ public:
   {
     enum
     {
+      // Event side properties
+      WRAP_ENABLED = PROPERTY_START_INDEX,               ///< Property, name "wrapEnabled",              @see SetWrapMode(),                 type bool,     @since DALi 1.1.18
+      PANNING_ENABLED,                                   ///< Property, name "panningEnabled",           @see SetScrollSensitive(),          type bool,     @since DALi 1.1.18
+      AXIS_AUTO_LOCK_ENABLED,                            ///< Property, name "axisAutoLockEnabled",      @see SetAxisAutoLock(),             type bool,     @since DALi 1.1.18
+      WHEEL_SCROLL_DISTANCE_STEP,                        ///< Property, name "wheelScrollDistanceStep",  @see SetWheelScrollDistanceStep(),  type Vector2,  @since DALi 1.1.18
+
       SCROLL_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollPosition",            type Vector2
       SCROLL_PRE_POSITION,                               ///< Property, name "scrollPrePosition",         type Vector2
       SCROLL_PRE_POSITION_X,                             ///< Property, name "scrollPrePositionX",        type float
index 76dbb07..c14f203 100644 (file)
@@ -75,6 +75,7 @@ public:
       // Event side properties
       OVERSHOOT_EFFECT_COLOR = PROPERTY_START_INDEX, ///< Property, name "overshootEffectColor",      @see SetOvershootEffectColor(),    type Vector4
       OVERSHOOT_ANIMATION_SPEED,                     ///< Property, name "overshootAnimationSpeed",   @see SetOvershootAnimationSpeed(), type float
+      OVERSHOOT_ENABLED,                             ///< Property, name "overshootEnabled",          @see SetOvershootEnabled(),        type bool,    @since DALi 1.1.18
 
       // Animatable properties
       SCROLL_RELATIVE_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollRelativePosition",   type Vector2
index f2205f5..1ada2cd 100644 (file)
@@ -60,51 +60,51 @@ public:
   };
 
   /**
-   * @brief An enumeration of properties belonging to the TextLabel class.
+   * @brief An enumeration of properties belonging to the TextField class.
    */
   struct Property
   {
     enum
     {
-      RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend",                    The type or rendering e.g. bitmap-based,                                  type INT
-      TEXT,                                     ///< name "text",                                The text to display in UTF-8 format,                                      type STRING
-      PLACEHOLDER_TEXT,                         ///< name "placeholderText",                     The text to display when the TextField is empty and inactive,             type STRING
-      PLACEHOLDER_TEXT_FOCUSED,                 ///< name "placeholderTextFocused",              The text to display when the TextField is empty with key-input focus,     type STRING
-      FONT_FAMILY,                              ///< name "fontFamily",                          The requested font family,                                                type STRING
-      FONT_STYLE,                               ///< name "fontStyle",                           The requested font style,                                                 type STRING
-      POINT_SIZE,                               ///< name "pointSize",                           The size of font in points,                                               type FLOAT
-      MAX_LENGTH,                               ///< name "maxLength"                            The maximum number of characters that can be inserted,                    type INTEGER
-      EXCEED_POLICY,                            ///< name "exceedPolicy"                         Specifies how the text is truncated when it does not fit,                 type INTEGER
-      HORIZONTAL_ALIGNMENT,                     ///< name "horizontalAlignment",                 The line horizontal alignment,                                            type STRING,  values "BEGIN", "CENTER", "END"
-      VERTICAL_ALIGNMENT,                       ///< name "verticalAlignment",                   The line vertical alignment,                                              type STRING,  values "TOP",   "CENTER", "BOTTOM"
-      TEXT_COLOR,                               ///< name "textColor",                           The text color,                                                           type VECTOR4
-      PLACEHOLDER_TEXT_COLOR,                   ///< name "placeholderTextColor",                The placeholder-text color,                                               type VECTOR4
-      SHADOW_OFFSET,                            ///< name "shadowOffset",                        The drop shadow offset 0 indicates no shadow,                             type VECTOR2
-      SHADOW_COLOR,                             ///< name "shadowColor",                         The color of a drop shadow,                                               type VECTOR4
-      PRIMARY_CURSOR_COLOR,                     ///< name "primaryCursorColor",                  The color to apply to the primary cursor,                                 type VECTOR4
-      SECONDARY_CURSOR_COLOR,                   ///< name "secondaryCursorColor",                The color to apply to the secondary cursor,                               type VECTOR4
-      ENABLE_CURSOR_BLINK,                      ///< name "enableCursorBlink",                   Whether the cursor should blink or not,                                   type BOOLEAN
-      CURSOR_BLINK_INTERVAL,                    ///< name "cursorBlinkInterval",                 The time interval in seconds between cursor on/off states,                type FLOAT
-      CURSOR_BLINK_DURATION,                    ///< name "cursorBlinkDuration",                 The cursor will stop blinking after this number of seconds (if non-zero), type FLOAT
-      CURSOR_WIDTH,                             ///< name "cursorWidth",                         The cursor width,                                                         type INTEGER
-      GRAB_HANDLE_IMAGE,                        ///< name "grabHandleImage",                     The image to display for the grab handle,                                 type STRING
-      GRAB_HANDLE_PRESSED_IMAGE,                ///< name "grabHandlePressedImage",              The image to display when the grab handle is pressed,                     type STRING
-      SCROLL_THRESHOLD,                         ///< name "scrollThreshold"                      Scrolling will occur if the cursor is this close to the control border,   type FLOAT
-      SCROLL_SPEED,                             ///< name "scrollSpeed"                          The scroll speed in pixels per second,                                    type FLOAT
-      SELECTION_HANDLE_IMAGE_LEFT,              ///< name "selectionHandleImageLeft",            The image to display for the left selection handle,                       type MAP
-      SELECTION_HANDLE_IMAGE_RIGHT,             ///< name "selectionHandleImageRight",           The image to display for the right selection handle,                      type MAP
-      SELECTION_HANDLE_PRESSED_IMAGE_LEFT,      ///< name "selectionHandlePressedImageLeft",     The image to display when the left selection handle is pressed,           type MAP
-      SELECTION_HANDLE_PRESSED_IMAGE_RIGHT,     ///< name "selectionHandlePressedImageRight",    The image to display when the right selection handle is pressed,          type MAP
-      SELECTION_HANDLE_MARKER_IMAGE_LEFT,       ///< name "selectionHandleMarkerImageLeft",      The image to display for the left selection handle marker,                type MAP
-      SELECTION_HANDLE_MARKER_IMAGE_RIGHT,      ///< name "selectionHandleMarkerImageRight",     The image to display for the right selection handle marker,               type MAP
-      SELECTION_HIGHLIGHT_COLOR,                ///< name "selectionHighlightColor",             The color of the selection highlight,                                     type VECTOR4
-      DECORATION_BOUNDING_BOX,                  ///< name "decorationBoundingBox",               The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
-      INPUT_METHOD_SETTINGS,                    ///< name "inputMethodSettings",                 The settings to relating to the System's Input Method, Key and Value      type MAP
-      INPUT_COLOR,                              ///< name "inputColor",                          The color of the new input text,                                          type VECTOR4
-      ENABLE_MARKUP,                            ///< name "enableMarkup",                        Whether the mark-up processing is enabled.                                type BOOLEAN
-      INPUT_FONT_FAMILY,                        ///< name "inputFontFamily",                     The font's family of the new input text,                                  type STRING
-      INPUT_FONT_STYLE,                         ///< name "inputFontStyle",                      The font's style of the new input text,                                   type STRING
-      INPUT_POINT_SIZE                          ///< name "inputPointSize",                      The font's size of the new input text in points,                          type FLOAT
+      RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend",                    The type or rendering e.g. bitmap-based,                                           type INT
+      TEXT,                                     ///< name "text",                                The text to display in UTF-8 format,                                               type STRING
+      PLACEHOLDER_TEXT,                         ///< name "placeholderText",                     The text to display when the TextField is empty and inactive,                      type STRING
+      PLACEHOLDER_TEXT_FOCUSED,                 ///< name "placeholderTextFocused",              The text to display when the TextField is empty with key-input focus,              type STRING
+      FONT_FAMILY,                              ///< name "fontFamily",                          The requested font family,                                                         type STRING
+      FONT_STYLE,                               ///< name "fontStyle",                           The requested font style,                                                          type STRING
+      POINT_SIZE,                               ///< name "pointSize",                           The size of font in points,                                                        type FLOAT
+      MAX_LENGTH,                               ///< name "maxLength"                            The maximum number of characters that can be inserted,                             type INTEGER
+      EXCEED_POLICY,                            ///< name "exceedPolicy"                         Specifies how the text is truncated when it does not fit,                          type INTEGER
+      HORIZONTAL_ALIGNMENT,                     ///< name "horizontalAlignment",                 The line horizontal alignment,                                                     type STRING,  values "BEGIN", "CENTER", "END"
+      VERTICAL_ALIGNMENT,                       ///< name "verticalAlignment",                   The line vertical alignment,                                                       type STRING,  values "TOP",   "CENTER", "BOTTOM"
+      TEXT_COLOR,                               ///< name "textColor",                           The text color,                                                                    type VECTOR4
+      PLACEHOLDER_TEXT_COLOR,                   ///< name "placeholderTextColor",                The placeholder-text color,                                                        type VECTOR4
+      SHADOW_OFFSET,                            ///< name "shadowOffset",                        The drop shadow offset 0 indicates no shadow,                                      type VECTOR2
+      SHADOW_COLOR,                             ///< name "shadowColor",                         The color of a drop shadow,                                                        type VECTOR4
+      PRIMARY_CURSOR_COLOR,                     ///< name "primaryCursorColor",                  The color to apply to the primary cursor,                                          type VECTOR4
+      SECONDARY_CURSOR_COLOR,                   ///< name "secondaryCursorColor",                The color to apply to the secondary cursor,                                        type VECTOR4
+      ENABLE_CURSOR_BLINK,                      ///< name "enableCursorBlink",                   Whether the cursor should blink or not,                                            type BOOLEAN
+      CURSOR_BLINK_INTERVAL,                    ///< name "cursorBlinkInterval",                 The time interval in seconds between cursor on/off states,                         type FLOAT
+      CURSOR_BLINK_DURATION,                    ///< name "cursorBlinkDuration",                 The cursor will stop blinking after this number of seconds (if non-zero),          type FLOAT
+      CURSOR_WIDTH,                             ///< name "cursorWidth",                         The cursor width,                                                                  type INTEGER
+      GRAB_HANDLE_IMAGE,                        ///< name "grabHandleImage",                     The image to display for the grab handle,                                          type STRING
+      GRAB_HANDLE_PRESSED_IMAGE,                ///< name "grabHandlePressedImage",              The image to display when the grab handle is pressed,                              type STRING
+      SCROLL_THRESHOLD,                         ///< name "scrollThreshold"                      Horizontal scrolling will occur if the cursor is this close to the control border, type FLOAT
+      SCROLL_SPEED,                             ///< name "scrollSpeed"                          The scroll speed in pixels per second,                                             type FLOAT
+      SELECTION_HANDLE_IMAGE_LEFT,              ///< name "selectionHandleImageLeft",            The image to display for the left selection handle,                                type MAP
+      SELECTION_HANDLE_IMAGE_RIGHT,             ///< name "selectionHandleImageRight",           The image to display for the right selection handle,                               type MAP
+      SELECTION_HANDLE_PRESSED_IMAGE_LEFT,      ///< name "selectionHandlePressedImageLeft",     The image to display when the left selection handle is pressed,                    type MAP
+      SELECTION_HANDLE_PRESSED_IMAGE_RIGHT,     ///< name "selectionHandlePressedImageRight",    The image to display when the right selection handle is pressed,                   type MAP
+      SELECTION_HANDLE_MARKER_IMAGE_LEFT,       ///< name "selectionHandleMarkerImageLeft",      The image to display for the left selection handle marker,                         type MAP
+      SELECTION_HANDLE_MARKER_IMAGE_RIGHT,      ///< name "selectionHandleMarkerImageRight",     The image to display for the right selection handle marker,                        type MAP
+      SELECTION_HIGHLIGHT_COLOR,                ///< name "selectionHighlightColor",             The color of the selection highlight,                                              type VECTOR4
+      DECORATION_BOUNDING_BOX,                  ///< name "decorationBoundingBox",               The decorations (handles etc) will positioned within this area on-screen,          type RECTANGLE
+      INPUT_METHOD_SETTINGS,                    ///< name "inputMethodSettings",                 The settings to relating to the System's Input Method, Key and Value               type MAP
+      INPUT_COLOR,                              ///< name "inputColor",                          The color of the new input text,                                                   type VECTOR4
+      ENABLE_MARKUP,                            ///< name "enableMarkup",                        Whether the mark-up processing is enabled.                                         type BOOLEAN
+      INPUT_FONT_FAMILY,                        ///< name "inputFontFamily",                     The font's family of the new input text,                                           type STRING
+      INPUT_FONT_STYLE,                         ///< name "inputFontStyle",                      The font's style of the new input text,                                            type STRING
+      INPUT_POINT_SIZE                          ///< name "inputPointSize",                      The font's size of the new input text in points,                                   type FLOAT
     };
   };
 
@@ -121,12 +121,13 @@ public:
 
   // Type Defs
 
-  /// @brief Max Characters Exceed signal type;
+  /// @brief Text changed signal type.
   typedef Signal<void ( TextField ) > TextChangedSignalType;
+  /// @brief Max Characters Exceed signal type.
   typedef Signal<void ( TextField ) > MaxLengthReachedSignalType;
 
   /**
-   * Create the TextField control.
+   * @brief Create the TextField control.
    * @return A handle to the TextField control.
    */
   static TextField New();
@@ -152,7 +153,7 @@ public:
   TextField& operator=( const TextField& handle );
 
   /**
-   * @brief Destructor
+   * @brief Destructor.
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
    */
@@ -164,8 +165,8 @@ public:
    * If the BaseHandle points is a TextField the downcast returns a valid handle.
    * If not the returned handle is left empty.
    *
-   * @param[in] handle Handle to an object
-   * @return handle to a TextField or an empty handle
+   * @param[in] handle Handle to an object.
+   * @return handle to a TextField or an empty handle.
    */
   static TextField DownCast( BaseHandle handle );
 
index f8d7918..afebe0a 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 = 17;
+const unsigned int TOOLKIT_MICRO_VERSION = 18;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
@@ -42,7 +42,7 @@ struct PrintVersion
 {
   PrintVersion()
   {
-    std::cout << "DALi Toolkit:   " << TOOLKIT_MAJOR_VERSION << "." << TOOLKIT_MINOR_VERSION << "." << TOOLKIT_MICRO_VERSION << " (" << TOOLKIT_BUILD_DATE << ")" << std::endl;
+    std::cerr << "DALi Toolkit:   " << TOOLKIT_MAJOR_VERSION << "." << TOOLKIT_MINOR_VERSION << "." << TOOLKIT_MICRO_VERSION << " (" << TOOLKIT_BUILD_DATE << ")" << std::endl;
   }
 };
 PrintVersion TOOLKIT_VERSION;
index 7b4b130..ab9c802 100644 (file)
@@ -131,6 +131,25 @@ distributing this software or its derivatives.
       "overshootEffectColor":"B018",
       "overshootAnimationSpeed":120.0,
       "overshootSize":[480.0,42.0]
+    },
+    "texteditor":
+    {
+      "pointSize":18,
+      "primaryCursorColor":[0.0,0.72,0.9,1.0],
+      "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+      "cursorWidth":1,
+      "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+      "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+      "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+      "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }
+    },
+    "popup":
+    {
+      "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png"
+    },
+    "confirmationpopup":
+    {
+      "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png"
     }
   }
 }
index 525857b..30325c6 100644 (file)
@@ -131,6 +131,17 @@ distributing this software or its derivatives.
       "overshootEffectColor":"B018",
       "overshootAnimationSpeed":360.0,
       "overshootSize":[720.0,130.0]
+    },
+    "texteditor":
+    {
+      "pointSize":18,
+      "primaryCursorColor":[0.0,0.72,0.9,1.0],
+      "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+      "cursorWidth":3,
+      "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+      "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+      "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+      "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }
     }
   }
 }
diff --git a/docs/content/images/item-view/list.png b/docs/content/images/item-view/list.png
new file mode 100755 (executable)
index 0000000..d588929
Binary files /dev/null and b/docs/content/images/item-view/list.png differ
index 7bd9936..1f6091a 100644 (file)
@@ -58,6 +58,7 @@
  + [Popup](@ref popup)
  + [Scroll View](@ref scroll-view)
  + TableView
+ + [Text Editor](@ref text-editor)
  + [Text Field](@ref text-field)
  + [Text Label](@ref text-label)
 
diff --git a/docs/content/shared-javascript-and-cpp-documentation/copy-and-paste.md b/docs/content/shared-javascript-and-cpp-documentation/copy-and-paste.md
new file mode 100644 (file)
index 0000000..759de31
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+/**-->
+
+# Copy and Paste  (Selection) {#copy-n-paste}
+
+Text can be selected by a long press or double tapping it.   Depending on certain conditions a popup could be shown giving options including [CUT][COPY][PASTE], [SELECT ALL] or [CLIPBOARD]. Below these conditions will be explained.
+
+[CUT] or [COPY] send the selected text to the clipboard ready to be pasted directly or via the clipboard UI.   Pressing [PASTE] will paste the top item from the clipboard (what has just been copied, possibly from another application).  If the system supports a clipboard UI this can be displayed by pressing the [CLIPBOARD] button.
+
+Empty text means the user has not inputted any text, a text-control containing special characters or purely whitespace is not empty.
+
+Below shows how the popup will look depending on the state of the text-control.
+
+|  |  |
+|--|--|
+| Condition: Long press/double tap when empty text but clipboard has content  |  Condition: Long press/double tap when text-control contains text |
+|[PASTE][CLIPBOARD] buttons shown| [CUT][COPY], [SELECT ALL] unless all text selected and [PASTE][CLIPBOARD] if content to paste. |
+|    ![ ](../assets/img/text-controls/EmptyTextClipboardHasContent.png) ![ ](./EmptyTextClipboardHasContent.png) |   ![ ](../assets/img/text-controls/SelectingText.png) ![ ](./SelectingText.png) |
+| Condition: Long press/double tap popup when text-control contains just whitespace | Condition: Empty text & clipboard empty |
+| Whitespace treated as regular text, [CUT][COPY] shown and [PASTE][CLIPBOARD] if content to paste. As all text is selected there is no need for [SELECT ALL] |  No popup shown after longpress/double tap|
+|  ![ ](../assets/img/text-controls/SelectAllWhitespace.png) ![ ](./SelectAllWhitespace.png) | ![ ](../assets/img/text-controls/EmptyTextAndNoContentToPaste.png) ![ ](./EmptyTextAndNoContentToPaste.png)|
+| Condition: Longpress/(double tap) on whitespace which is following text | Condition: Tapping text or panning grab handle |
+| [PASTE][CLIPBOARD] shown if something to paste. [SELECT ALL] as more text to select | If content in clipboard [PASTE][CLIPBOARD] popup will be shown. |
+| ![ ](../assets/img/text-controls/SelectWhitespaceAfterText.png) ![ ](./SelectWhitespaceAfterText.png) | ![ ](../assets/img/text-controls/TapAfterCopyingText.png) ![ ](./TapAfterCopyingText.png) |
+
+
+*/
diff --git a/docs/content/shared-javascript-and-cpp-documentation/input-style.md b/docs/content/shared-javascript-and-cpp-documentation/input-style.md
new file mode 100644 (file)
index 0000000..f37f126
--- /dev/null
@@ -0,0 +1,17 @@
+<!--
+/**-->
+
+# Input Style {#input-style}
+
+The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style.
+
+Note the input style may change if the cursor is updated by tapping in a new position.
+
+Current supported input style properties are:
+
+- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1.
+- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set.
+- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details.
+- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details.
+
+*/
diff --git a/docs/content/shared-javascript-and-cpp-documentation/text-editor.md b/docs/content/shared-javascript-and-cpp-documentation/text-editor.md
new file mode 100644 (file)
index 0000000..0da1f43
--- /dev/null
@@ -0,0 +1,134 @@
+<!--
+/**-->
+
+# Text Editor {#text-editor}
+
+## Overview
+
+The Dali::Toolkit::TextEditor is a control which provides a multi-line editable text.
+
+### Basic usage
+
+Add the text-editor to the stage.
+
+~~~{.cpp}
+// C++
+
+TextEditor editor = TextEditor::New();
+
+Stage::GetCurrent().Add( editor );
+~~~
+
+~~~{.js}
+// JavaScript
+
+var editor = new dali.TextEditor();
+
+dali.stage.add( editor );
+~~~
+
+When the TextEditor is tapped, it will automatically gain the keyboard focus. Key events will then result in text being inserted.
+After text has been entered, it can be retrieved from the TEXT property.
+
+~~~{.cpp}
+// C++
+
+Property::Value editorText = editor.GetProperty( TextEditor::Property::TEXT );
+std::cout << "Received text: " << editorText.Get< std::string >() << std::endl;
+~~~
+
+~~~{.js}
+// JavaScript
+
+console.log( editor.text );
+~~~
+
+### Font Selection
+
+By default TextEditor will automatically select a suitable font from the platform. However, a different font could be selected. See the [Font Selection](@ref font-selection) section for more details.
+
+### Mark-up Style
+
+Mark-up tags can be used to change the style of the text. See the [Mark-up Style](@ref markup-style) section for more details.
+
+### Input Style
+
+The input style can be changed through the control properties.See the [Input Style](@ref input-style) section for more details.
+
+### Text Alignment
+
+TextEditor displays a multi-line of text, which will scroll if there is not enough room for the text displayed.
+If there is enough room, then the text can be aligned horizontally to the beginning, end, or center of the available area:
+
+~~~{.cpp}
+// C++
+
+editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "BEGIN" ); // "CENTER" or "END"
+~~~
+
+~~~{.js}
+// JavaScript
+
+editor.HorizontalAlignment = "BEGIN"; // "CENTER" or "END"
+~~~
+
+### Copy and Paste  (Selection)
+
+Text can be selected by a long press or double tapping it. See the [Copy and Paste](@ref copy-n-paste) section for more details.
+
+### TextEditor Decorations
+
+#### Color
+
+To change the color of the text, the recommended way is to use the TEXT_COLOR property.
+
+~~~{.cpp}
+// C++
+editor.SetProperty( TextEditor::Property::TEXT_COLOR, Color::CYAN );
+~~~
+
+~~~{.js}
+// JavaScript
+
+editor.textColor = dali.COLOR_CYAN;
+~~~
+
+### TextEditor Properties
+
+ Name (JavaScript)                 |  Name (C++)                          |  Type        | Writable     | Animatable
+-----------------------------------|--------------------------------------|--------------|--------------|-----------
+ renderingBackend                  | RENDERING_BACKEND                    |  INTEGER     | O            | X
+ text                              | TEXT                                 |  STRING      | O            | X
+ textColor                         | TEXT_COLOR                           |  VECTOR4     | O            | X
+ fontFamily                        | FONT_FAMILY                          |  STRING      | O            | X
+ fontStyle                         | FONT_STYLE                           |  STRING      | O            | X
+ pointSize                         | POINT_SIZE                           |  FLOAT       | O            | X
+ horizontalAlignment               | HORIZONTAL_ALIGNMENT                 |  STRING      | O            | X
+ verticalAlignment                 | VERTICAL_ALIGNMENT                   |  STRING      | O            | X
+ scrollThreshold                   | SCROLL_THRESHOLD                     |  FLOAT       | O            | X
+ scrollSpeed                       | SCROLL_SPEED                         |  FLOAT       | O            | X
+ primaryCursorColor                | PRIMARY_CURSOR_COLOR                 |  VECTOR4     | O            | X
+ secondaryCursorColor              | SECONDARY_CURSOR_COLOR               |  VECTOR4     | O            | X
+ enableCursorBlink                 | ENABLE_CURSOR_BLINK                  |  BOOLEAN     | O            | X
+ cursorBlinkInterval               | CURSOR_BLINK_INTERVAL                |  FLOAT       | O            | X
+ cursorBlinkDuration               | CURSOR_BLINK_DURATION                |  FLOAT       | O            | X
+ cursorWidth                       | CURSOR_WIDTH                         |  INTEGER     | O            | X
+ grabHandleImage                   | GRAB_HANDLE_IMAGE                    |  STRING      | O            | X
+ grabHandlePressedImage            | GRAB_HANDLE_PRESSED_IMAGE            |  STRING      | O            | X
+ selectionHandleImageLeft          | SELECTION_HANDLE_IMAGE_LEFT          |  STRING      | O            | X
+ selectionHandleImageRight         | SELECTION_HANDLE_IMAGE_RIGHT         |  STRING      | O            | X
+ selectionHandlePressedImageLeft   | SELECTION_HANDLE_PRESSED_IMAGE_LEFT  |  STRING      | O            | X
+ selectionHandlePressedImageRight  | SELECTION_HANDLE_PRESSED_IMAGE_RIGHT |  STRING      | O            | X
+ selectionHandleMarkerImageLeft    | SELECTION_HANDLE_MARKER_IMAGE_LEFT   |  MAP         | O            | X
+ selectionHandleMarkerImageRight   | SELECTION_HANDLE_MARKER_IMAGE_RIGHT  |  MAP         | O            | X
+ selectionHighlightColor           | SELECTION_HIGHLIGHT_COLOR            |  VECTOR4     | O            | X
+ decorationBoundingBox             | DECORATION_BOUNDING_BOX              |  RECTANGLE   | O            | X
+ enableMarkup                      | ENABLE_MARKUP                        |  BOOLEAN     | O            | X
+ inputColor                        | INPUT_COLOR                          |  VECTOR4     | O            | X
+ inputFontFamily                   | INPUT_FONT_FAMILY                    |  STRING      | O            | X
+ inputFontStyle                    | INPUT_FONT_STYLE                     |  STRING      | O            | X
+ inputPointSize                    | INPUT_POINT_SIZE                     |  FLOAT       | O            | X
+
+@class TextEditor
+
+*/
index 76cea4c..f6c8ecc 100644 (file)
@@ -61,16 +61,7 @@ Mark-up tags can be used to change the style of the text. See the [Mark-up Style
 
 ### Input Style
 
-The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style.
-
-Note the input style may change if the cursor is updated by tapping in a new position.
-
-Current supported input style properties are:
-
-- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1.
-- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set.
-- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details.
-- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details.
+The input style can be changed through the control properties. See the [Input Style](@ref input-style) section for more details.
 
 ### Text Alignment
 
@@ -91,25 +82,7 @@ field.HorizontalAlignment = "BEGIN"; // "CENTER" or "END"
 
 ### Copy and Paste  (Selection)
 
-Text can be selected by a long press or double tapping it.   Depending on certain conditions a popup could be shown giving options including [CUT][COPY][PASTE], [SELECT ALL] or [CLIPBOARD]. Below these conditions will be explained.
-
-[CUT] or [COPY] send the selected text to the clipboard ready to be pasted directly or via the clipboard UI.   Pressing [PASTE] will paste the top item from the clipboard (what has just been copied, possibly from another application).  If the system supports a clipboard UI this can be displayed by pressing the [CLIPBOARD] button.
-
-Empty text means the user has not inputted any text, a TextField containing special characters or purely whitespace is not empty.
-
-Below shows how the popup will look depending on the state of the TextField
-
-|  |  |
-|--|--|
-| Condition: Long press/double tap when empty text but clipboard has content  |  Condition: Long press/double tap when TextField contains text |
-|[PASTE][CLIPBOARD] buttons shown| [CUT][COPY], [SELECT ALL] unless all text selected and [PASTE][CLIPBOARD] if content to paste. |
-|    ![ ](../assets/img/text-controls/EmptyTextClipboardHasContent.png) ![ ](./EmptyTextClipboardHasContent.png) |   ![ ](../assets/img/text-controls/SelectingText.png) ![ ](./SelectingText.png) |
-| Condition: Long press/double tap popup when TextField contains just whitespace | Condition: Empty text & clipboard empty |
-| Whitespace treated as regular text, [CUT][COPY] shown and [PASTE][CLIPBOARD] if content to paste. As all text is selected there is no need for [SELECT ALL] |  No popup shown after longpress/double tap|
-|  ![ ](../assets/img/text-controls/SelectAllWhitespace.png) ![ ](./SelectAllWhitespace.png) | ![ ](../assets/img/text-controls/EmptyTextAndNoContentToPaste.png) ![ ](./EmptyTextAndNoContentToPaste.png)|
-| Condition: Longpress/(double tap) on whitespace which is following text | Condition: Tapping text or panning grab handle |
-| [PASTE][CLIPBOARD] shown if something to paste. [SELECT ALL] as more text to select | If content in clipboard [PASTE][CLIPBOARD] popup will be shown. |
-| ![ ](../assets/img/text-controls/SelectWhitespaceAfterText.png) ![ ](./SelectWhitespaceAfterText.png) | ![ ](../assets/img/text-controls/TapAfterCopyingText.png) ![ ](./TapAfterCopyingText.png) |
+Text can be selected by a long press or double tapping it. See the [Copy and Paste](@ref copy-n-paste) section for more details.
 
 ### TextField Decorations
 
index dcef968..142cc74 100644 (file)
@@ -18,6 +18,9 @@
       '<(DALI_JS_DIR)/actors/layer-api.cpp',
       '<(DALI_JS_DIR)/actors/camera-actor-api.cpp',
       '<(DALI_JS_DIR)/constants/constants-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/control-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/item-factory-wrapper.cpp',
+      '<(DALI_JS_DIR)/controls/item-view-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-api.cpp',
       '<(DALI_JS_DIR)/animation/animation-wrapper.cpp',
       '<(DALI_JS_DIR)/animation/constrainer-api.cpp',
@@ -66,7 +69,7 @@
       'cflags': [
             '-fPIC',
             '-frtti',
-            '<!@(pkg-config --cflags dali dali-toolkit)'
+            '<!@(pkg-config --cflags dali-core dali-adaptor-uv dali-toolkit)'
         ],
 
     'cflags_cc': [
             '-frtti'    # needed for typeinfo with dali-any
         ],
       'ldflags': [
-            '<!@(pkg-config --libs-only-L --libs-only-other dali dali-toolkit)'
+            '<!@(pkg-config --libs-only-L --libs-only-other dali-core dali-adaptor-uv dali-toolkit)'
         ],
       'libraries': [
-        '<!@(pkg-config --libs-only-l dali dali-toolkit)'
+        '<!@(pkg-config --libs-only-l dali-core dali-adaptor-uv dali-toolkit)'
       ]
     }]
 }
index bd4dd2c..d418eca 100644 (file)
@@ -56,6 +56,9 @@ add_library(dali_addon SHARED
   ${PLUGING_SRC_DIR}/actors/actor-api.cpp
   ${PLUGING_SRC_DIR}/actors/layer-api.cpp
   ${PLUGING_SRC_DIR}/actors/camera-actor-api.cpp
+  ${PLUGING_SRC_DIR}/controls/control-wrapper.cpp
+  ${PLUGING_SRC_DIR}/controls/item-factory-wrapper.cpp
+  ${PLUGING_SRC_DIR}/controls/item-view-api.cpp
   ${PLUGING_SRC_DIR}/constants/constants-wrapper.cpp
   ${PLUGING_SRC_DIR}/animation/animation-api.cpp
   ${PLUGING_SRC_DIR}/animation/animation-wrapper.cpp
@@ -110,7 +113,8 @@ set_source_files_properties(${builddir}/lib.${TOOLSET}/dali.node PROPERTIES GENE
 set_target_properties(dali_addon PROPERTIES EXCLUDE_FROM_ALL "FALSE")
 
 
-SET(PKG_LIST dali
+SET(PKG_LIST dali-core
+             dali-adaptor-uv
              dali-toolkit)
 
 INCLUDE(FindPkgConfig)
diff --git a/node-addon/examples/images/icon-0.png b/node-addon/examples/images/icon-0.png
new file mode 100755 (executable)
index 0000000..8d300e9
Binary files /dev/null and b/node-addon/examples/images/icon-0.png differ
diff --git a/node-addon/examples/images/icon-1.png b/node-addon/examples/images/icon-1.png
new file mode 100755 (executable)
index 0000000..bfed8ac
Binary files /dev/null and b/node-addon/examples/images/icon-1.png differ
diff --git a/node-addon/examples/images/icon-2.png b/node-addon/examples/images/icon-2.png
new file mode 100755 (executable)
index 0000000..db892fb
Binary files /dev/null and b/node-addon/examples/images/icon-2.png differ
diff --git a/node-addon/examples/item-view.js b/node-addon/examples/item-view.js
new file mode 100644 (file)
index 0000000..5abfcfc
--- /dev/null
@@ -0,0 +1,142 @@
+ var window= {
+           x:0,
+           y:0,
+           width:1920,
+           height: 1080,
+           transparent: false,
+           name:'itemview-example'
+ };
+
+ var viewMode={
+       'stereoscopic-mode':'mono', // stereo-horizontal, stereo-vertical, stereo-interlaced,
+       'stereoBase': 65 // Distance in millimeters between left/right cameras typically between (50-70mm)
+ };
+
+ var options= {
+    'window': window,
+    'viewMode': viewMode,
+ }
+
+//desktop
+//var dali = require('../build/Release/dali')( options );
+
+//target
+var dali = require('dali')( options );
+
+var items = [];
+var button;
+var stageSize;
+
+var itemView;
+var itemFactory;
+
+var currentLayoutIndex = 0;
+var totalItemCount = 100;
+
+var imageDir = "./images/";
+
+var daliApp = {};
+
+daliApp.createItemView = function() {
+
+  // Create item view data
+  var itemViewData = [];
+  for (var itemId = 0; itemId < totalItemCount; itemId++)
+  {
+    var data = {};
+    data["template"] = "template-item-list"; // Create items initially with list template
+    data["icon_path"] = imageDir + "icon-" + itemId % 3 + ".png";
+    data["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = data;
+  }
+
+  // Create item factory and set the data
+  itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./scripts/item-template.json";
+  itemFactory.data = itemViewData;
+
+  // Create item view
+  stageSize = dali.stage.getSize();
+  itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  itemView.refreshInterval = 4.0;
+
+  // Add item view to the stage
+  dali.stage.add( itemView );
+
+  // Create scroll bar for item view
+  var scrollBar = new dali.Control("ScrollBar");
+  scrollBar.parentOrigin = dali.TOP_RIGHT;
+  scrollBar.anchorPoint = dali.TOP_RIGHT;
+  scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+  scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+  itemView.add(scrollBar);
+
+  // Add the list and grid layouts
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST); // layout index 0
+  itemView.addLayout(dali.ITEM_LAYOUT_GRID); // layout index 1
+
+  // Set custom item size for list layout
+  itemView.setItemSize(0, [stageSize.x, stageSize.y * 0.1, 0.0]);
+
+  // Set custom item size for grid layout
+  var layoutMargin = 120;
+  itemView.setItemSize(1, [(stageSize.x - layoutMargin) / 4, stageSize.y * 0.2, 0.0]);
+
+  // Activate the list layout
+  itemView.activateLayout(0, itemView.size);
+
+  // Create button for layout switching
+  button = new dali.Control("PushButton");
+  button.size = [100.0, 60.0, 0.0];
+  button.position = [-20.0, 20.0, 0.0];
+  button.parentOrigin = dali.TOP_RIGHT;
+  button.anchorPoint = dali.TOP_RIGHT;
+  button.labelText = "Switch";
+  dali.stage.add( button );
+
+  // Connect a signal callback to button pressed signal
+  button.on("pressed", daliApp.buttonPressedEvent);
+}
+
+daliApp.buttonPressedEvent = function( button ) {
+
+  // Calculate the layout index for the next layout to switch to
+  currentLayoutIndex++;
+  currentLayoutIndex = currentLayoutIndex % itemView.getLayoutCount();
+
+  // Activate the next layout
+  itemView.activateLayout(currentLayoutIndex, [stageSize.x, stageSize.y, 0.0], 0.0);
+
+  // Change the item template in item view data as we want to change the layout of the items
+  var data = itemFactory.data;
+  for (var itemId = 0; itemId < totalItemCount; itemId++)
+  {
+    if(currentLayoutIndex == 0)
+    {
+      // List layout
+      data[itemId]["template"] = "template-item-list"; // Create items with list template
+    }
+    else
+    {
+      // Grid layout
+      data[itemId]["template"] = "template-item-grid"; // Create items with grid template
+    }
+  }
+  itemFactory.data = data;
+}
+
+function startup()
+{
+  daliApp.init();
+}
+
+daliApp.init = function()
+{
+  daliApp.createItemView();
+}
+
+startup();
+
similarity index 98%
rename from node-addon/line-mesh.js
rename to node-addon/examples/line-mesh.js
index f1c9532..faaedb9 100644 (file)
@@ -18,7 +18,7 @@
  }
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
similarity index 99%
rename from node-addon/mesh-morph.js
rename to node-addon/examples/mesh-morph.js
index dd4527a..edbdcf9 100644 (file)
@@ -17,9 +17,8 @@
     'view-mode': viewMode,
  }
 
-
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
similarity index 98%
rename from node-addon/point-mesh.js
rename to node-addon/examples/point-mesh.js
index f9c7186..ceb9b1e 100644 (file)
     'view-mode': viewMode,
  }
 
-var imageDir = "./";
+var imageDir = "./images/";
 
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
diff --git a/node-addon/examples/scripts/item-template.json b/node-addon/examples/scripts/item-template.json
new file mode 100644 (file)
index 0000000..f909edd
--- /dev/null
@@ -0,0 +1,92 @@
+{
+  "templates":
+  {
+    "template-item-list":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[20.0, 0.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER_LEFT",
+          "parentOrigin":"CENTER_LEFT",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"CENTER_LEFT",
+              "parentOrigin":"CENTER_RIGHT",
+              "type":"TextLabel",
+              "position": [30.0, 0.0, 0.0],
+              "size":[200.0, 70.0, 0.0],
+              "pointSize":30,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"BEGIN",
+              "verticalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    },
+
+    "template-item-grid":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[0.0, -10.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER",
+          "parentOrigin":"CENTER",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"TOP_CENTER",
+              "parentOrigin":"BOTTOM_CENTER",
+              "type":"TextLabel",
+              "position": [0.0,10.0,0.0],
+              "size":[100.0, 100.0, 0.0],
+              "pointSize":22,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+
similarity index 98%
rename from node-addon/texture-mesh.js
rename to node-addon/examples/texture-mesh.js
index 7f6173e..016a7a9 100644 (file)
     'view-mode': viewMode,
  }
 
-var imageDir = "./";
+var imageDir = "./images/";
 
 
 // desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
 
 // target
 var dali = require('dali')( options );
diff --git a/node-addon/item-template.json b/node-addon/item-template.json
new file mode 100644 (file)
index 0000000..f909edd
--- /dev/null
@@ -0,0 +1,92 @@
+{
+  "templates":
+  {
+    "template-item-list":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[20.0, 0.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER_LEFT",
+          "parentOrigin":"CENTER_LEFT",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"CENTER_LEFT",
+              "parentOrigin":"CENTER_RIGHT",
+              "type":"TextLabel",
+              "position": [30.0, 0.0, 0.0],
+              "size":[200.0, 70.0, 0.0],
+              "pointSize":30,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"BEGIN",
+              "verticalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    },
+
+    "template-item-grid":
+    {
+      "name":"item",
+      "type":"Actor",
+      "position":[0,0,0],
+      "anchorPoint":"TOP_LEFT",
+      "parentOrigin":"TOP_LEFT",
+      "actors":
+       [
+        {
+          "name":"icon",
+          "type":"ImageView",
+          "image":
+          {
+            "rendererType" : "imageRenderer",
+            "imageUrl": "{icon_path}"
+          },
+          "position":[0.0, -10.0, 0.0],
+          "size":[70.0, 70.0, 0.0],
+          "color":[1.0,1.0,1.0,1.0],
+          "anchorPoint":"CENTER",
+          "parentOrigin":"CENTER",
+          "actors":
+          [
+            {
+              "name":"title",
+              "anchorPoint":"TOP_CENTER",
+              "parentOrigin":"BOTTOM_CENTER",
+              "type":"TextLabel",
+              "position": [0.0,10.0,0.0],
+              "size":[100.0, 100.0, 0.0],
+              "pointSize":22,
+              "fontFamily":"HelveticaNeue",
+              "fontStyle":"Bold",
+              "horizontalAlignment":"CENTER",
+              "textColor": [1.0,0.0,1.0,1.0],
+              "text":"{title_text}"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+
index fe4bc23..22bfeae 100644 (file)
@@ -7,17 +7,17 @@ License:    Apache License, Version 2.0
 URL:        https://review.tizen.org/gerrit/#/q/project:platform/core/uifw/dali-toolkit
 Distribution: Tizen
 Source0:    %{name}-%{version}.tar.gz
-Requires:   dali
 
-# Do NOT put an adaptor here - it is an application choice which adaptor to use
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  cmake
-BuildRequires:  pkgconfig(dali)
 BuildRequires:  pkgconfig(dali-core)
 BuildRequires:  pkgconfig(dali-toolkit)
 BuildRequires:  nodejs-devel
 
+# DALi JS applications using dali-addon always run on dali-adaptor-uv.
+BuildRequires:  pkgconfig(dali-adaptor-uv)
+
 %description
 DALi Node.JS addon
 
@@ -69,7 +69,7 @@ rm -rf %{buildroot}
 
 cd "%{addonBuildDir}"
 %make_install
-cp %{addonDir}/line-mesh.js %{installDir}/line-mesh.js
+cp -R %{addonDir}/examples %{installDir}/examples
 
 
 %clean
index 1e82cbb..d326e26 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.1.17
+Version:    1.1.18
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT
@@ -9,13 +9,16 @@ Source0:    %{name}-%{version}.tar.gz
 
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
-Requires:       dali
-# Do NOT put an adaptor here - it is an application choice which adaptor to use
+
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(dali)
 BuildRequires:  pkgconfig(dali-core)
 
+# dali-toolkit only need to know the interfaces(APIs) of dali-adaptor(the devel package).
+# It doesn't need to know which adaptor will be used by applications.
+# Applications or dali-addon will decide which one they will use.
+BuildRequires:  dali-adaptor-devel
+
 #############################
 # profile setup
 #############################
index d321285..a09ed33 100644 (file)
@@ -184,6 +184,13 @@ Constants accessible under the dali global object.
 |PROPERTY_ARRAY                       | integer value  |
 |PROPERTY_MAP                         | integer value  |
 |PROPERTY_INVALID_INDEX               | integer value  |
+|PROPERTY_READ_ONLY                   | integer value  |
+|PROPERTY_READ_WRITE                  | integer value  |
+|PROPERTY_ANIMATABLE                  | integer value  |
+
+|**Item layout type ** | |
+|ITEM_LAYOUT_LIST                     | integer value  |
+|ITEM_LAYOUT_GRID                     | integer value  |
 
  * @class Constants
  */
diff --git a/plugins/dali-script-v8/docs/content/item-factory.js b/plugins/dali-script-v8/docs/content/item-factory.js
new file mode 100644 (file)
index 0000000..b7ae5ab
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ *
+## ItemFactory API
+
+ ItemFactory is for storing the data of {{#crossLink "ItemView"}}ItemView{{/crossLink}}
+ and creating actors for ItemView on request. Each item in ItemView is identified by a
+ unique ID, and has a linear order from 0.
+ A JSON file should be provided to ItemFactory which defines the templates of items
+ to be used to create the actors. Multiple templates can be defined in the JSON file
+ for different type of items.
+### Simple example of creating a JSON template for items
+```
+  {
+    "templates":
+    {
+      "template-item":
+      {
+        "name":"item",
+        "type":"Actor",
+        "position":[0,0,0],
+        "anchorPoint":"TOP_LEFT",
+        "parentOrigin":"TOP_LEFT",
+        "actors":
+         [
+          {
+            "name":"icon",
+            "type":"ImageView",
+            "image":
+            {
+              "rendererType" : "imageRenderer",
+              "imageUrl": "{icon_path}"
+            },
+            "position":[20.0, 0.0, 0.0],
+            "size":[70.0, 70.0, 0.0],
+            "color":[1.0,1.0,1.0,1.0],
+            "anchorPoint":"CENTER_LEFT",
+            "parentOrigin":"CENTER_LEFT",
+            "actors":
+            [
+              {
+                "name":"title",
+                "anchorPoint":"CENTER_LEFT",
+                "parentOrigin":"CENTER_RIGHT",
+                "type":"TextLabel",
+                "position": [30.0, 0.0, 0.0],
+                "size":[200.0, 70.0, 0.0],
+                "pointSize":30,
+                "fontFamily":"HelveticaNeue",
+                "fontStyle":"Bold",
+                "horizontalAlignment":"BEGIN",
+                "verticalAlignment":"CENTER",
+                "textColor": [1.0,0.0,1.0,1.0],
+                "text":"{title_text}"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+```
+ The data of items should be provided to ItemFactory as an array of property maps
+ in which each map contains the data for each item, including the template to be used
+ to build the actor and the pairs of key/value to be used to replace the constants
+ defined in the template. The order of property maps in the array represents the actual
+ order of items in ItemView.
+ ### Example of defining the data of an ItemView with two items
+```
+  var itemViewData = [
+                       { "template" : "template-item",
+                         "icon_path" : "icon0.png",
+                         "title_text" : "Item 0" },
+                       { "template" : "template-item",
+                         "icon_path" : "icon1.png",
+                         "title_text" : "Item 1" }
+                     ];
+```
+ This means ItemFactory will use the template "template-item" defined in the JSON file
+ to create the item for ItemView and replace the constants "icon_path" and "title_text"
+ in the template with their actual values, e.g. "icon0.png" and "Item 0". Each item can
+ have different template and different data.
+ ### Example of creating an ItemFactory with the above JSON template and link it with an ItemView
+
+![ ](../assets/img/item-view/list.png)
+
+```
+  // Define the data of 100 items
+  var itemViewData = [];
+  for (var itemId = 0; itemId < 100; itemId++)
+  {
+    var itemData = {};
+    itemData["template"] = "template-item";
+    itemData["icon_path"] = "icon" + itemId + ".png";
+    itemData["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = itemData;
+  }
+  // Create the item factory and set the JSON template file and item view data
+  var itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+  itemFactory.data = itemViewData; // Set the ItemView data
+  // Create the item view with the given item factory
+  var itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  dali.stage.add( itemView );
+
+  // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+  // Set custom item size for the list layout
+  // If set, this will overide the predefined item size in the list layout
+  itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+  // Acticate the list layout (which will layout the items as a list)
+  itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+ ### Example of changing the data of items in ItemView dynamically
+```
+  var data = itemFactory.data;
+  data[itemId]["icon_path"] = "new-icon.png";
+  data[itemId]["title_text"] = "New Item";
+  itemFactory.data = data; // ItemView will update the changed items immediately
+```
+ @class ItemFactory
+
+*/
+
+/**
+ * Sets the file name of JSON template that contains the templates for items.
+ *
+ * @example
+ *    itemFactory.jsonTemplateFile = "item-template.json"; // ItemFactory will look for the template from this JSON file
+ *
+ * @type String
+ * @property jsonTemplateFile
+ */
+JSON_TEMPLATE_FILE
+
+/**
+ * Sets the data of ItemView
+ *
+ *  The data is an array of property maps in which each map contains the data
+ *  for each item, including the template to be used to build the actor and
+ *  the pairs of key/value to be used to replace the constants defined in the
+ *  template. The order of property maps in the array represents the actual
+ *  order of items in ItemView.
+ *
+ * @example
+ *   var itemViewData = [
+ *                        { "template" : "template-item",
+ *                          "icon_path" : "icon0.png",
+ *                          "title_text" : "Item 0" },
+ *                        { "template" : "template-item",
+ *                          "icon_path" : "icon1.png",
+ *                          "title_text" : "Item 1" }
+ *                     ];
+ *
+ *    itemFactory.data = itemViewData; // ItemFactory will look for the template from this JSON file
+ *
+ * @type Array
+ * @property data
+ */
+DATA
diff --git a/plugins/dali-script-v8/docs/content/item-view.js b/plugins/dali-script-v8/docs/content/item-view.js
new file mode 100644 (file)
index 0000000..776c5ea
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ *
+## ItemView API
+
+ ItemView is a scrollable layout container with built-in layouts to determine
+ the logical position of each item in a layout.
+ Actors are provided from an external {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}},
+ to display the currently visible items. ItemFactory is for storing the data of ItemView and
+ creating actors for ItemView on request. Each item in ItemView is identified by a unique ID,
+ and has a linear order from 0.
+ ### Example of creating an ItemView (see {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}} API for a full example)
+```
+  // Define the data of 100 items
+  var itemViewData = [];
+  for (var itemId = 0; itemId < 100; itemId++)
+  {
+    var itemData = {};
+    itemData["template"] = "template-item";
+    itemData["title_text"] = "Item " + itemId;
+    itemViewData[itemId] = itemData;
+  }
+  // Create an item factory and set the JSON template file and item view data
+  var itemFactory = new dali.ItemFactory();
+  itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+  itemFactory.data = itemViewData; // Set the ItemView data
+  // Create the item view with the given item factory
+  var itemView = new dali.Control("ItemView", itemFactory);
+  itemView.size = [stageSize.x, stageSize.y, 0.0];
+  itemView.parentOrigin = dali.CENTER_LEFT;
+  itemView.anchorPoint = dali.CENTER_LEFT;
+  dali.stage.add( itemView );
+  // Add a scroll bar to ItemView (optional)
+  var scrollBar = new dali.Control("ScrollBar");
+  scrollBar.parentOrigin = dali.TOP_RIGHT;
+  scrollBar.anchorPoint = dali.TOP_RIGHT;
+  scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+  scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+  scrollBar.indicatorHeightPolicy = "Fixed";
+  scrollBar.indicatorFixedHeight = 60.0;
+  itemView.add(scrollBar);
+  // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+  itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+  // Set custom item size for the list layout
+  // If set, this will overide the predefined item size in the list layout
+  itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+  // Acticate the list layout (which will layout the items as a list)
+  itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+ @class ItemView
+ @extends Actor
+
+*/
index e50d5cd..598d90e 100644 (file)
@@ -13,6 +13,9 @@ script_v8_plugin_src_files = \
    $(v8_plugin_dir)/actors/actor-api.cpp \
    $(v8_plugin_dir)/actors/layer-api.cpp \
    $(v8_plugin_dir)/actors/camera-actor-api.cpp \
+   $(v8_plugin_dir)/controls/control-wrapper.cpp \
+   $(v8_plugin_dir)/controls/item-factory-wrapper.cpp \
+   $(v8_plugin_dir)/controls/item-view-api.cpp \
    $(v8_plugin_dir)/constants/constants-wrapper.cpp \
    $(v8_plugin_dir)/animation/animation-api.cpp \
    $(v8_plugin_dir)/animation/animation-wrapper.cpp \
index 5bac818..371639d 100644 (file)
@@ -36,21 +36,14 @@ namespace V8Plugin
 
 namespace  // unanmed namespace
 {
+
 Actor GetActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
 {
   HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
   return Actor::DownCast( handleWrapper->mHandle );
 }
-} //unanmed namespace
-
 
-namespace TextLabelApi
-{
- Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
- {
-   return Dali::Toolkit::TextLabel::New();
- }
-}
+} //unanmed namespace
 
 /***************************************
  * ACTOR API FUNCTIONS
@@ -279,7 +272,7 @@ void ActorApi::GetChildCount( const v8::FunctionCallbackInfo<v8::Value>& args )
 }
 
 /**
- * Retrieve and child actor by index.
+ * Retrieve a child actor by index.
  *
  * @for Actor
  * @method getChildAt
index 26f8991..bcd600e 100644 (file)
@@ -28,14 +28,6 @@ namespace Dali
 namespace V8Plugin
 {
 
-namespace TextLabelApi
-{
-  /**
-   * Temporary TextView constructor
-   */
-  Actor New( const v8::FunctionCallbackInfo< v8::Value >& args );
-}
-
 namespace ActorApi
 {
 
index 336ed23..a1c0f78 100644 (file)
@@ -84,7 +84,7 @@ struct ActorApiStruct
 
 /**
  * Lookup table to match a actor type with a constructor and supported API's.
- * HandleWrapper::ActorType is used to index this table
+ * ActorWrapper::ActorType is used to index this table
  */
 const ActorApiStruct ActorApiLookup[]=
 {
@@ -305,7 +305,7 @@ v8::Handle<v8::Object> ActorWrapper::WrapActor( v8::Isolate* isolate, Actor acto
   // create an instance of the template
   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
 
-  // create teh actor object
+  // create the actor object
   ActorWrapper* pointer = new ActorWrapper( actor, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
 
   // assign the JavaScript object to the wrapper.
@@ -392,42 +392,6 @@ void ActorWrapper::NewActor( const v8::FunctionCallbackInfo< v8::Value >& args)
   args.GetReturnValue().Set( localObject );
 }
 
-void ActorWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
-{
-  v8::Isolate* isolate = args.GetIsolate();
-  v8::HandleScope handleScope( isolate );
-
-  if( !args.IsConstructCall() )
-  {
-    DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
-    return;
-  }
-
-  bool found( false );
-  std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate,  args );
-
-  if( !found )
-  {
-    DALI_SCRIPT_EXCEPTION( isolate, "missing control name" );
-    return;
-  }
-  Actor control;
-  Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( controlName );
-  if( typeInfo ) // handle, check if it has a value
-  {
-    Dali::BaseHandle handle = typeInfo.CreateInstance();
-    if( handle )
-    {
-      control = Actor::DownCast( handle );
-    }
-  }
-
-  v8::Local<v8::Object> localObject = WrapActor( isolate, control, ACTOR );
-
-  args.GetReturnValue().Set( localObject );
-}
-
-
 /**
  * given an actor type name, e.g. CameraActor returns the type, e.g. ActorWrapper::CAMERA_ACTOR
  */
@@ -443,8 +407,6 @@ ActorWrapper::ActorType ActorWrapper::GetActorType( const std::string& name )
   return ActorWrapper::UNKNOWN_ACTOR;
 }
 
-
-
 } // namespace V8Plugin
 
 } // namespace Dali
index fd12185..e84559f 100644 (file)
@@ -76,13 +76,6 @@ public:
   static void NewActor( const v8::FunctionCallbackInfo< v8::Value >& args);
 
   /**
-   * @brief Creates a new Control wrapped inside a Javascript Object.
-   * @note: the control type is passed as a parameter e.g. 'TextField'
-   * @param[in] args v8 function call arguments interpreted
-   */
-  static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
-
-  /**
    * @brief Wraps an actor of a given type
    */
   static v8::Handle<v8::Object> WrapActor(v8::Isolate* isolate, Dali::Actor actor,ActorType actorType);
@@ -107,14 +100,16 @@ public:
    */
   static ActorWrapper::ActorType GetActorType( const std::string& name );
 
-private:
+protected:
 
   /**
-   * Helper to make the actor template
+   * @brief Helper to make the actor template
    *
    */
   static v8::Handle<v8::ObjectTemplate> MakeDaliActorTemplate( v8::Isolate* isolate, ActorType actorType );
 
+private:
+
   /**
    * Helper, get an actor template given an actor type
    */
index acaacb6..edbd62b 100644 (file)
@@ -35,6 +35,7 @@
 #include <dali/public-api/common/loading-state.h>
 #include <dali/devel-api/rendering/material.h>
 #include <dali/devel-api/rendering/geometry.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
 
 namespace Dali
 {
@@ -243,6 +244,12 @@ const IntegerPair EnumTable[] =
     { "PROPERTY_ARRAY",                       Property::ARRAY          },
     { "PROPERTY_MAP",                         Property::MAP            },
     { "PROPERTY_INVALID_INDEX",               Property::INVALID_INDEX  },
+    { "PROPERTY_READ_ONLY",                   Property::READ_ONLY      },
+    { "PROPERTY_READ_WRITE",                  Property::READ_WRITE     },
+    { "PROPERTY_ANIMATABLE",                  Property::ANIMATABLE     },
+
+    { "ITEM_LAYOUT_LIST",                     Toolkit::DefaultItemLayout::LIST     },
+    { "ITEM_LAYOUT_GRID",                     Toolkit::DefaultItemLayout::GRID     },
 
 };
 const unsigned int EnumTableCount = sizeof(EnumTable)/sizeof(EnumTable[0]);
diff --git a/plugins/dali-script-v8/src/controls/control-wrapper.cpp b/plugins/dali-script-v8/src/controls/control-wrapper.cpp
new file mode 100644 (file)
index 0000000..09093a2
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * 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 <actors/actor-wrapper.h>
+#include "control-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <controls/item-view-api.h>
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mControlTemplate;
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mItemViewTemplate;
+
+Vector< void* > ControlWrapper::mControlGarbageContainer;
+
+namespace
+{
+
+
+/**
+ * pointer to a persistent template handle
+ */
+struct ControlTemplate
+{
+  v8::Persistent<v8::ObjectTemplate>* controlTemplate;
+};
+
+/**
+ * array of templates for each type of control
+ */
+const ControlTemplate ControlTemplateLookup[]=
+{
+    { &ControlWrapper::mControlTemplate },        // CONTROL
+    { &ControlWrapper::mItemViewTemplate }        // ITEMVIEW
+};
+
+/**
+ * Bitmask of API's that an control can support
+ */
+enum ControlApiBitMask
+{
+  CONTROL_API             = 1 << 0,
+  ITEMVIEW_API            = 1 << 1
+};
+
+/**
+ * structure used for the ControlApiLookup.
+ */
+struct ControlApiStruct
+{
+  const char* controlName;
+  ControlWrapper::ControlType controlType;
+  Toolkit::Control (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
+  int supportApis;
+};
+
+/**
+ * Lookup table to match a control type with a constructor and supported API's.
+ * ControlWrapper::ControlType is used to index this table
+ */
+const ControlApiStruct ControlApiLookup[]=
+{
+  {"Control",      ControlWrapper::CONTROL,      NULL,                 CONTROL_API },
+  {"ItemView",     ControlWrapper::ITEMVIEW,     ItemViewApi::New,     CONTROL_API | ITEMVIEW_API },
+};
+
+const unsigned int ControlApiLookupCount = sizeof(ControlApiLookup)/sizeof(ControlApiLookup[0]);
+
+
+/**
+ * Creates a control given a type name
+ * Uses the type registry to create an control of the correct type
+ */
+Toolkit::Control CreateControl( const v8::FunctionCallbackInfo< v8::Value >& args,
+                        const std::string& typeName )
+{
+  Toolkit::Control control;
+
+  ControlWrapper::ControlType controlType = ControlWrapper::GetControlType( typeName );
+
+  // if we don't currently have specific binding for the given control type,
+  // try to use type registry to create it
+  if( controlType == ControlWrapper::UNKNOWN_CONTROL )
+  {
+    Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
+    if( typeInfo )
+    {
+      Dali::BaseHandle handle = typeInfo.CreateInstance();
+      if( handle )
+      {
+        control = Toolkit::Control::DownCast( handle );
+        if( !control )
+        {
+          DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown control type" );
+          return Toolkit::Control();
+        }
+      }
+    }
+  }
+  else
+  {
+    // run the constructor for this type of control so it can pull out custom parameters
+    control = (ControlApiLookup[controlType].constructor)( args );
+  }
+
+  return control;
+}
+
+/**
+ * given a control type return what api's it supports
+ */
+int GetControlSupportedApis( ControlWrapper::ControlType type )
+{
+  return ControlApiLookup[type].supportApis;
+}
+
+/**
+ * Used for the ControlFunctionTable to map function names to functions
+ * with for a specific API
+ */
+struct ControlFunctions
+{
+  const char* name;               ///< function name
+  void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
+  ControlApiBitMask api;
+};
+
+/**
+ * Contains a list of all functions that can be called in
+ * ItemView
+ */
+const ControlFunctions ControlFunctionTable[]=
+{
+
+    /**************************************
+     * ItemView  API
+     **************************************/
+    { "GetLayoutCount",                  ItemViewApi::GetLayoutCount,                   ITEMVIEW_API  },
+    { "AddLayout",                       ItemViewApi::AddLayout,                        ITEMVIEW_API  },
+    { "RemoveLayout",                    ItemViewApi::RemoveLayout,                     ITEMVIEW_API  },
+    { "ActivateLayout",                  ItemViewApi::ActivateLayout,                   ITEMVIEW_API  },
+    { "GetItemSize",                     ItemViewApi::GetItemSize,                      ITEMVIEW_API  },
+    { "SetItemSize",                     ItemViewApi::SetItemSize,                      ITEMVIEW_API  },
+    { "ScrollToItem",                    ItemViewApi::ScrollToItem,                     ITEMVIEW_API  },
+    { "GetItem",                         ItemViewApi::GetItem,                          ITEMVIEW_API  },
+    { "GetItemId",                       ItemViewApi::GetItemId,                        ITEMVIEW_API  },
+    { "GetItemsRange",                   ItemViewApi::GetItemsRange,                    ITEMVIEW_API  },
+
+};
+
+const unsigned int ControlFunctionTableCount = sizeof(ControlFunctionTable)/sizeof(ControlFunctionTable[0]);
+} //un-named space
+
+
+ControlWrapper::ControlWrapper( Toolkit::Control control,
+              GarbageCollectorInterface& gc )
+: ActorWrapper( control, gc ),
+  mControl( control )
+
+{
+}
+
+ControlWrapper::~ControlWrapper()
+{
+  mControlGarbageContainer.Release();
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl(v8::Isolate* isolate, Toolkit::Control control )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  // Check whether the control is a Control
+  ControlWrapper::ControlType controlType = GetControlType( control.GetTypeName() );
+
+  if( controlType == ControlWrapper::UNKNOWN_CONTROL && Toolkit::Control::DownCast(control) )
+  {
+    controlType = ControlWrapper::CONTROL;
+  }
+
+  v8::Local<v8::Object> object = WrapControl( isolate, control, controlType );
+
+  return handleScope.Escape( object );
+}
+
+Toolkit::Control ControlWrapper::GetControl()
+{
+  return mControl;
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl( v8::Isolate* isolate, Toolkit::Control control, ControlType controlType )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  objectTemplate = GetControlTemplate( isolate, controlType );
+
+  // create an instance of the template
+  v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+  // create the control object
+  ControlWrapper* pointer = new ControlWrapper( control, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+  // assign the JavaScript object to the wrapper.
+  // This also stores Dali object, in an internal field inside the JavaScript object.
+  pointer->SetJavascriptObject( isolate, localObject );
+
+  return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ControlWrapper::GetControlTemplate( v8::Isolate* isolate, ControlWrapper::ControlType type )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  if( ControlTemplateLookup[type].controlTemplate->IsEmpty() )
+  {
+    objectTemplate = MakeDaliControlTemplate( isolate, type );
+    ControlTemplateLookup[type].controlTemplate->Reset( isolate, objectTemplate );
+  }
+  else
+  {
+    // get the object template
+    objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ControlTemplateLookup[type].controlTemplate );
+  }
+
+  return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ControlWrapper::MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  // all the controls support actor APIs
+  v8::Local<v8::ObjectTemplate> objTemplate = ActorWrapper::MakeDaliActorTemplate( isolate, ActorWrapper::ACTOR );
+
+  // find out what API's this control supports
+  int supportApis = GetControlSupportedApis( controlType );
+
+  // add our function properties
+  for( unsigned int i = 0; i < ControlFunctionTableCount; ++i )
+  {
+    const ControlFunctions property =  ControlFunctionTable[i];
+
+    // check to see if the control supports a certain type of API
+    // e.g. ItemView will support CONTROL_API and ITEMVIEW_API
+    if( supportApis &  property.api )
+    {
+      std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
+
+      objTemplate->Set( v8::String::NewFromUtf8( isolate, funcName.c_str() ),
+                      v8::FunctionTemplate::New( isolate, property.function ) );
+    }
+  }
+
+  return handleScope.Escape( objTemplate );
+}
+
+void ControlWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  if( !args.IsConstructCall() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
+    return;
+  }
+
+  bool found( false );
+  std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate,  args );
+
+  Toolkit::Control control;
+  if( found && controlName != ControlApiLookup[0].controlName )
+  {
+    control = CreateControl( args, controlName ); // create the control with the given type
+  }
+  else
+  {
+    control = Toolkit::Control::New(); // no given type, so create the base type of control
+  }
+
+  if( control )
+  {
+    v8::Local<v8::Object> localObject = WrapControl( isolate, control );
+    args.GetReturnValue().Set( localObject );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "unsupported control type" );
+  }
+}
+
+/**
+ * Given a control type name, e.g. ItemView returns the type, e.g. ControlWrapper::ITEMVIEW
+ */
+ControlWrapper::ControlType ControlWrapper::GetControlType( const std::string& name )
+{
+  for( unsigned int i = 0 ; i < ControlApiLookupCount ; i++ )
+  {
+    if( ControlApiLookup[i].controlName == name )
+    {
+      return ControlApiLookup[i].controlType;
+    }
+  }
+  return ControlWrapper::UNKNOWN_CONTROL;
+}
+
+void ControlWrapper::RegisterGarbage(void* garbage)
+{
+  mControlGarbageContainer.PushBack(garbage);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/control-wrapper.h b/plugins/dali-script-v8/src/controls/control-wrapper.h
new file mode 100644 (file)
index 0000000..dc4b636
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef __DALI_V8PLUGIN_CONTROL_WRAPPER_H__
+#define __DALI_V8PLUGIN_CONTROL_WRAPPER_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 <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/control.h>
+
+// INTERNAL INCLUDES
+#include <actors/actor-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali Control.
+ */
+class ControlWrapper : public ActorWrapper
+{
+
+public:
+
+  /**
+   * Control type used an index.
+   * These enums are used to index the ControlApiLookup table in control-wrapper.cpp.
+   * Any changes made must be reflected in the ControlApiLookup otherwise it may segfault when creating a control
+   */
+  enum ControlType
+  {
+    UNKNOWN_CONTROL = -1,
+    CONTROL         = 0,
+    ITEMVIEW        = 1
+  };
+
+  /**
+   * Constructor
+   * @param control DALi control
+   * @param gc garbage collection interface
+   */
+  ControlWrapper( Toolkit::Control control,
+                GarbageCollectorInterface& gc );
+
+  /**
+   * destructor
+   */
+  virtual ~ControlWrapper();
+
+  /**
+   * @brief Creates a new Control wrapped inside a Javascript Object.
+   * @note: the control type is passed as a parameter e.g. 'ItemView'
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+  /**
+   * @brief Wraps a control of a given type
+   */
+  static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control, ControlType controlType);
+
+  /**
+   * @brief Wraps a control, the type is looked up from the control
+   */
+  static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control );
+
+  // The Control ObjectTemplates.
+  static v8::Persistent<v8::ObjectTemplate> mControlTemplate;
+  static v8::Persistent<v8::ObjectTemplate> mItemViewTemplate;
+  static v8::Persistent<v8::ObjectTemplate> mScrollViewTemplate;
+
+  /**
+   * @return the wrapped control
+   */
+  Toolkit::Control GetControl();
+
+  /**
+   * @return the control type
+   */
+  static ControlWrapper::ControlType GetControlType( const std::string& name );
+
+  /**
+   * @brief Register the garbage to be released when the wrapped control is deleted.
+   */
+  static void RegisterGarbage(void* garbage);
+
+private:
+
+  /**
+   * Helper to make the control template
+   */
+  static v8::Handle<v8::ObjectTemplate> MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType );
+
+  /**
+   * Helper, get a control template given a control type
+   */
+  static v8::Local<v8::ObjectTemplate> GetControlTemplate( v8::Isolate* isolate, ControlType type );
+
+  Toolkit::Control mControl;
+  static Vector< void* > mControlGarbageContainer;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
diff --git a/plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp b/plugins/dali-script-v8/src/controls/item-factory-wrapper.cpp
new file mode 100644 (file)
index 0000000..62535cb
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * 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 "item-factory-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/devel-api/object/weak-handle.h>
+#include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+#include <shared/api-function.h>
+#include <shared/object-template-helper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ItemFactoryWrapper::mItemFactoryTemplate;
+
+namespace
+{
+
+typedef std::vector< Property::Map > ItemDataContainer;
+
+// Implementation of ItemFactory for providing actors to ItemView
+class ItemFactory : public Toolkit::ItemFactory
+{
+public:
+
+  /**
+   * Constructor
+   * @param application class, stored as reference
+   */
+  ItemFactory()
+  : mJsonFileLoaded(false),
+    mNumberOfItems(0)
+  {
+    mBuilder = Toolkit::Builder::New();
+  }
+
+  /**
+   * Set the name of the JSON file which defines the templates of items.
+   * @param jsonFile The JSON file
+   */
+  void SetJsonTemplateFile(std::string jsonFile)
+  {
+    if(mJsonFile != jsonFile)
+    {
+      mJsonFile = jsonFile;
+      LoadJsonFile(mJsonFile);
+
+      // Check whether any layout activated in ItemView
+      Toolkit::ItemView itemView = mItemView.GetHandle();
+      if(itemView && itemView.GetActiveLayout() != NULL)
+      {
+        // Refresh ItemView if item templates are changed
+        itemView.Refresh();
+      }
+    }
+  }
+
+  /**
+   * Returns the name of the JSON file.
+   * @return The JSON file name
+   */
+  std::string GetJsonTemplate()
+  {
+    return mJsonFile;
+  }
+
+  /**
+   * Set the data to be used to create new items.
+   *
+   * If ItemView is already created, this will immediately update ItemView with the
+   * new data.
+   *
+   * The data is an array of property maps in which each map contains the data for
+   * each item, including the template to be used to build the actor and the pairs
+   * of key/value to be used to replace the constants defined in the template.
+   * The order of property maps in the array represents the actual order of items
+   * in ItemView.
+   *
+   * @param data The array of property maps
+   */
+  void SetData(ItemDataContainer data)
+  {
+    ItemDataContainer currentData = mData;
+    mData = data;
+    mNumberOfItems = mData.size();
+
+    // Check whether any layout activated in ItemView
+    Toolkit::ItemView itemView = mItemView.GetHandle();
+    if(itemView && itemView.GetActiveLayout() != NULL)
+    {
+      unsigned int currentNumberOfItems = currentData.size();
+      unsigned int newNumberOfItems = data.size();
+
+      // Check whether any items added or deleted from the data
+      // which requires ItemView to be refreshed with the new data
+      if(currentNumberOfItems != newNumberOfItems)
+      {
+        itemView.Refresh();
+      }
+      else
+      {
+        for( unsigned int itemId = 0; itemId < newNumberOfItems; itemId++)
+        {
+          // Check whether the item is already built in ItemView
+          Actor itemActor = itemView.GetItem(itemId);
+          if(itemActor)
+          {
+            // Check if the item needs to be rebuilt
+            if( !V8Utils::IsPropertyMapIdentical(currentData[itemId], data[itemId]) )
+            {
+              // Rebuild the item with the new data
+              Actor newItemActor = NewItem(itemId);
+
+              // Replace the old item with the new one
+              itemView.ReplaceItem( Toolkit::Item( itemId, newItemActor ), 0.0f );
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Retrieve the data.
+   * @return the data.
+   */
+  ItemDataContainer GetData()
+  {
+    return mData;
+  }
+
+  /**
+   * Store a weak handle of ItemView in order to access ItemView APIs
+   * from this ItemFactory implementation
+   * @return the data.
+   */
+  void SetItemView(Toolkit::ItemView itemView)
+  {
+    mItemView = itemView;
+  }
+
+public: // From Toolkit::ItemFactory
+
+  /**
+   * Query the number of items available from the factory.
+   * The maximum available item has an ID of GetNumberOfItems() - 1.
+   */
+  virtual unsigned int GetNumberOfItems()
+  {
+    return mJsonFileLoaded ? mNumberOfItems : 0;
+  }
+
+  /**
+   * Create an Actor to represent a visible item.
+   * @param itemId
+   * @return the created actor.
+   */
+  virtual Actor NewItem(unsigned int itemId)
+  {
+    std::string itemTemplate;
+
+    Property::Map constantsMap = mData[itemId];
+    for ( unsigned int i = 0, count = constantsMap.Count(); i < count; ++i )
+    {
+      Property::Value& constantValue = constantsMap.GetValue(i);
+      if(constantsMap.GetKey(i) == "template")
+      {
+        constantValue.Get(itemTemplate);
+      }
+      else
+      {
+        mBuilder.AddConstant( constantsMap.GetKey(i), constantValue );
+      }
+    }
+
+    Actor item = Actor::DownCast( mBuilder.Create(itemTemplate) );
+    return item;
+  }
+
+private:
+
+  /**
+   * Load the JSON file.
+   * @param The JSON file name
+   */
+  void LoadJsonFile(std::string jsonFile)
+  {
+    try
+    {
+      std::string data;
+      V8Utils::GetFileContents(jsonFile, data);
+
+      mBuilder.LoadFromString(data);
+
+      mJsonFileLoaded = true;
+    }
+    catch(...)
+    {
+//      printf("invalid JSON data\n");
+      mJsonFileLoaded = false;
+    }
+  }
+
+private:
+
+  std::string mJsonFile;
+  bool mJsonFileLoaded;
+  Toolkit::Builder mBuilder;
+  unsigned int mNumberOfItems;
+  ItemDataContainer mData;
+  WeakHandle< Toolkit::ItemView > mItemView;
+};
+
+} //un-named space
+
+ItemFactoryWrapper::ItemFactoryWrapper( Toolkit::ItemFactory& factory, GarbageCollectorInterface& gc )
+: BaseWrappedObject( BaseWrappedObject::ITEMFACTORY , gc ),
+  mItemFactory( factory )
+{
+}
+
+ItemFactoryWrapper::~ItemFactoryWrapper()
+{
+}
+
+v8::Handle<v8::Object> ItemFactoryWrapper::WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  objectTemplate = GetItemFactoryTemplate( isolate );
+
+  // create an instance of the template
+  v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+  // create the ItemFactory wrapper
+  ItemFactoryWrapper* pointer =  new ItemFactoryWrapper( factory, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+  // assign the JavaScript object to the wrapper.
+  pointer->SetJavascriptObject( isolate, localObject );
+
+  return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ItemFactoryWrapper::GetItemFactoryTemplate( v8::Isolate* isolate)
+{
+  v8::EscapableHandleScope handleScope( isolate );
+  v8::Local<v8::ObjectTemplate> objectTemplate;
+
+  if( mItemFactoryTemplate.IsEmpty() )
+  {
+    objectTemplate = MakeItemFactoryTemplate( isolate );
+    mItemFactoryTemplate.Reset( isolate, objectTemplate );
+  }
+  else
+  {
+    // get the object template
+    objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, mItemFactoryTemplate );
+  }
+  return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ItemFactoryWrapper::MakeItemFactoryTemplate( v8::Isolate* isolate )
+{
+  v8::EscapableHandleScope handleScope( isolate );
+
+  v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
+
+  objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
+
+  // set property setter and getter
+  objTemplate->SetNamedPropertyHandler( ItemFactoryWrapper::PropertyGet, ItemFactoryWrapper::PropertySet);
+
+  return handleScope.Escape( objTemplate );
+}
+
+void ItemFactoryWrapper::NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate);
+
+  if( !args.IsConstructCall() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "ItemFactory constructor called without 'new'" );
+    return;
+  }
+
+  Toolkit::ItemFactory* factory = new ItemFactory();
+
+  v8::Local<v8::Object> localObject = WrapItemFactory( isolate, *factory );
+  args.GetReturnValue().Set( localObject );
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactoryFromParams( int paramIndex,
+                                             bool& found,
+                                             v8::Isolate* isolate,
+                                             const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  found = false;
+
+  v8::HandleScope handleScope( isolate );
+  BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::ITEMFACTORY, isolate, args );
+  if( wrappedObject )
+  {
+    found = true;
+    ItemFactoryWrapper* wrapper = static_cast< ItemFactoryWrapper *>(wrappedObject);
+    return wrapper->GetItemFactory();
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "no valid ItemFactory parameter" );
+    Toolkit::ItemFactory* dummyFactory = new ItemFactory();
+    return *dummyFactory; // avoid build error
+  }
+}
+
+ItemFactoryWrapper* ItemFactoryWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
+{
+  v8::HandleScope handleScope( isolate );
+
+  v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
+  void* ptr = field->Value();
+  return static_cast< ItemFactoryWrapper *>(ptr);
+}
+
+void ItemFactoryWrapper::PropertyGet( v8::Local<v8::String> propertyName,
+                                        const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // get the property name
+  std::string name = V8Utils::v8StringToStdString( propertyName );
+
+  if( std::isupper( name[0] ))
+  {
+    return;
+  }
+
+  // unwrap the object
+  ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+  if( !itemFactoryWrapper )
+  {
+    return;
+  }
+
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+  if( name == "jsonTemplateFile" )
+  {
+    std::string jsonTemplateFile = factory.GetJsonTemplate();
+    info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, jsonTemplateFile.c_str()));
+  }
+  else if( name == "data" )
+  {
+    ItemDataContainer data = factory.GetData();
+    unsigned int itemCount = data.size();
+
+    v8::Local<v8::Array> array= v8::Array::New( isolate, itemCount );
+    for( unsigned int i = 0; i < itemCount; i++)
+    {
+      v8::Local<v8::Object> mapObject = v8::Object::New( isolate );
+      V8Utils::CreatePropertyMap( isolate, data[i], mapObject );
+
+      array->Set( i, mapObject);
+    }
+
+    info.GetReturnValue().Set(array);
+  }
+  else
+  {
+    std::string error="Invalid property Get for "+name + "\n";
+    DALI_SCRIPT_EXCEPTION( isolate, error );
+  }
+}
+
+void ItemFactoryWrapper::PropertySet( v8::Local<v8::String> propertyName,
+                  v8::Local<v8::Value> javaScriptValue,
+                  const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // get the property name
+  std::string name = V8Utils::v8StringToStdString( propertyName );
+
+  // unwrap the object
+  ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+  if( !itemFactoryWrapper )
+  {
+    return;
+  }
+
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+  if( name == "jsonTemplateFile" && javaScriptValue->IsString() )
+  {
+    std::string jsonTemplateFile = V8Utils::v8StringToStdString( javaScriptValue );
+    factory.SetJsonTemplateFile(jsonTemplateFile);
+  }
+  else if( name == "data" && javaScriptValue->IsArray() )
+  {
+    v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(javaScriptValue);
+
+    ItemDataContainer data;
+
+    for( unsigned int i = 0; i < array->Length(); ++i )
+    {
+      v8::Local<v8::Value> itemData = array->Get(i);
+
+      if( itemData->IsObject() )
+      {
+        Dali::Property::Map map = V8Utils::GetPropertyMapFromObject( isolate, itemData->ToObject() );
+        data.push_back(map);
+      }
+    }
+
+    factory.SetData(data);
+  }
+  else
+  {
+    std::string error = "Invalid property Set for " + name + "\n";
+    DALI_SCRIPT_EXCEPTION( isolate, error );
+  }
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactory()
+{
+  return mItemFactory;
+}
+
+void ItemFactoryWrapper::SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView)
+{
+  ItemFactory& factory = static_cast<ItemFactory&>( itemFactory );
+  factory.SetItemView(itemView);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/item-factory-wrapper.h b/plugins/dali-script-v8/src/controls/item-factory-wrapper.h
new file mode 100644 (file)
index 0000000..cfb21fb
--- /dev/null
@@ -0,0 +1,146 @@
+#ifndef __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_H__
+#define __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_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 <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+// INTERNAL INCLUDES
+#include <shared/base-wrapped-object.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali ItemFactory.
+ */
+class ItemFactoryWrapper : public BaseWrappedObject
+{
+
+public:
+
+  /**
+   * Constructor
+   * @param factory DALi ItemFactory
+   * @param gc garbage collection interface
+   */
+  ItemFactoryWrapper( Toolkit::ItemFactory& factory,
+                GarbageCollectorInterface& gc );
+
+  /**
+   * destructor
+   */
+  virtual ~ItemFactoryWrapper();
+
+  /**
+   * @brief Creates a new ItemFactory wrapped inside a Javascript Object.
+   * @note: the item template and data are passed as a parameter e.g. 'template'
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+  /**
+   * @brief Wraps an ItemFactory
+   */
+  static v8::Handle<v8::Object> WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory );
+
+  // The ItemFactory ObjectTemplates.
+  static v8::Persistent<v8::ObjectTemplate> mItemFactoryTemplate;
+
+  /**
+   * @brief Helper to get ItemFactory from the JavaScript object held in the given function argument
+   * @param[in] paramIndex Argument index the object is held in
+   * @param[in] found Whether ItemFactory is found in the given function parameter
+   * @param[in] isolate v8 isolated instance
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static Toolkit::ItemFactory& GetItemFactoryFromParams( int paramIndex,
+                                                             bool& found,
+                                                             v8::Isolate* isolate,
+                                                             const v8::FunctionCallbackInfo< v8::Value >& args );
+
+  /**
+   * @brief Helper to store a weak handle of ItemView in the given ItemFactory
+   * @param[in] itemFactory The item factory used to provide items to the given item view
+   * @param[in] itemView The ItemView which uses the given item factory to create items
+   */
+  static void SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView);
+
+  /**
+   * @return the wrapped item factory
+   */
+  Toolkit::ItemFactory& GetItemFactory();
+
+private:
+
+  /**
+   * Helper to make the item factory template
+   */
+  static v8::Handle<v8::ObjectTemplate> MakeItemFactoryTemplate( v8::Isolate* isolate );
+
+  /**
+   * Helper, get a item factory template
+   */
+  static v8::Local<v8::ObjectTemplate> GetItemFactoryTemplate( v8::Isolate* isolate );
+
+  /**
+   * @brief get the value for a property for JavaScript object than contains a Dali ItemFactory.
+   * E.g. Get( "data", JavaScript object that wraps a Dali ItemFactory )
+   * @param[in] propertyName property name
+   * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+   * object and the return value).
+   */
+  static void PropertyGet( v8::Local<v8::String> propertyName,
+                              const v8::PropertyCallbackInfo<v8::Value>& info);
+
+  /**
+   * @brief Set the value for a property for JavaScript object than contains a Dali ItemFactory.
+   * E.g. Set( "data", itemData, JavaScript object that wraps a Dali ItemFactory)
+   * @param[in] propertyName property name
+   * @param[in] javaScriptValue javascript value to set, this is typically a number
+   * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+   * object).
+   */
+  static void PropertySet( v8::Local<v8::String> propertyName,
+                              v8::Local<v8::Value> javaScriptValue,
+                              const v8::PropertyCallbackInfo<v8::Value>& info);
+
+
+  /**
+   * @brief Extract a item factory wrapper from a javascript object
+   * @return item factory wrapper
+   */
+  static ItemFactoryWrapper* Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj);
+
+  Toolkit::ItemFactory& mItemFactory;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
diff --git a/plugins/dali-script-v8/src/controls/item-view-api.cpp b/plugins/dali-script-v8/src/controls/item-view-api.cpp
new file mode 100644 (file)
index 0000000..4852a61
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * 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 "item-view-api.h"
+
+// EXTERNAL INCLUDES
+#include <fstream>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
+#include <controls/item-factory-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace  // unanmed namespace
+{
+
+Toolkit::ItemView GetItemView( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
+  return Toolkit::ItemView::DownCast( handleWrapper->mHandle );
+}
+
+} //unanmed namespace
+
+/***************************************
+ * ITEMVIEW API FUNCTIONS
+ ***************************************/
+
+/**
+ * Constructor
+ *
+ * @for ItemView
+ * @constructor
+ * @method ItemView
+ * @return {Object} itemView
+ */
+Toolkit::Control ItemViewApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  bool found( false );
+  Toolkit::ItemFactory& factory = ItemFactoryWrapper::GetItemFactoryFromParams( 1, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid ItemFactory parameter" );
+    return Toolkit::Control();
+  }
+  else
+  {
+    Toolkit::ItemView itemView = Toolkit::ItemView::New(factory);
+    ItemFactoryWrapper::SetItemView(factory, itemView);
+    return itemView;
+  }
+}
+
+/**
+ * Query the number of layouts.
+ *
+ * @for ItemView
+ * @method getLayoutCount
+ * @return {Integer} The number of layouts.
+ */
+void ItemViewApi::GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  args.GetReturnValue().Set( v8::Integer::New( isolate, itemView.GetLayoutCount() ) );
+}
+
+/**
+ * Add a layout
+ *
+ * @for ItemView
+ * @method addLayout
+ * @param {Integer} layout The layout to be added
+ * @example
+ *      // layout is one of the following
+ *      dali.ITEM_LAYOUT_LIST
+ *      dali.ITEM_LAYOUT_GRID
+ *
+ *      itemView.addLayout( dali.ITEM_LAYOUT_LIST );
+ */
+void ItemViewApi::AddLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layout = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout parameter" );
+    return;
+  }
+
+  Toolkit::ItemLayoutPtr layoutPtr = Toolkit::DefaultItemLayout::New( static_cast<Toolkit::DefaultItemLayout::Type>(layout) );
+  itemView.AddLayout( *layoutPtr );
+}
+
+/**
+ * Remove a layout.
+ *
+ * @for ItemView
+ * @method removeLayout
+ * @param {Integer} layoutIndex The index of the ItemView layouts which must be less than getLayoutCount().
+ */
+void ItemViewApi::RemoveLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid index parameter" );
+    return;
+  }
+
+  itemView.RemoveLayout( layoutIndex );
+}
+
+/**
+ * Activate one of the layouts. This will resize the ItemView and relayout actors within the ItemView.
+ *
+ * @for ItemView
+ * @method activateLayout
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} targetSize An array of 3 numbers for the target ItemView and layout size.
+ * @param {Float} [durationSeconds] The time taken to relayout in seconds (0 by default for immediate).
+ */
+void ItemViewApi::ActivateLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 targetSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "Vector3 targetSize size parameter missing" );
+    return;
+  }
+
+  found = false;
+  float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_2, found, isolate, args, 0.0f ); // 0 by default for immediate activation
+
+  itemView.ActivateLayout( layoutIndex, targetSize, durationSeconds );
+}
+
+/**
+ * Retrieve the target size of an item in the given layout.
+ * This will return the default size for the layout unless overridden by calling setLayoutItemSize().
+ *
+ * @for ItemView
+ * @method getItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Object} targetLayoutSize An array of 3 numbers for the target ItemView and layout size.
+ * @return {Object} The target size of the item {x, y, z}.
+ */
+void ItemViewApi::GetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 targetLayoutSize = V8Utils::GetVector3Parameter( PARAMETER_2, found, isolate, args );
+  if( found )
+  {
+    Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+    Vector3 itemSize;
+    layoutPtr->GetItemSize( itemId, targetLayoutSize, itemSize );
+
+    v8::Local<v8::Object> itemSizeObject = v8::Object::New( isolate );
+
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Integer::New( isolate, itemSize.width ) );
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Integer::New( isolate, itemSize.height ) );
+    itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "z" ), v8::Integer::New( isolate, itemSize.depth ) );
+
+    args.GetReturnValue().Set( itemSizeObject );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid Vector3 target size parameter" );
+  }
+}
+
+/**
+ * Set the size of the item for the given layout which overrides the default item size for the layout.
+ *
+ * @for ItemView
+ * @method setItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} itemSize An array of 3 numbers for the size of the item.
+ * @example
+ *      itemView.setLayoutItemSize( 0, [100.0, 50.0, 0.0] );
+ */
+void ItemViewApi::SetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+    return;
+  }
+
+  found = false;
+  Vector3 itemSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+  if( found )
+  {
+    Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+    layoutPtr->SetItemSize( itemSize );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item size parameter" );
+  }
+}
+
+/**
+ * Scroll the current layout to a particular item.
+ * If calling this with zero second of duration immediately after calling activateLayout(),
+ * it will not work unless the duration of relayout animation for activateLayout is also
+ * set to zero.
+ *
+ * @for ItemView
+ * @method scrollToItem
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Float} [durationSeconds] How long the scrolling takes in seconds (0 by default for instant scrolling to the particular item).
+ */
+void ItemViewApi::ScrollToItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item Id parameter" );
+    return;
+  }
+
+  found = false;
+  float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 0.0f ); // 0 by default for instant scrolling
+
+  itemView.ScrollToItem( itemId, durationSeconds );
+}
+
+/**
+ * Given the Item ID, this returns the accompanying actor.
+ *
+ * @for ItemView
+ * @method getItem
+ * @param {Integer} itemId The Item ID of the actor required.
+ * @return {Object} The Actor corresponding to the Item ID.
+ */
+void ItemViewApi::GetItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+  if( found )
+  {
+    found = false;
+    Actor actor = itemView.GetItem( itemId );
+    if( actor )
+    {
+      found = true;
+      // wrap the actor
+      v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, actor );
+      args.GetReturnValue().Set( wrappedActor );
+    }
+  }
+
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID" );
+    return;
+  }
+}
+
+/**
+ * Returns the Item ID of the specified actor. The actor must be an item of ItemView.
+ *
+ * @for ItemView
+ * @method getItemId
+ * @param {Object} actor The actor whose Item ID is required.
+ * @return {Integer} The Item ID of the item.
+ */
+void ItemViewApi::GetItemId( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  bool found( false );
+  Actor actor = V8Utils::GetActorParameter( 0, found, isolate, args );
+  if( found )
+  {
+    args.GetReturnValue().Set( itemView.GetItemId(actor) );
+  }
+  else
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid item actor parameter" );
+    return;
+  }
+}
+
+/**
+ * Get the range of items that are currently in ItemView.
+ *
+ * @for ItemView
+ * @method getItemsRange
+ * @return {Object} The range of items in the item ID {begin, end}.
+ */
+void ItemViewApi::GetItemsRange( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+  Toolkit::ItemRange range(0, 0);
+  itemView.GetItemsRange(range);
+
+  v8::Local<v8::Object> itemRangeObject = v8::Object::New( isolate );
+
+  itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "begin" ), v8::Integer::New( isolate, range.begin ) );
+  itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "end" ), v8::Integer::New( isolate, range.end ) );
+
+  args.GetReturnValue().Set( itemRangeObject );
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
diff --git a/plugins/dali-script-v8/src/controls/item-view-api.h b/plugins/dali-script-v8/src/controls/item-view-api.h
new file mode 100644 (file)
index 0000000..7f56653
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __DALI_V8PLUGIN_ITEM_VIEW_API_H__
+#define __DALI_V8PLUGIN_ITEM_VIEW_API_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 <v8.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace ItemViewApi
+{
+
+  /**
+   * constructor
+   */
+  Toolkit::Control New( const v8::FunctionCallbackInfo< v8::Value >& args );
+
+  /**
+   * ItemView API. See item-view.h for description of functions
+   */
+  void GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void AddLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void RemoveLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void ActivateLayout( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void SetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void ScrollToItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemId( const v8::FunctionCallbackInfo< v8::Value >& args);
+  void GetItemsRange( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+}; // namespace ItemViewApi
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header __DALI_V8PLUGIN_ITEM_VIEW_API_H__
index 132dc5e..92719c7 100644 (file)
 #include <object/property-value-wrapper.h>
 #include <dali/integration-api/debug.h>
 #include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
 #include <stage/stage-wrapper.h>
 #include <image/image-wrapper.h>
 #include <animation/linear-constrainer-wrapper.h>
 #include <animation/path-constrainer-wrapper.h>
 #include <animation/path-wrapper.h>
 #include <animation/animation-wrapper.h>
+#include <controls/item-factory-wrapper.h>
 #include <events/pan-gesture-detector-wrapper.h>
 #include <object/property-buffer-wrapper.h>
 #include <rendering/geometry-wrapper.h>
@@ -70,11 +72,12 @@ const ApiFunction ConstructorFunctionTable[]=
     { "Actor",              ActorWrapper::NewActor },
     { "CameraActor",        ActorWrapper::NewActor },
     { "Layer",              ActorWrapper::NewActor },
-    { "Control",            ActorWrapper::NewControl },
+    { "Control",            ControlWrapper::NewControl },
     { "ResourceImage",      ImageWrapper::NewImage },
     { "BufferImage",        ImageWrapper::NewImage },
     { "FrameBufferImage",   ImageWrapper::NewImage },
     { "Animation",          AnimationWrapper::NewAnimation},
+    { "ItemFactory",        ItemFactoryWrapper::NewItemFactory},
     { "Shader",             ShaderWrapper::NewShader},
     { "Sampler",            SamplerWrapper::NewSampler},
     { "Material",           MaterialWrapper::NewMaterial},
index 2915670..be1739d 100644 (file)
@@ -42,6 +42,7 @@ namespace // un-named name space
 const ApiFunction HandleFunctionTable[]=
 {
   { "RegisterAnimatableProperty",            HandleWrapper::RegisterAnimatableProperty },
+  { "RegisterCustomProperty",                HandleWrapper::RegisterCustomProperty     },
 };
 
 const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
@@ -212,8 +213,8 @@ void HandleWrapper::AddInterceptsToTemplate( v8::Isolate* isolate, v8::Local<v8:
  * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
  * @example
  *
- *     var morphPropertyIdex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
- *     var fadeColorPropertyIdex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
+ *     var morphPropertyIndex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
+ *     var fadeColorPropertyIndex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
  *
  */
 void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
@@ -251,6 +252,75 @@ void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo<
   }
 }
 
+/**
+ * Register a new custom property.
+ *
+ * The object should support dynamic properties.
+ * Property names must be unused.
+ * Property indices are unique to each registered custom property in a given object.
+ * Properties can be set as non animatable using property attributes.
+ * returns dali.PROPERTY_INVALID_INDEX if registration failed.
+ *
+ * @method registerCustomProperty
+ * @for Handle
+ * @param {string} name The name of the property.
+ * @param {Object} propertyValue The new value of the property.
+ * @param {integer} accessMode The property access mode (writable, animatable etc).
+ * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
+ * @example
+ *
+ *     // access mode is one of the following
+ *     dali.PROPERTY_READ_ONLY
+ *     dali.PROPERTY_READ_WRITE
+ *     dali.PROPERTY_ANIMATABLE
+ *
+ *     var cellIndexPropertyIndex = actor.registerCustomProperty("cellIndex", 2, dali.PROPERTY_READ_WRITE);
+ *     var myCustomPropertyIndex = handle.registerCustomProperty("myCustomProperty", [10.0, 25.0, 0.0], dali.PROPERTY_READ_ONLY);
+ *
+ */
+void HandleWrapper::RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+
+  // unwrap the object
+  HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
+  if( !handleWrapper )
+  {
+    return;
+  }
+
+  Handle handle =  handleWrapper->mHandle;
+
+  bool found( false );
+  std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
+    return;
+  }
+
+  found = false;
+  Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
+  if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
+    return;
+  }
+
+  found = false;
+  int accessMode = V8Utils::GetIntegerParameter( PARAMETER_2, found, isolate, args, 0 /* default */);
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "invalid access mode parameter" );
+    return;
+  }
+  else
+  {
+    args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty( propertyName, daliPropertyValue, static_cast<Property::AccessMode>(accessMode) ) ) );
+  }
+}
+
 } // namespace V8Plugin
 
 } // namespace Dali
index 2e612c7..7356f01 100644 (file)
@@ -81,6 +81,13 @@ public:
    */
   static void RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
 
+  /**
+   * @brief Register a custom property for a JavaScript object that
+   * contains a Dali Handle.
+   * @param[in] args v8 function call arguments interpreted
+   */
+  static void RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
+
   Handle GetHandle() { return mHandle; }
   Handle mHandle;
   ConnectionTracker mConnectionTracker;
index db1c8a8..0bd9840 100644 (file)
@@ -80,6 +80,8 @@ public:
       IMAGE_ATTRIBUTES,
       ACTOR,
       ACTOR_PROPERTY,
+      ITEMVIEW,
+      ITEMFACTORY,
       RENDER_TASK,
       RENDER_TASK_LIST,
       TIMER,
index 4d09da9..b77d458 100644 (file)
@@ -149,6 +149,118 @@ void GetModuleName( const std::string& fileName, std::string& moduleName )
   }
 }
 
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2)
+{
+  bool dirty = false;
+
+  // Compare number of properties
+  if ( map1.Count() != map2.Count() )
+  {
+    dirty = true;
+  }
+  else
+  {
+    for ( unsigned int i = 0, count = map1.Count(); i < count; ++i )
+    {
+      // Compare the key first
+      if(map1.GetKey(i) != map2.GetKey(i))
+      {
+        dirty = true;
+      }
+      else
+      {
+        Property::Value& value = map1.GetValue(i);
+        Property::Value& newValue = map2.GetValue(i);
+
+        // Compare the value type
+        if(value.GetType() != newValue.GetType())
+        {
+          dirty = true;
+        }
+        else
+        {
+          // Compare the value
+          switch( value.GetType() )
+          {
+            case Property::BOOLEAN:
+            {
+              dirty = ( value.Get<bool>() != newValue.Get<bool>() );
+              break;
+            }
+            case Property::FLOAT:
+            {
+              dirty = ( value.Get<float>() != newValue.Get<float>() );
+              break;
+            }
+            case Property::INTEGER:
+            {
+              dirty = ( value.Get<int>() != newValue.Get<int>() );
+              break;
+            }
+            case Property::RECTANGLE:
+            {
+              dirty = ( value.Get< Rect<int> >() != newValue.Get< Rect<int> >() );
+              break;
+            }
+            case Property::VECTOR2:
+            {
+              dirty = ( value.Get<Vector2>() != newValue.Get<Vector2>() );
+              break;
+            }
+            case Property::VECTOR3:
+            {
+              dirty = ( value.Get<Vector3>() != newValue.Get<Vector3>() );
+              break;
+            }
+            case Property::VECTOR4:
+            {
+              dirty = ( value.Get<Vector4>() != newValue.Get<Vector4>() );
+              break;
+            }
+            case Property::MATRIX3:
+            {
+              dirty = ( value.Get<Matrix3>() != newValue.Get<Matrix3>() );
+              break;
+            }
+            case Property::MATRIX:
+            {
+              dirty = ( value.Get<Matrix>() != newValue.Get<Matrix>() );
+              break;
+            }
+            case Property::ROTATION:
+            {
+              dirty = ( value.Get<Quaternion>() != newValue.Get<Quaternion>() );
+              break;
+            }
+            case Property::STRING:
+            {
+              dirty = ( value.Get<std::string>() != newValue.Get<std::string>() );
+              break;
+            }
+            case Property::MAP:
+            {
+              dirty = ( !IsPropertyMapIdentical( value.Get<Property::Map>(), newValue.Get<Property::Map>() ) );
+              break;
+            }
+            default:
+            {
+              break;
+            }
+          }
+        }
+      }
+
+      if(dirty)
+      {
+        // Different already, no need any further comparison
+        break;
+      }
+    }
+  }
+
+  return !dirty;
+}
+
 void ReportException(  v8::Isolate* isolate, v8::TryCatch* tryCatch)
 {
   v8::HandleScope handleScope( isolate );
@@ -879,7 +991,7 @@ void CreatePropertyMap( v8::Isolate* isolate, const Property::Map& map, v8::Loca
     return;
   }
 
-  for( unsigned int index = 0; index < map.Count() - 1; ++index )
+  for( unsigned int index = 0; index < map.Count(); ++index )
   {
     const std::string& key = map.GetKey( index );
     Property::Value& value = map.GetValue( index );
index 1551868..5a86f39 100644 (file)
@@ -96,6 +96,14 @@ void GetFileName( const std::string& fullPathName, std::string& fileName);
 void GetModuleName( const std::string& fileName, std::string& moduleName );
 
 /**
+ * Compare whether two DALi property maps are identical
+ * @param[in] map1 The first property map to be compared
+ * @param[in] map2 The second property map to be compared
+ * @return true if the two specified property maps are identical or false if not.
+ */
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2);
+
+/**
  * Report an exception by writing as a warning to the Dali Log
  *
  * @param[in] try_catch The v8 TryCatch exception object