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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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__
$(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 \
$(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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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__
*/
virtual bool OnKeyEvent(const KeyEvent& event);
+// From ControlInterface
+
/**
* @copydoc Text::ControlInterface::AddDecoration()
*/
*/
virtual void MaxLengthReached();
+private: // Implementation
+
/**
* @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
*/
*/
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
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
$(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 \
}
}
-void Controller::SetMaximumNumberOfCharacters( int maxCharacters )
+void Controller::SetMaximumNumberOfCharacters( Length maxCharacters )
{
- if( maxCharacters >= 0 )
- {
- mImpl->mMaximumNumberOfCharacters = maxCharacters;
- }
+ mImpl->mMaximumNumberOfCharacters = maxCharacters;
}
int Controller::GetMaximumNumberOfCharacters()
*
* @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
};
/**
- * @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
};
};
// 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();
TextField& operator=( const TextField& handle );
/**
- * @brief Destructor
+ * @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
*/
* 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 );
"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" }
}
}
}
"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" }
}
}
}
+ [Popup](@ref popup)
+ [Scroll View](@ref scroll-view)
+ TableView
+ + [Text Editor](@ref text-editor)
+ [Text Field](@ref text-field)
+ [Text Label](@ref text-label)
--- /dev/null
+<!--
+/**-->
+
+# 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) |
+
+
+*/
--- /dev/null
+<!--
+/**-->
+
+# 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.
+
+*/
--- /dev/null
+<!--
+/**-->
+
+# 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
+
+*/
### 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
### 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