Multiline - Create a text-editor control. 93/56893/5
authorVictor Cebollada <v.cebollada@samsung.com>
Mon, 11 Jan 2016 09:00:21 +0000 (09:00 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Mon, 18 Jan 2016 12:02:42 +0000 (12:02 +0000)
Change-Id: If2d26ec599b30fcb121d0ff720f67fc9f6b0263b
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
19 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp [new file with mode: 0644]
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/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/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/controls/text-controls/text-field.h
dali-toolkit/styles/480x800/dali-toolkit-default-theme.json
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
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

index 5951546..e338ad4 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
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;
+}
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
 
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 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 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 7b4b130..3717470 100644 (file)
@@ -131,6 +131,17 @@ 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" }
     }
   }
 }
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" }
     }
   }
 }
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