Add TextField BACKGROUND property and more Preedit style options
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 3e2c606..e9d1fe4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
 // EXTERNAL INCLUDES
 #include <cstring>
 #include <dali/public-api/adaptor-framework/key.h>
+#include <dali/devel-api/adaptor-framework/key-devel.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/object/property-helper-devel.h>
+#include <dali/devel-api/actors/actor-devel.h>
 #include <dali/public-api/object/type-registry-helper.h>
-#include <dali/integration-api/adaptors/adaptor.h>
 #include <dali/integration-api/debug.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/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
-#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-field-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>
 #include <dali-toolkit/internal/text/text-effects-style.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>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 
 using namespace Dali::Toolkit::Text;
 
@@ -62,23 +69,6 @@ namespace // unnamed namespace
 
 namespace
 {
-
-const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "BEGIN",  Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN  },
-  { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER },
-  { "END",    Toolkit::Text::Layout::HORIZONTAL_ALIGN_END    },
-};
-const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
-
-const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "TOP",    Toolkit::Text::Layout::VERTICAL_ALIGN_TOP    },
-  { "CENTER", Toolkit::Text::Layout::VERTICAL_ALIGN_CENTER },
-  { "BOTTOM", Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM },
-};
-const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
-
 // Type registration
 BaseHandle Create()
 {
@@ -101,8 +91,8 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "horizontalAlignment",
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                   )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor",                            VECTOR4,   TEXT_COLOR                           )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor",                 VECTOR4,   PLACEHOLDER_TEXT_COLOR               )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowOffset",                         VECTOR2,   SHADOW_OFFSET                        )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowColor",                          VECTOR4,   SHADOW_COLOR                         )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "reservedProperty01",                   STRING,    RESERVED_PROPERTY_01                 )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "reservedProperty02",                   STRING,    RESERVED_PROPERTY_02                 )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
@@ -135,6 +125,16 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "emboss",
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputEmboss",                          MAP,       INPUT_EMBOSS                         )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "outline",                              MAP,       OUTLINE                              )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputOutline",                         MAP,       INPUT_OUTLINE                        )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "hiddenInputSettings",                  MAP,       HIDDEN_INPUT_SETTINGS                )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "pixelSize",                            FLOAT,     PIXEL_SIZE                           )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableSelection",                      BOOLEAN,   ENABLE_SELECTION                     )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholder",                          MAP,       PLACEHOLDER                          )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "ellipsis",                             BOOLEAN,   ELLIPSIS                             )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableShiftSelection",           BOOLEAN,   ENABLE_SHIFT_SELECTION               )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandle",               BOOLEAN,   ENABLE_GRAB_HANDLE                   )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "matchSystemLanguageDirection",   BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION      )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup",          BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP             )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "textBackground",                 VECTOR4,   BACKGROUND                           )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -252,9 +252,9 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
           const float pointSize = value.Get< float >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
 
-          if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
+          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
           {
-            impl.mController->SetDefaultPointSize( pointSize );
+            impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
           }
         }
         break;
@@ -289,15 +289,10 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string& alignStr = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
-
-          Layout::HorizontalAlignment alignment( Layout::HORIZONTAL_ALIGN_BEGIN );
-          if( Scripting::GetEnumeration< Layout::HorizontalAlignment >( alignStr.c_str(),
-                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                        alignment ) )
+          Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+          if( GetHorizontalAlignmentEnumeration( value, alignment ) )
           {
+            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
             impl.mController->SetHorizontalAlignment( alignment );
           }
         }
@@ -307,16 +302,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string& alignStr = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
-
-          Layout::VerticalAlignment alignment( Layout::VERTICAL_ALIGN_BOTTOM );
-          if( Scripting::GetEnumeration< Layout::VerticalAlignment >( alignStr.c_str(),
-                                                                      VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                      VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                      alignment ) )
+          Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+          if( GetVerticalAlignmentEnumeration( value, alignment ) )
           {
             impl.mController->SetVerticalAlignment( alignment );
+            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
           }
         }
         break;
