Merge "fix wrong behaviour of SelectNone()" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl-event-handler.cpp
index 995a800..e298a5a 100644 (file)
@@ -54,6 +54,8 @@ bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl)
     return false;
   }
 
+  unsigned int oldPos = eventData->mPrimaryCursorPosition;
+
   if(eventData->mDecorator)
   {
     for(std::vector<Event>::iterator iter = eventData->mEventQueue.begin();
@@ -104,6 +106,11 @@ bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl)
           OnSelectNoneEvent(impl);
           break;
         }
+        case Event::SELECT_RANGE:
+        {
+          OnSelectRangeEvent(impl, *iter);
+          break;
+        }
       }
     }
   }
@@ -119,12 +126,14 @@ bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl)
   {
     // Updates the cursor position and scrolls the text to make it visible.
     CursorInfo cursorInfo;
+
     // Calculate the cursor position from the new cursor index.
     impl.GetCursorPosition(eventData->mPrimaryCursorPosition, cursorInfo);
 
-    if(nullptr != impl.mEditableControlInterface)
+    //only emit the event if the cursor is moved in current function.
+    if(nullptr != impl.mEditableControlInterface && eventData->mEventQueue.size() > 0)
     {
-      impl.mEditableControlInterface->CursorMoved(eventData->mPrimaryCursorPosition);
+      impl.mEditableControlInterface->CursorPositionChanged(oldPos, eventData->mPrimaryCursorPosition);
     }
 
     if(eventData->mUpdateCursorHookPosition)
@@ -277,6 +286,8 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const
   ModelPtr&        model           = impl.mModel;
   LogicalModelPtr& logicalModel    = model->mLogicalModel;
   VisualModelPtr&  visualModel     = model->mVisualModel;
+  uint32_t         oldSelStart     = eventData.mLeftSelectionPosition;
+  uint32_t         oldSelEnd       = eventData.mRightSelectionPosition;
 
   CharacterIndex& primaryCursorPosition         = eventData.mPrimaryCursorPosition;
   CharacterIndex  previousPrimaryCursorPosition = primaryCursorPosition;
@@ -333,7 +344,7 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const
     const LineRun& line = *(visualModel->mLines.Begin() + previousLineIndex);
 
     // Get the next hit 'y' point.
-    const float hitPointY = cursorInfo.lineOffset - 0.5f * (line.ascender - line.descender);
+    const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line);
 
     // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
     bool matchedCharacter = false;
@@ -369,7 +380,7 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const
       const LineRun& line = *(visualModel->mLines.Begin() + lineIndex + 1u);
 
       // Get the next hit 'y' point.
-      const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * (line.ascender - line.descender);
+      const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line);
 
       // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
       bool matchedCharacter = false;
@@ -388,6 +399,11 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const
     // Update selection position after moving the cursor
     eventData.mLeftSelectionPosition  = primaryCursorPosition;
     eventData.mRightSelectionPosition = primaryCursorPosition;
+
+    if(impl.mSelectableControlInterface != nullptr && eventData.mDecorator->IsHighlightVisible())
+    {
+      impl.mSelectableControlInterface->SelectionChanged(oldSelStart, oldSelEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+    }
   }
 
   if(isShiftModifier && impl.IsShowingRealText() && eventData.mShiftSelectionFlag)
@@ -402,6 +418,11 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const
       if(cursorPositionDelta > 0 || eventData.mRightSelectionPosition > 0u) // Check the boundary
       {
         eventData.mRightSelectionPosition += cursorPositionDelta;
+
+        if(impl.mSelectableControlInterface != nullptr)
+        {
+          impl.mSelectableControlInterface->SelectionChanged(oldSelStart, oldSelEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+        }
       }
       selecting = true;
     }
@@ -460,8 +481,10 @@ void ControllerImplEventHandler::OnTapEvent(Controller::Impl& impl, const Event&
       if(impl.IsShowingRealText())
       {
         // Convert from control's coords to text's coords.
-        const float xPosition = event.p2.mFloat - model->mScrollPosition.x;
-        const float yPosition = event.p3.mFloat - model->mScrollPosition.y;
+        const float xPosition   = event.p2.mFloat - model->mScrollPosition.x;
+        const float yPosition   = event.p3.mFloat - model->mScrollPosition.y;
+        uint32_t    oldSelStart = eventData.mLeftSelectionPosition;
+        uint32_t    oldSelEnd   = eventData.mRightSelectionPosition;
 
         // Keep the tap 'x' position. Used to move the cursor.
         eventData.mCursorHookPositionX = xPosition;
@@ -476,6 +499,11 @@ void ControllerImplEventHandler::OnTapEvent(Controller::Impl& impl, const Event&
                                                                        CharacterHitTest::TAP,
                                                                        matchedCharacter);
 
+        if(impl.mSelectableControlInterface != nullptr && eventData.mDecorator->IsHighlightVisible())
+        {
+          impl.mSelectableControlInterface->SelectionChanged(oldSelStart, oldSelEnd, eventData.mPrimaryCursorPosition, eventData.mPrimaryCursorPosition);
+        }
+
         // When the cursor position is changing, delay cursor blinking
         eventData.mDecorator->DelayCursorBlink();
       }
@@ -658,7 +686,7 @@ void ControllerImplEventHandler::OnSelectAllEvent(Controller::Impl& impl)
   if(impl.mEventData)
   {
     EventData& eventData = *impl.mEventData;
-    if(eventData.mSelectionEnabled)
+    if(eventData.mSelectionEnabled && eventData.mState != EventData::INACTIVE)
     {
       ModelPtr&      model          = impl.mModel;
       const Vector2& scrollPosition = model->mScrollPosition;
@@ -668,8 +696,16 @@ void ControllerImplEventHandler::OnSelectAllEvent(Controller::Impl& impl)
                                       0.f - scrollPosition.y,
                                       Controller::NoTextTap::HIGHLIGHT);
 
+      uint32_t oldStart = eventData.mLeftSelectionPosition;
+      uint32_t oldEnd   = eventData.mRightSelectionPosition;
+
       eventData.mLeftSelectionPosition  = 0u;
       eventData.mRightSelectionPosition = model->mLogicalModel->mText.Count();
+
+      if(impl.mSelectableControlInterface != nullptr)
+      {
+        impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+      }
     }
   }
 }
