+bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl)
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->Controller::ProcessInputEvents\n");
+
+ EventData*& eventData = impl.mEventData;
+ if(NULL == eventData)
+ {
+ // Nothing to do if there is no text input.
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::ProcessInputEvents no event data\n");
+ return false;
+ }
+
+ unsigned int oldPos = eventData->mPrimaryCursorPosition;
+
+ if(eventData->mDecorator)
+ {
+ for(std::vector<Event>::iterator iter = eventData->mEventQueue.begin();
+ iter != eventData->mEventQueue.end();
+ ++iter)
+ {
+ switch(iter->type)
+ {
+ case Event::CURSOR_KEY_EVENT:
+ {
+ OnCursorKeyEvent(impl, *iter);
+ break;
+ }
+ case Event::TAP_EVENT:
+ {
+ OnTapEvent(impl, *iter);
+ break;
+ }
+ case Event::LONG_PRESS_EVENT:
+ {
+ OnLongPressEvent(impl, *iter);
+ break;
+ }
+ case Event::PAN_EVENT:
+ {
+ OnPanEvent(impl, *iter);
+ break;
+ }
+ case Event::GRAB_HANDLE_EVENT:
+ case Event::LEFT_SELECTION_HANDLE_EVENT:
+ case Event::RIGHT_SELECTION_HANDLE_EVENT: // Fall through
+ {
+ OnHandleEvent(impl, *iter);
+ break;
+ }
+ case Event::SELECT:
+ {
+ OnSelectEvent(impl, *iter);
+ break;
+ }
+ case Event::SELECT_ALL:
+ {
+ OnSelectAllEvent(impl);
+ break;
+ }
+ case Event::SELECT_NONE:
+ {
+ OnSelectNoneEvent(impl);
+ break;
+ }
+ case Event::SELECT_RANGE:
+ {
+ OnSelectRangeEvent(impl, *iter);
+ break;
+ }
+ }
+ }
+ }
+
+ if(eventData->mUpdateCursorPosition ||
+ eventData->mUpdateHighlightBox)
+ {
+ impl.NotifyInputMethodContext();
+ }
+
+ // The cursor must also be repositioned after inserts into the model
+ if(eventData->mUpdateCursorPosition)
+ {
+ // 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);
+
+ //only emit the event if the cursor is moved in current function.
+ if(nullptr != impl.mEditableControlInterface && eventData->mEventQueue.size() > 0)
+ {
+ impl.mEditableControlInterface->CursorPositionChanged(oldPos, eventData->mPrimaryCursorPosition);
+ }
+
+ if(eventData->mUpdateCursorHookPosition)
+ {
+ // Update the cursor hook position. Used to move the cursor with the keys 'up' and 'down'.
+ eventData->mCursorHookPositionX = cursorInfo.primaryPosition.x;
+ eventData->mUpdateCursorHookPosition = false;
+ }
+
+ // Scroll first the text after delete ...
+ if(eventData->mScrollAfterDelete)
+ {
+ impl.ScrollTextToMatchCursor(cursorInfo);
+ }
+
+ // ... then, text can be scrolled to make the cursor visible.
+ if(eventData->mScrollAfterUpdatePosition)
+ {
+ const Vector2 currentCursorPosition(cursorInfo.primaryPosition.x, cursorInfo.lineOffset);
+ impl.ScrollToMakePositionVisible(currentCursorPosition, cursorInfo.lineHeight);
+ }
+ eventData->mScrollAfterUpdatePosition = false;
+ eventData->mScrollAfterDelete = false;
+
+ impl.UpdateCursorPosition(cursorInfo);
+
+ eventData->mDecoratorUpdated = true;
+ eventData->mUpdateCursorPosition = false;
+ eventData->mUpdateGrabHandlePosition = false;
+ }
+
+ if(eventData->mUpdateHighlightBox ||
+ eventData->mUpdateLeftSelectionPosition ||
+ eventData->mUpdateRightSelectionPosition)
+ {
+ CursorInfo leftHandleInfo;
+ CursorInfo rightHandleInfo;
+
+ if(eventData->mUpdateHighlightBox)
+ {
+ impl.GetCursorPosition(eventData->mLeftSelectionPosition, leftHandleInfo);
+
+ impl.GetCursorPosition(eventData->mRightSelectionPosition, rightHandleInfo);
+
+ if(eventData->mScrollAfterUpdatePosition && (eventData->mIsLeftHandleSelected ? eventData->mUpdateLeftSelectionPosition : eventData->mUpdateRightSelectionPosition))
+ {
+ if(eventData->mIsLeftHandleSelected && eventData->mIsRightHandleSelected)
+ {
+ CursorInfo& infoLeft = leftHandleInfo;
+
+ const Vector2 currentCursorPositionLeft(infoLeft.primaryPosition.x, infoLeft.lineOffset);
+ impl.ScrollToMakePositionVisible(currentCursorPositionLeft, infoLeft.lineHeight);
+
+ CursorInfo& infoRight = rightHandleInfo;
+
+ const Vector2 currentCursorPositionRight(infoRight.primaryPosition.x, infoRight.lineOffset);
+ impl.ScrollToMakePositionVisible(currentCursorPositionRight, infoRight.lineHeight);
+ }
+ else
+ {
+ CursorInfo& info = eventData->mIsLeftHandleSelected ? leftHandleInfo : rightHandleInfo;
+
+ const Vector2 currentCursorPosition(info.primaryPosition.x, info.lineOffset);
+ impl.ScrollToMakePositionVisible(currentCursorPosition, info.lineHeight);
+ }
+ }
+ }
+
+ if(eventData->mUpdateLeftSelectionPosition)
+ {
+ impl.UpdateSelectionHandle(LEFT_SELECTION_HANDLE, leftHandleInfo);
+
+ impl.SetPopupButtons();
+ eventData->mDecoratorUpdated = true;
+ eventData->mUpdateLeftSelectionPosition = false;
+ }
+
+ if(eventData->mUpdateRightSelectionPosition)
+ {
+ impl.UpdateSelectionHandle(RIGHT_SELECTION_HANDLE, rightHandleInfo);
+
+ impl.SetPopupButtons();
+ eventData->mDecoratorUpdated = true;
+ eventData->mUpdateRightSelectionPosition = false;
+ }
+
+ if(eventData->mUpdateHighlightBox)
+ {
+ impl.RepositionSelectionHandles();
+
+ eventData->mUpdateLeftSelectionPosition = false;
+ eventData->mUpdateRightSelectionPosition = false;
+ eventData->mUpdateHighlightBox = false;
+ eventData->mIsLeftHandleSelected = false;
+ eventData->mIsRightHandleSelected = false;
+ }
+
+ eventData->mScrollAfterUpdatePosition = false;
+ }
+
+ if(eventData->mUpdateInputStyle)
+ {
+ // Keep a copy of the current input style.
+ InputStyle currentInputStyle;
+ currentInputStyle.Copy(eventData->mInputStyle);
+
+ // Set the default style first.
+ impl.RetrieveDefaultInputStyle(eventData->mInputStyle);
+
+ // Get the character index from the cursor index.
+ const CharacterIndex styleIndex = (eventData->mPrimaryCursorPosition > 0u) ? eventData->mPrimaryCursorPosition - 1u : 0u;
+
+ // Retrieve the style from the style runs stored in the logical model.
+ impl.mModel->mLogicalModel->RetrieveStyle(styleIndex, eventData->mInputStyle);
+
+ // Compare if the input style has changed.
+ const bool hasInputStyleChanged = !currentInputStyle.Equal(eventData->mInputStyle);
+
+ if(hasInputStyleChanged)
+ {
+ const InputStyle::Mask styleChangedMask = currentInputStyle.GetInputStyleChangeMask(eventData->mInputStyle);
+ // Queue the input style changed signal.
+ eventData->mInputStyleChangedQueue.PushBack(styleChangedMask);
+ }
+
+ eventData->mUpdateInputStyle = false;
+ }
+
+ eventData->mEventQueue.clear();
+
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::ProcessInputEvents\n");
+
+ const bool decoratorUpdated = eventData->mDecoratorUpdated;
+ eventData->mDecoratorUpdated = false;
+
+ return decoratorUpdated;
+}