Merge "Change MatchSystemLanguageDirection is true." into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-editor-impl.cpp
index 75677ca..db7096a 100644 (file)
@@ -147,6 +147,8 @@ DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextEditor, "selectedText",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "fontSizeScale",                        FLOAT,     FONT_SIZE_SCALE                     )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "primaryCursorPosition",                INTEGER,   PRIMARY_CURSOR_POSITION             )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "grabHandleColor",                      VECTOR4,   GRAB_HANDLE_COLOR                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "enableGrabHandlePopup",                BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP            )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS               )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED       )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED)
@@ -775,6 +777,30 @@ void TextEditor::SetProperty(BaseObject* object, Property::Index index, const Pr
         impl.RequestTextRelayout();
         break;
       }
+      case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
+      {
+        const bool grabHandlePopupEnabled = value.Get<bool>();
+        DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+        impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+      {
+        const Property::Map* map = value.GetMap();
+        if(map)
+        {
+          impl.mInputMethodOptions.ApplyProperty(*map);
+        }
+        impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
+
+        Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+        if(control == textEditor)
+        {
+          impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
+        }
+        break;
+      }
     } // switch
   }   // texteditor
 }
@@ -1136,6 +1162,18 @@ Property::Value TextEditor::GetProperty(BaseObject* object, Property::Index inde
         value = impl.mDecorator->GetHandleColor();
         break;
       }
+      case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
+      {
+        value = impl.mController->IsGrabHandlePopupEnabled();
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+      {
+        Property::Map map;
+        impl.mInputMethodOptions.RetrieveProperty(map);
+        value = map;
+        break;
+      }
     } //switch
   }
 
@@ -1456,6 +1494,12 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
     ResizeActor(mActiveLayer, contentSize);
   }
 
+  // If there is text changed, callback is called.
+  if(mTextChanged)
+  {
+    EmitTextChangedSignal();
+  }
+
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
 
   if((Text::Controller::NONE_UPDATED != updateTextType) ||
@@ -1475,12 +1519,6 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
     }
 
     RenderText(updateTextType);
-
-    // If there is text changed, callback is called.
-    if(mTextChanged)
-    {
-      EmitTextChangedSignal();
-    }
   }
 
   // The text-editor emits signals when the input style changes. These changes of style are
@@ -1522,16 +1560,50 @@ void TextEditor::RenderText(Text::Controller::UpdateTextType updateTextType)
 
     if(renderableActor != mRenderableActor)
     {
+      UnparentAndReset(mBackgroundActor);
       UnparentAndReset(mRenderableActor);
       mRenderableActor = renderableActor;
+
+      if(mRenderableActor)
+      {
+        mBackgroundActor = mController->CreateBackgroundActor();
+      }
     }
   }
 
   if(mRenderableActor)
   {
+    const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
+
+    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.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
     // Make sure the actors are parented correctly with/without clipping
     Actor self = mStencil ? mStencil : Self();
 
+    Actor highlightActor;
+
     for(std::vector<Actor>::iterator it    = mClippingDecorationActors.begin(),
                                      endIt = mClippingDecorationActors.end();
         it != endIt;
@@ -1539,11 +1611,32 @@ void TextEditor::RenderText(Text::Controller::UpdateTextType updateTextType)
     {
       self.Add(*it);
       it->LowerToBottom();
+
+      if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
+      {
+        highlightActor = *it;
+      }
     }
     mClippingDecorationActors.clear();
 
     self.Add(mRenderableActor);
 
+    if(mBackgroundActor)
+    {
+      if(mDecorator && mDecorator->IsHighlightVisible())
+      {
+        self.Add(mBackgroundActor);
+        mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
+        mBackgroundActor.LowerBelow(highlightActor);
+      }
+      else
+      {
+        mRenderableActor.Add(mBackgroundActor);
+        mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
+        mBackgroundActor.LowerToBottom();
+      }
+    }
+
     ApplyScrollPosition();
   }
   UpdateScrollBar();
@@ -1555,6 +1648,7 @@ void TextEditor::OnKeyInputFocusGained()
   if(mInputMethodContext && IsEditable())
   {
     // All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
+    mInputMethodContext.ApplyOptions(mInputMethodOptions);
     mInputMethodContext.NotifyTextInputMultiLine(true);
 
     mInputMethodContext.StatusChangedSignal().Connect(this, &TextEditor::KeyboardStatusChanged);
@@ -2057,7 +2151,7 @@ TextEditor::~TextEditor()
 
 std::string TextEditor::AccessibleImpl::GetName()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   return slf.GetProperty(Toolkit::TextEditor::Property::TEXT)
     .Get<std::string>();
 }
@@ -2068,7 +2162,7 @@ std::string TextEditor::AccessibleImpl::GetText(size_t startOffset,
   if(endOffset <= startOffset)
     return {};
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 
@@ -2080,7 +2174,7 @@ std::string TextEditor::AccessibleImpl::GetText(size_t startOffset,
 
 size_t TextEditor::AccessibleImpl::GetCharacterCount()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 
@@ -2089,13 +2183,13 @@ size_t TextEditor::AccessibleImpl::GetCharacterCount()
 
 size_t TextEditor::AccessibleImpl::GetCaretOffset()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 }
 
 bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   if(offset > txt.size())
     return false;
@@ -2109,7 +2203,7 @@ bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
 Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(
   size_t offset, Dali::Accessibility::TextBoundary boundary)
 {
-  auto slf      = Toolkit::TextEditor::DownCast(self);
+  auto slf      = Toolkit::TextEditor::DownCast(Self());
   auto txt      = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   auto txt_size = txt.size();
 
@@ -2189,7 +2283,7 @@ TextEditor::AccessibleImpl::GetSelection(size_t selectionNum)
   if(selectionNum > 0)
     return {};
 
-  auto        slf  = Toolkit::TextEditor::DownCast(self);
+  auto        slf  = Toolkit::TextEditor::DownCast(Self());
   auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
   std::string ret;
   ctrl->RetrieveSelection(ret);
@@ -2204,7 +2298,7 @@ bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionNum)
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
   return true;
 }
@@ -2217,7 +2311,7 @@ bool TextEditor::AccessibleImpl::SetSelection(size_t selectionNum,
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
                                                             endOffset);
   return true;
@@ -2229,7 +2323,7 @@ bool TextEditor::AccessibleImpl::CopyText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
@@ -2242,12 +2336,27 @@ bool TextEditor::AccessibleImpl::CutText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
   slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
-                  txt.substr(0, startPosition) + txt.substr(endPosition - startPosition, txt.size()));
+                  txt.substr(0, startPosition) + txt.substr(endPosition));
+
+  return true;
+}
+
+bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition,
+                                            size_t endPosition)
+{
+  if(endPosition <= startPosition)
+    return false;
+
+  auto slf = Toolkit::TextEditor::DownCast(Self());
+  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
+
+  slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
+                  txt.substr(0, startPosition) + txt.substr(endPosition));
 
   return true;
 }
@@ -2269,6 +2378,26 @@ Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
   return states;
 }
 
+bool TextEditor::AccessibleImpl::InsertText(size_t      startPosition,
+                                            std::string text)
+{
+  auto slf = Toolkit::TextEditor::DownCast(Self());
+  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
+
+  txt.insert(startPosition, text);
+
+  slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(txt));
+
+  return true;
+}
+
+bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
+{
+  auto slf = Toolkit::TextEditor::DownCast(Self());
+  slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
+  return true;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit