Add a TextEditor property to limit input to maximum characters
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-editor-impl.cpp
index 77974d5..5eaecfa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
 #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/common/stage.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/object/property-helper-devel.h>
 #include <dali/public-api/object/type-registry-helper.h>
-#include <dali/integration-api/adaptors/adaptor.h>
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/public-api/text/text-enumerations.h>
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
+#include <dali-toolkit/devel-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
@@ -44,6 +42,7 @@
 #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>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 
 using namespace Dali::Toolkit::Text;
 
@@ -63,7 +62,7 @@ namespace // unnamed namespace
 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;
+const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
 const float DEFAULT_SCROLL_SPEED = 1200.f; ///< The default scroll speed for the text editor in pixels/second.
 } // unnamed namespace
 
@@ -83,7 +82,6 @@ BaseHandle Create()
 // 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                          )
@@ -136,12 +134,35 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "lineWrapMode",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "placeholderText",                STRING,    PLACEHOLDER_TEXT                     )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "placeholderTextColor",           VECTOR4,   PLACEHOLDER_TEXT_COLOR               )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableShiftSelection",           BOOLEAN,   ENABLE_SHIFT_SELECTION               )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableGrabHandle",               BOOLEAN,   ENABLE_GRAB_HANDLE                   )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "matchSystemLanguageDirection",   BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION      )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "renderingBackend",               INTEGER,   RENDERING_BACKEND                    )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "maxLength",                      INTEGER,   MAX_LENGTH                           )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
+DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
 
 DALI_TYPE_REGISTRATION_END()
 
+const char * const IMAGE_MAP_FILENAME_STRING = "filename";
+
+/// Retrieves a filename from a value that is a Property::Map
+std::string GetImageFileNameFromPropertyValue( const Property::Value& value )
+{
+  std::string filename;
+  const Property::Map* map = value.GetMap();
+  if( map )
+  {
+    const Property::Value* filenameValue = map->Find( IMAGE_MAP_FILENAME_STRING );
+    if( filenameValue )
+    {
+      filenameValue->Get( filename );
+    }
+  }
+  return filename;
+}
+
 } // namespace
 
 Toolkit::TextEditor TextEditor::New()
@@ -172,7 +193,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
 
     switch( index )
     {
-      case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+      case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
       {
         int backend = value.Get< int >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
@@ -348,90 +369,90 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       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() );
+        const std::string imageFileName = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator )
+        if( impl.mDecorator && imageFileName.size() )
         {
-          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName );
           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() );
+        const std::string imageFileName = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator )
+        if( impl.mDecorator && imageFileName.size() )
         {
-          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+          impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
       {
-        const Image image = Scripting::NewImage( value );
+        const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && image )
+        if( impl.mDecorator && filename.size() )
         {
-          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+          impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
         }
         break;
@@ -732,6 +753,36 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
+      {
+        if( impl.mController )
+        {
+          const bool grabHandleEnabled = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
+
+          impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
+        }
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        if( impl.mController )
+        {
+          impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
+        }
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+      {
+        if( impl.mController )
+        {
+          const int max = value.Get< int >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max );
+
+          impl.mController->SetMaximumNumberOfCharacters( max );
+        }
+        break;
+      }
     } // switch
   } // texteditor
 }
@@ -748,7 +799,7 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
 
     switch( index )
     {
-      case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+      case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
       {
         value = impl.mRenderingBackend;
         break;
@@ -870,11 +921,7 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       {
         if( impl.mDecorator )
         {
-          ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
-          if( image )
-          {
-            value = image.GetUrl();
-          }
+          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
         }
         break;
       }
@@ -882,11 +929,7 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       {
         if( impl.mDecorator )
         {
-          ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
-          if( image )
-          {
-            value = image.GetUrl();
-          }
+          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
         }
         break;
       }
@@ -1124,12 +1167,46 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsGrabHandleEnabled();
+        }
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsMatchSystemLanguageDirection();
+        }
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetMaximumNumberOfCharacters();
+        }
+        break;
+      }
     } //switch
   }
 
   return value;
 }
 
+InputMethodContext TextEditor::GetInputMethodContext()
+{
+  return mInputMethodContext;
+}
+
+DevelTextEditor::MaxLengthReachedSignalType& TextEditor::MaxLengthReachedSignal()
+{
+  return mMaxLengthReachedSignal;
+}
+
 bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   Dali::BaseHandle handle( object );