@@ -352,36 +342,6 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
-      case Toolkit::TextField::Property::SHADOW_OFFSET:
-      {
-        if( impl.mController )
-        {
-          const Vector2& shadowOffset = value.Get< Vector2 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_OFFSET %f,%f\n", impl.mController.Get(), shadowOffset.x, shadowOffset.y );
-
-          if ( impl.mController->GetShadowOffset() != shadowOffset )
-          {
-            impl.mController->SetShadowOffset( shadowOffset );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextField::Property::SHADOW_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4& shadowColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_COLOR %f,%f,%f,%f\n", impl.mController.Get(), shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a );
-
-          if ( impl.mController->GetShadowColor() != shadowColor )
-          {
-            impl.mController->SetShadowColor( shadowColor );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
       {
         if( impl.mDecorator )
@@ -600,7 +560,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
         if (control == textField)
         {
-          impl.mImfManager.ApplyOptions( impl.mInputMethodOptions );
+          impl.mInputMethodContext.ApplyOptions( impl.mInputMethodOptions );
         }
         break;
       }
@@ -723,6 +683,112 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
+      {
+        const Property::Map* map = value.GetMap();
+        if (map)
+        {
+          impl.mController->SetHiddenInputOption(*map);
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::PIXEL_SIZE:
+      {
+        if( impl.mController )
+        {
+          const float pixelSize = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
+
+          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
+          {
+            impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
+          }
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::ENABLE_SELECTION:
+      {
+        if( impl.mController )
+        {
+          const bool enableSelection = value.Get< bool >();
+           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
+          impl.mController->SetSelectionEnabled( enableSelection );
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::PLACEHOLDER:
+      {
+        const Property::Map* map = value.GetMap();
+        if( map )
+        {
+          impl.mController->SetPlaceholderProperty( *map );
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::ELLIPSIS:
+      {
+        if( impl.mController )
+        {
+          const bool ellipsis = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
+
+          impl.mController->SetTextElideEnabled( ellipsis );
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
+      {
+        if( impl.mController )
+        {
+          const bool shiftSelection = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
+
+          impl.mController->SetShiftSelectionEnabled( shiftSelection );
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
+      {
+        if( impl.mController )
+        {
+          const bool grabHandleEnabled = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
+
+          impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        if( impl.mController )
+        {
+          impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+      {
+        if( impl.mController )
+        {
+          const bool grabHandlePopupEnabled = value.Get<bool>();
+          DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+          impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+          break;
+        }
+      }
+      case Toolkit::DevelTextField::Property::BACKGROUND:
+      {
+        if( impl.mController )
+        {
+          const Vector4 backgroundColor = value.Get< Vector4 >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a );
+
+          impl.mController->SetBackgroundEnabled( true );
+          impl.mController->SetBackgroundColor( backgroundColor );
+        }
+        break;
+      }
     } // switch
   } // textfield
 }
@@ -792,7 +858,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          value = impl.mController->GetDefaultPointSize();
+          value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
         }
         break;
       }
@@ -813,10 +879,9 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
-                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-          if( name )
+          const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
+
+          if ( name )
           {
             value = std::string( name );
           }
@@ -827,9 +892,8 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
-                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
+
           if( name )
           {
             value = std::string( name );
@@ -853,22 +917,6 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
-      case Toolkit::TextField::Property::SHADOW_OFFSET:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowOffset();
-        }
-        break;
-      }
-      case Toolkit::TextField::Property::SHADOW_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowColor();
-        }
-        break;
-      }
       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
       {
         if( impl.mDecorator )
@@ -1086,12 +1134,104 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         GetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
         break;
       }
+      case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
+      {
+        Property::Map map;
+        impl.mController->GetHiddenInputOption(map);
+        value = map;
+        break;
+      }
+      case Toolkit::TextField::Property::PIXEL_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::ENABLE_SELECTION:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsSelectionEnabled();
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::PLACEHOLDER:
+      {
+        Property::Map map;
+        impl.mController->GetPlaceholderProperty( map );
+        value = map;
+        break;
+      }
+      case Toolkit::TextField::Property::ELLIPSIS:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsTextElideEnabled();
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsShiftSelectionEnabled();
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsGrabHandleEnabled();
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsMatchSystemLanguageDirection();
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsGrabHandlePopupEnabled();
+        }
+        break;
+      }
+      case Toolkit::DevelTextField::Property::BACKGROUND:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetBackgroundColor();
+        }
+        break;
+      }
     } //switch
   }
 
   return value;
 }
 
+void TextField::SelectWholeText()
+{
+  if( mController && mController->IsShowingRealText() )
+  {
+    mController->SelectEvent( 0.f, 0.f, true );
+    SetKeyInputFocus();
+  }
+}
+
+InputMethodContext TextField::GetInputMethodContext()
+{
+  return mInputMethodContext;
+}
+
 bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   Dali::BaseHandle handle( object );
@@ -1148,10 +1288,12 @@ void TextField::OnInitialize()
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
 
+  mInputMethodContext = InputMethodContext::New( self );
+
   mController->GetLayoutEngine().SetLayout( Layout::Engine::SINGLE_LINE_BOX );
 
   // Enables the text input.
-  mController->EnableTextInput( mDecorator );
+  mController->EnableTextInput( mDecorator, mInputMethodContext );
 
   // Enables the horizontal scrolling after the text input has been enabled.
   mController->SetHorizontalScrollEnabled( true );
@@ -1162,12 +1304,18 @@ void TextField::OnInitialize()
   // Disable the smooth handle panning.
   mController->SetSmoothHandlePanEnabled( false );
 
+  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, &TextField::OnTouched );
 
   // Set BoundingBox to stage size if not already set.
@@ -1188,6 +1336,8 @@ void TextField::OnInitialize()
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
   self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
 
+  DevelControl::SetInputMethodContext( *this, mInputMethodContext );
+
   if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy )
   {
     EnableClipping();
@@ -1206,37 +1356,74 @@ void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       // Property system did not set the font so should update it.
       mController->UpdateAfterFontChange( newFont );
+      RelayoutRequest();
       break;
     }
 
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      RelayoutRequest();
       break;
     }
     case StyleChange::THEME_CHANGE:
     {
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      // Nothing to do, let control base class handle this
       break;
     }
   }
