Add InputFilter to TextField, TextEditor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index f29ab22..b2b6550 100644 (file)
@@ -25,6 +25,7 @@
 #include <limits>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
@@ -75,11 +76,13 @@ ControllerPtr Controller::New(ControlInterface* controlInterface)
 
 ControllerPtr Controller::New(ControlInterface*           controlInterface,
                               EditableControlInterface*   editableControlInterface,
-                              SelectableControlInterface* selectableControlInterface)
+                              SelectableControlInterface* selectableControlInterface,
+                              AnchorControlInterface*     anchorControlInterface)
 {
   return ControllerPtr(new Controller(controlInterface,
                                       editableControlInterface,
-                                      selectableControlInterface));
+                                      selectableControlInterface,
+                                      anchorControlInterface));
 }
 
 // public : Configure the text controller.
@@ -122,6 +125,8 @@ void Controller::SetMarkupProcessorEnabled(bool enable)
     GetText(text);
     SetText(text);
   }
+
+  mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
 }
 
 bool Controller::IsMarkupProcessorEnabled() const
@@ -401,15 +406,22 @@ void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
 {
   if(lineWrapMode != mImpl->mModel->mLineWrapMode)
   {
-    // Set the text wrap mode.
-    mImpl->mModel->mLineWrapMode = lineWrapMode;
-
     // Update Text layout for applying wrap mode
-    mImpl->mOperationsPending                          = static_cast<OperationsMask>(mImpl->mOperationsPending |
+    mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
                                                             ALIGN |
                                                             LAYOUT |
                                                             UPDATE_LAYOUT_SIZE |
                                                             REORDER);
+
+    if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+       (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break
+    {
+      mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | GET_LINE_BREAKS);
+    }
+
+    // Set the text wrap mode.
+    mImpl->mModel->mLineWrapMode = lineWrapMode;
+
     mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
     mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
     mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
@@ -1222,28 +1234,37 @@ void Controller::SetInputColor(const Vector4& color)
 
     if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
     {
-      const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
+      if(EventData::SELECTING == mImpl->mEventData->mState)
+      {
+        const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
+
+        // Get start and end position of selection
+        const CharacterIndex startOfSelectedText  = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
+        const Length         lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
 
-      // Get start and end position of selection
-      const CharacterIndex startOfSelectedText  = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
-      const Length         lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
+        // Add the color run.
+        const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
+        mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
 
-      // Add the color run.
-      const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
-      mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
+        ColorRun& colorRun                       = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
+        colorRun.color                           = color;
+        colorRun.characterRun.characterIndex     = startOfSelectedText;
+        colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
 
-      ColorRun& colorRun                       = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
-      colorRun.color                           = color;
-      colorRun.characterRun.characterIndex     = startOfSelectedText;
-      colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+        mImpl->mTextUpdateInfo.mCharacterIndex             = startOfSelectedText;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = lengthOfSelectedText;
+      }
+      else
+      {
+        mImpl->mTextUpdateInfo.mCharacterIndex             = 0;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
+      }
 
       // Request to relayout.
       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
       mImpl->RequestRelayout();
-
-      mImpl->mTextUpdateInfo.mCharacterIndex             = startOfSelectedText;
-      mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
-      mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = lengthOfSelectedText;
     }
   }
 }
@@ -1597,6 +1618,23 @@ void Controller::GetHiddenInputOption(Property::Map& options)
   }
 }
 
+void Controller::SetInputFilterOption(const Property::Map& options)
+{
+  if(!mImpl->mInputFilter)
+  {
+    mImpl->mInputFilter = std::unique_ptr<InputFilter>(new InputFilter());
+  }
+  mImpl->mInputFilter->SetProperties(options);
+}
+
+void Controller::GetInputFilterOption(Property::Map& options)
+{
+  if(NULL != mImpl->mInputFilter)
+  {
+    mImpl->mInputFilter->GetProperties(options);
+  }
+}
+
 void Controller::SetPlaceholderProperty(const Property::Map& map)
 {
   PlaceholderHandler::SetPlaceholderProperty(*this, map);
@@ -1722,6 +1760,11 @@ bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
   return EventHandler::KeyEvent(*this, keyEvent);
 }
 
+void Controller::AnchorEvent(float x, float y)
+{
+  EventHandler::AnchorEvent(*this, x, y);
+}
+
 void Controller::TapEvent(unsigned int tapCount, float x, float y)
 {
   EventHandler::TapEvent(*this, tapCount, x, y);
@@ -1936,6 +1979,19 @@ bool Controller::RemoveSelectedText()
   return TextUpdater::RemoveSelectedText(*this);
 }
 
+void Controller::InsertTextAnchor(int            numberOfCharacters,
+                                  CharacterIndex previousCursorIndex)
+{
+  TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
+}
+
+void Controller::RemoveTextAnchor(int            cursorOffset,
+                                  int            numberOfCharacters,
+                                  CharacterIndex previousCursorIndex)
+{
+  TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
+}
+
 // private : Relayout.
 
 bool Controller::DoRelayout(const Size&    size,
@@ -2060,6 +2116,11 @@ void Controller::SetControlInterface(ControlInterface* controlInterface)
   mImpl->mControlInterface = controlInterface;
 }
 
+void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
+{
+  mImpl->mAnchorControlInterface = anchorControlInterface;
+}
+
 bool Controller::ShouldClearFocusOnEscape() const
 {
   return mImpl->mShouldClearFocusOnEscape;
@@ -2073,19 +2134,20 @@ Actor Controller::CreateBackgroundActor()
 // private : Private contructors & copy operator.
 
 Controller::Controller()
-: Controller(nullptr, nullptr, nullptr)
+: Controller(nullptr, nullptr, nullptr, nullptr)
 {
 }
 
 Controller::Controller(ControlInterface* controlInterface)
-: Controller(controlInterface, nullptr, nullptr)
+: Controller(controlInterface, nullptr, nullptr, nullptr)
 {
 }
 
 Controller::Controller(ControlInterface*           controlInterface,
                        EditableControlInterface*   editableControlInterface,
-                       SelectableControlInterface* selectableControlInterface)
-: mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface))
+                       SelectableControlInterface* selectableControlInterface,
+                       AnchorControlInterface*     anchorControlInterface)
+: mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
 {
 }