@@ -1145,6 +1222,14 @@ bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface
   {
     editor.InputStyleChangedSignal().Connect( tracker, functor );
   }
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) )
+  {
+    if( editor )
+    {
+      Internal::TextEditor& editorImpl( GetImpl( editor ) );
+      editorImpl.MaxLengthReachedSignal().Connect( tracker, functor );
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1178,10 +1263,12 @@ void TextEditor::OnInitialize()
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
 
+  mInputMethodContext = InputMethodContext::New( self );
+
   mController->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX );
 
   // Enables the text input.
-  mController->EnableTextInput( mDecorator );
+  mController->EnableTextInput( mDecorator, mInputMethodContext );
 
   // Enables the vertical scrolling after the text input has been enabled.
   mController->SetVerticalScrollEnabled( true );
@@ -1198,12 +1285,15 @@ void TextEditor::OnInitialize()
   mController->SetNoTextDoubleTapAction( Controller::NoTextTap::HIGHLIGHT );
   mController->SetNoTextLongPressAction( Controller::NoTextTap::HIGHLIGHT );
 
+  // Sets layoutDirection value
+  Dali::Stage stage = Dali::Stage::GetCurrent();
+  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( stage.GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+  mController->SetLayoutDirection( layoutDirection );
+
   // Forward input events to controller
   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
 
-  mImfManager = ImfManager::Get();
-
   self.TouchSignal().Connect( this, &TextEditor::OnTouched );
 
   // Set BoundingBox to stage size if not already set.
@@ -1227,10 +1317,12 @@ void TextEditor::OnInitialize()
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
   self.OnStageSignal().Connect( this, &TextEditor::OnStageConnect );
 
+  DevelControl::SetInputMethodContext( *this, mInputMethodContext );
+
   // Creates an extra control to be used as stencil buffer.
   mStencil = Control::New();
-  mStencil.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-  mStencil.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  mStencil.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  mStencil.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
 
   // Creates a background visual. Even if the color is transparent it updates the stencil.
   mStencil.SetProperty( Toolkit::Control::Property::BACKGROUND,
@@ -1238,7 +1330,7 @@ void TextEditor::OnInitialize()
                         Add( ColorVisual::Property::MIX_COLOR, Color::TRANSPARENT ) );
 
   // Enable the clipping property.
-  mStencil.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+  mStencil.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
   mStencil.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
 
   self.Add( mStencil );
@@ -1316,14 +1408,14 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
   if( mStencil )
   {
-    mStencil.SetPosition( padding.start, padding.top );
+    mStencil.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
   }
   if( mActiveLayer )
   {
-    mActiveLayer.SetPosition( padding.start, padding.top );
+    mActiveLayer.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
   }
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
@@ -1359,7 +1451,7 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
       {
         // @note: The callback manager takes the ownership of the callback object.
         mIdleCallback = MakeCallback( this, &TextEditor::OnIdleSignal );
-        adaptor.AddIdle( mIdleCallback );
+        adaptor.AddIdle( mIdleCallback, false );
       }
     }
   }
@@ -1414,23 +1506,24 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
 void TextEditor::OnKeyInputFocusGained()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
 
-  mImfManager.StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
-
-  mImfManager.EventReceivedSignal().Connect( this, &TextEditor::OnImfEvent );
-
-  // Notify that the text editing start.
-  mImfManager.Activate();
+    mInputMethodContext.EventReceivedSignal().Connect( this, &TextEditor::OnInputMethodContextEvent );
 
-  // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
-  mImfManager.SetRestoreAfterFocusLost( true );
+    // Notify that the text editing start.
+    mInputMethodContext.Activate();
 
-   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+    // When window gain lost focus, the InputMethodContext is deactivated. Thus when window gain focus again, the InputMethodContext must be activated.
+    mInputMethodContext.SetRestoreAfterFocusLost( true );
+  }
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
 
-   if ( notifier )
-   {
-      notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
-   }
+  if ( notifier )
+  {
+    notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
+  }
 
   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
 
@@ -1440,17 +1533,18 @@ void TextEditor::OnKeyInputFocusGained()
 void TextEditor::OnKeyInputFocusLost()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get() );
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
 