+
+  // Up call to Control
+  Control::OnStyleChange( styleManager, change );
 }
 
 Vector3 TextField::GetNaturalSize()
 {
-  return mController->GetNaturalSize();
+  Extents padding;
+  padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+
+  Vector3 naturalSize = mController->GetNaturalSize();
+  naturalSize.width += ( padding.start + padding.end );
+  naturalSize.height += ( padding.top + padding.bottom );
+
+  return naturalSize;
 }
 
 float TextField::GetHeightForWidth( float width )
 {
-  return mController->GetHeightForWidth( width );
+  Extents padding;
+  padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+  return mController->GetHeightForWidth( width ) + padding.top + padding.bottom;
 }
 
 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+  Actor self = Self();
+
+  Extents padding;
+  padding = self.GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+
+  Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) );
+
+  // Support Right-To-Left of padding
+  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( self.GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+  if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+  {
+    std::swap( padding.start, padding.end );
+  }
+
+  if( mStencil )
+  {
+    mStencil.SetPosition( padding.start, padding.top );
+  }
+  if( mActiveLayer )
+  {
+    mActiveLayer.SetPosition( padding.start, padding.top );
+  }
+
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
@@ -1255,6 +1442,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
     }
 
     RenderText( updateTextType );
+
   }
 
   // The text-field emits signals when the input style changes. These changes of style are
@@ -1271,7 +1459,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
       {
         // @note: The callback manager takes the ownership of the callback object.
         mIdleCallback = MakeCallback( this, &TextField::OnIdleSignal );
-        adaptor.AddIdle( mIdleCallback );
+        adaptor.AddIdle( mIdleCallback, false );
       }
     }
   }
@@ -1285,15 +1473,25 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
   {
     if( mRenderer )
     {
+      Dali::Toolkit::TextField handle = Dali::Toolkit::TextField( GetOwner() );
+
       renderableActor = mRenderer->Render( mController->GetView(),
+                                           handle,
+                                           Property::INVALID_INDEX, // Animatable property not supported
                                            mAlignmentOffset,
                                            DepthIndex::CONTENT );
     }
 
     if( renderableActor != mRenderableActor )
     {
+      UnparentAndReset( mBackgroundActor );
       UnparentAndReset( mRenderableActor );
       mRenderableActor = renderableActor;
+
+      if ( mRenderableActor )
+      {
+        mBackgroundActor = mController->CreateBackgroundActor();
+      }
     }
   }
 
@@ -1301,46 +1499,94 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
   {
     const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
 
-    mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset, scrollOffset.y );
+    float renderableActorPositionX, renderableActorPositionY;
+
+    if( mStencil )
+    {
+      renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
+      renderableActorPositionY = scrollOffset.y;
+    }
+    else
+    {
+      Extents padding;
+      padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+
+      // Support Right-To-Left of padding
+      Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+      if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+      {
+        std::swap( padding.start, padding.end );
+      }
+
+      renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
+      renderableActorPositionY = scrollOffset.y + padding.top;
+    }
+
+    mRenderableActor.SetPosition( renderableActorPositionX, renderableActorPositionY );
 
     // Make sure the actors are parented correctly with/without clipping
     Actor self = mStencil ? mStencil : Self();
 
-    for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
+    Actor highlightActor;
+
+    for( std::vector<Actor>::iterator it = mClippingDecorationActors.begin(),
            endIt = mClippingDecorationActors.end();
          it != endIt;
          ++it )
     {
       self.Add( *it );
+      it->LowerToBottom();
+
+      if ( it->GetName() == "HighlightActor" )
+      {
+        highlightActor = *it;
+      }
     }
     mClippingDecorationActors.clear();
 
     self.Add( mRenderableActor );