@@ -683,12 +719,50 @@ void ControllerImplEventHandler::OnSelectNoneEvent(Controller::Impl& impl)
     EventData& eventData = *impl.mEventData;
     if(eventData.mSelectionEnabled && eventData.mState == EventData::SELECTING)
     {
-      eventData.mPrimaryCursorPosition = 0u;
+      uint32_t oldStart                = eventData.mLeftSelectionPosition;
+      uint32_t oldEnd                  = eventData.mRightSelectionPosition;
+
       eventData.mLeftSelectionPosition = eventData.mRightSelectionPosition = eventData.mPrimaryCursorPosition;
-      impl.ChangeState(EventData::INACTIVE);
+      impl.ChangeState(EventData::EDITING);
       eventData.mUpdateCursorPosition      = true;
       eventData.mUpdateInputStyle          = true;
       eventData.mScrollAfterUpdatePosition = true;
+
+      if(impl.mSelectableControlInterface != nullptr)
+      {
+        impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+      }
+    }
+  }
+}
+
+void ControllerImplEventHandler::OnSelectRangeEvent(Controller::Impl& impl, const Event& event)
+{
+  if(impl.mEventData && impl.mEventData->mSelectionEnabled && impl.mEventData->mState != EventData::INACTIVE)
+  {
+    ModelPtr&      model          = impl.mModel;
+    const Vector2& scrollPosition = model->mScrollPosition;
+
+    // Calculate the selection index.
+    const uint32_t length = static_cast<uint32_t>(model->mLogicalModel->mText.Count());
+    const uint32_t start  = std::min(event.p2.mUint, length);
+    const uint32_t end    = std::min(event.p3.mUint, length);
+
+    if(start != end)
+    {
+      uint32_t oldStart = impl.mEventData->mLeftSelectionPosition;
+      uint32_t oldEnd   = impl.mEventData->mRightSelectionPosition;
+
+      // Calculates the logical position from the x,y coords.
+      impl.RepositionSelectionHandles(0.f - scrollPosition.x, 0.f - scrollPosition.y, Controller::NoTextTap::HIGHLIGHT);
+
+      impl.mEventData->mLeftSelectionPosition  = start;
+      impl.mEventData->mRightSelectionPosition = end;
+
+      if(impl.mSelectableControlInterface != nullptr)
+      {
+        impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, start, end);
+      }
     }
   }
 }
@@ -713,6 +787,8 @@ void ControllerImplEventHandler::OnHandlePressed(Controller::Impl& impl, const E
                                                                        matchedCharacter);
 
   EventData& eventData = *impl.mEventData;
+  uint32_t   oldStart  = eventData.mLeftSelectionPosition;
+  uint32_t   oldEnd    = eventData.mRightSelectionPosition;
 
   if(Event::GRAB_HANDLE_EVENT == event.type)
   {
@@ -772,6 +848,11 @@ void ControllerImplEventHandler::OnHandlePressed(Controller::Impl& impl, const E
     eventData.mIsLeftHandleSelected  = false;
     eventData.mIsRightHandleSelected = true;
   }
+
+  if((impl.mSelectableControlInterface != nullptr) && ((oldStart != eventData.mLeftSelectionPosition) || (oldEnd != eventData.mRightSelectionPosition)))
+  {
+    impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+  }
 }
 
 void ControllerImplEventHandler::OnHandleReleased(Controller::Impl& impl, const Event& event, const bool isSmoothHandlePanEnabled, const bool handleStopScrolling)
@@ -797,6 +878,8 @@ void ControllerImplEventHandler::OnHandleReleased(Controller::Impl& impl, const
   }
 
   EventData& eventData = *impl.mEventData;
+  uint32_t   oldStart  = eventData.mLeftSelectionPosition;
+  uint32_t   oldEnd    = eventData.mRightSelectionPosition;
 
   if(Event::GRAB_HANDLE_EVENT == event.type)
   {
@@ -853,6 +936,11 @@ void ControllerImplEventHandler::OnHandleReleased(Controller::Impl& impl, const
     }
   }
 
+  if((impl.mSelectableControlInterface != nullptr) && ((oldStart != eventData.mLeftSelectionPosition) || (oldEnd != eventData.mRightSelectionPosition)))
+  {
+    impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+  }
+
   eventData.mDecoratorUpdated = true;
 }
 
@@ -967,6 +1055,8 @@ void ControllerImplEventHandler::OnHandleScrolling(Controller::Impl& impl, const
                                                                       position.y - scrollPosition.y,
                                                                       CharacterHitTest::SCROLL,
                                                                       matchedCharacter);
+    uint32_t             oldStart         = eventData.mLeftSelectionPosition;
+    uint32_t             oldEnd           = eventData.mRightSelectionPosition;
 
     if(leftSelectionHandleEvent)
     {
@@ -997,6 +1087,11 @@ void ControllerImplEventHandler::OnHandleScrolling(Controller::Impl& impl, const
       impl.RepositionSelectionHandles();
 
       eventData.mScrollAfterUpdatePosition = !isSmoothHandlePanEnabled;
+
+      if(impl.mSelectableControlInterface != nullptr)
+      {
+        impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition);
+      }
     }
   }
   eventData.mDecoratorUpdated = true;