-  mImfManager.StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
-
-  // The text editing is finished. Therefore the imf manager don't have restore activation.
-  mImfManager.SetRestoreAfterFocusLost( false );
-
-  // Notify that the text editing finish.
-  mImfManager.Deactivate();
+    // The text editing is finished. Therefore the InputMethodContext don't have restore activation.
+    mInputMethodContext.SetRestoreAfterFocusLost( false );
 
-  mImfManager.EventReceivedSignal().Disconnect( this, &TextEditor::OnImfEvent );
+    // Notify that the text editing finish.
+    mInputMethodContext.Deactivate();
 
+    mInputMethodContext.EventReceivedSignal().Disconnect( this, &TextEditor::OnInputMethodContextEvent );
+  }
   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
 
   if ( notifier )
@@ -1466,9 +1560,10 @@ void TextEditor::OnKeyInputFocusLost()
 void TextEditor::OnTap( const TapGesture& gesture )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
-
-  mImfManager.Activate();
-
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.Activate();
+  }
   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
   Extents padding;
   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
@@ -1484,8 +1579,10 @@ void TextEditor::OnPan( const PanGesture& gesture )
 
 void TextEditor::OnLongPress( const LongPressGesture& gesture )
 {
-  mImfManager.Activate();
-
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.Activate();
+  }
   Extents padding;
   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
   mController->LongPressEvent( gesture.state, gesture.localPoint.x - padding.start, gesture.localPoint.y - padding.top );
@@ -1524,7 +1621,8 @@ void TextEditor::TextChanged()
 
 void TextEditor::MaxLengthReached()
 {
-  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+  Dali::Toolkit::TextEditor handle( GetOwner() );
+  mMaxLengthReachedSignal.Emit( handle );
 }
 
 void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
@@ -1591,8 +1689,8 @@ void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
     }
     else
     {
-      actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
-      actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+      actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+      actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
       Self().Add( actor );
       mActiveLayer = actor;
     }
@@ -1623,8 +1721,8 @@ void TextEditor::UpdateScrollBar()
   {
     mScrollBar = Toolkit::ScrollBar::New( Toolkit::ScrollBar::Vertical );
     mScrollBar.SetIndicatorHeightPolicy( Toolkit::ScrollBar::Variable );
-    mScrollBar.SetParentOrigin( ParentOrigin::TOP_RIGHT );
-    mScrollBar.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
+    mScrollBar.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT );
+    mScrollBar.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT );
     mScrollBar.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
     mScrollBar.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::WIDTH );
 
@@ -1678,7 +1776,7 @@ void TextEditor::UpdateScrollBar()
   {
     mAnimation = Animation::New( mAnimationPeriod.durationSeconds );
   }
-  indicator.SetOpacity(1.0f);
+  indicator.SetProperty( Actor::Property::OPACITY,1.0f);
   mAnimation.AnimateTo( Property( indicator, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN, mAnimationPeriod );
   mAnimation.Play();
   mAnimation.FinishedSignal().Connect( this, &TextEditor::OnScrollIndicatorAnimationFinished );
@@ -1707,24 +1805,19 @@ void TextEditor::OnStageConnect( Dali::Actor actor )
   }
 }
 
-ImfManager::ImfCallbackData TextEditor::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+InputMethodContext::CallbackData TextEditor::OnInputMethodContextEvent( Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
-  return mController->OnImfEvent( imfManager, imfEvent );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName );
+  return mController->OnInputMethodContextEvent( inputMethodContext, inputMethodContextEvent );
 }
 
 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;
-    }
+    Property::Map map;
+    map[ IMAGE_MAP_FILENAME_STRING ] = mDecorator->GetHandleImage( handleType, handleImageType );
+    value = map;
   }
 }
 
@@ -1788,7 +1881,7 @@ void TextEditor::ApplyScrollPosition()
   }
   else if ( Equals( scrollAmount, 0.0f, Math::MACHINE_EPSILON_1 ))
   {
-    mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset, scrollOffset.y - scrollAmount );
+    mRenderableActor.SetProperty( Actor::Property::POSITION, Vector2( scrollOffset.x + mAlignmentOffset, scrollOffset.y - scrollAmount ));
   }
   else
   {