Set TapGesture only if there is an anchor.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index f29ab22..7e0410d 100644 (file)
 #include <dali-toolkit/internal/text/text-controller.h>
 
 // EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/integration-api/debug.h>
 #include <memory.h>
 #include <cmath>
 #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 +78,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 +127,8 @@ void Controller::SetMarkupProcessorEnabled(bool enable)
     GetText(text);
     SetText(text);
   }
+
+  mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
 }
 
 bool Controller::IsMarkupProcessorEnabled() const
@@ -129,6 +136,11 @@ bool Controller::IsMarkupProcessorEnabled() const
   return mImpl->mMarkupProcessorEnabled;
 }
 
+bool Controller::HasAnchors() const
+{
+  return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
+}
+
 void Controller::SetAutoScrollEnabled(bool enable)
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable) ? "true" : "false", (mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) ? "true" : "false", this);
@@ -377,14 +389,19 @@ void Controller::SetIgnoreSpacesAfterText(bool ignore)
   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
 }
 
-bool Controller::IsMatchSystemLanguageDirection() const
+void Controller::ChangedLayoutDirection()
 {
-  return mImpl->mModel->mMatchSystemLanguageDirection;
+  mImpl->mIsLayoutDirectionChanged = true;
 }
 
-void Controller::SetMatchSystemLanguageDirection(bool match)
+void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
 {
-  mImpl->mModel->mMatchSystemLanguageDirection = match;
+  mImpl->mModel->mMatchLayoutDirection = type;
+}
+
+DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
+{
+  return mImpl->mModel->mMatchLayoutDirection;
 }
 
 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
@@ -392,6 +409,19 @@ void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
   mImpl->mLayoutDirection = layoutDirection;
 }
 
+Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
+{
+  if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
+     (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged))
+  {
+    return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+  }
+  else
+  {
+    return static_cast<Dali::LayoutDirection::Type>(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+  }
+}
+
 bool Controller::IsShowingRealText() const
 {
   return mImpl->IsShowingRealText();
@@ -401,15 +431,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();
@@ -427,6 +464,7 @@ Text::LineWrap::Mode Controller::GetLineWrapMode() const
 void Controller::SetTextElideEnabled(bool enabled)
 {
   mImpl->mModel->mElideEnabled = enabled;
+  mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
 }
 
 bool Controller::IsTextElideEnabled() const
@@ -1222,28 +1260,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 +1644,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);
@@ -1661,6 +1725,17 @@ void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignm
   mImpl->mModel->mVerticalLineAlignment = alignment;
 }
 
+Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
+{
+  return mImpl->mModel->GetEllipsisPosition();
+}
+
+void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
+{
+  mImpl->mModel->mEllipsisPosition = ellipsisPosition;
+  mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
+}
+
 // public : Relayout.
 
 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
@@ -1722,6 +1797,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 +2016,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 +2153,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 +2171,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))
 {
 }