+
+    if ( mBackgroundActor )
+    {
+      if ( mDecorator && mDecorator->IsHighlightVisible() )
+      {
+        self.Add( mBackgroundActor );
+        mBackgroundActor.SetPosition( renderableActorPositionX, renderableActorPositionY); // In text field's coords.
+        mBackgroundActor.LowerBelow( highlightActor );
+      }
+      else
+      {
+        mRenderableActor.Add( mBackgroundActor );
+        mBackgroundActor.SetPosition( 0.0f, 0.0f ); // In renderable actor's coords.
+        mBackgroundActor.LowerToBottom();
+      }
+    }
   }
 }
 
 void TextField::OnKeyInputFocusGained()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.ApplyOptions( mInputMethodOptions );
 
-  mImfManager.ApplyOptions( mInputMethodOptions );
-
-  mImfManager.StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
-
-  mImfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
+    mInputMethodContext.StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
 
-  // Notify that the text editing start.
-  mImfManager.Activate();
+    mInputMethodContext.EventReceivedSignal().Connect( this, &TextField::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, &TextField::OnClipboardTextSelected );
-   }
+  if ( notifier )
+  {
+    notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
+  }
 
   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
 
@@ -1350,16 +1596,17 @@ void TextField::OnKeyInputFocusGained()
 void TextField::OnKeyInputFocusLost()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
+  if ( mInputMethodContext )
+  {
+    mInputMethodContext.StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
+    // The text editing is finished. Therefore the inputMethodContext don't have restore activation.
+    mInputMethodContext.SetRestoreAfterFocusLost( false );
 
-  mImfManager.StatusChangedSignal().Disconnect( this, &TextField::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();
-
-  mImfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
+    // Notify that the text editing finish.
+    mInputMethodContext.Deactivate();
 
+    mInputMethodContext.EventReceivedSignal().Disconnect( this, &TextField::OnInputMethodContextEvent );
+  }
   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
 
   if ( notifier )
@@ -1375,11 +1622,14 @@ void TextField::OnKeyInputFocusLost()
 void TextField::OnTap( const TapGesture& gesture )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::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
-  mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
+  Extents padding;
+  padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+  mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x - padding.start, gesture.localPoint.y - padding.top );
 
   SetKeyInputFocus();
 }
@@ -1391,9 +1641,13 @@ void TextField::OnPan( const PanGesture& gesture )
 
 void TextField::OnLongPress( const LongPressGesture& gesture )
 {
-  mImfManager.Activate();
-
-  mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
+  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 );
 
   SetKeyInputFocus();
 }
@@ -1402,7 +1656,7 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
 
-  if( Dali::DALI_KEY_ESCAPE == event.keyCode || "Return" == event.keyPressedName ) // Make a Dali key code for this
+  if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
   {
     // Make sure ClearKeyInputFocus when only key is up
     if( event.state == KeyEvent::Up )
@@ -1412,6 +1666,11 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
 
     return true;
   }
+  else if( Dali::DevelKey::DALI_KEY_RETURN == event.keyCode )
+  {
+    // Do nothing when enter is comming.
+    return false;
+  }
 
   return mController->KeyEvent( event );
 }
@@ -1493,7 +1752,10 @@ void TextField::AddDecoration( Actor& actor, bool needsClipping )
     }
     else
     {
+      actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+      actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
       Self().Add( actor );
+      mActiveLayer = actor;
     }
   }
 }
@@ -1510,10 +1772,10 @@ void TextField::OnStageConnect( Dali::Actor actor )
   }
 }
 
-ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+InputMethodContext::CallbackData TextField::OnInputMethodContextEvent( Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
-  return mController->OnImfEvent( imfManager, imfEvent );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName );
+  return mController->OnInputMethodContextEvent( inputMethodContext, inputMethodContextEvent );
 }
 
 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
@@ -1537,16 +1799,16 @@ void TextField::EnableClipping()
   {
     // Creates an extra control to be used as stencil buffer.
     mStencil = Control::New();
-    mStencil.SetAnchorPoint( AnchorPoint::CENTER );
-    mStencil.SetParentOrigin( ParentOrigin::CENTER );
+    mStencil.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+    mStencil.SetParentOrigin( ParentOrigin::TOP_LEFT );
 
     // Creates a background visual. Even if the color is transparent it updates the stencil.
     mStencil.SetProperty( Toolkit::Control::Property::BACKGROUND,
-                          Property::Map().Add( Toolkit::Visual::Property::TYPE, DevelVisual::COLOR ).
+                          Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR ).
                           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 );