X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl-event-handler.cpp;h=1ed8c7f1144dee4f9dbc6ac5af58cbfc1b791a62;hb=c427acac5f2616578c05987c99e7b430c9ab0137;hp=22525db0d9849beb4ee254f52be8630d70bd8e2b;hpb=b8da2e53925b9abb9fa362560069e8ca4aa62f81;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/text-controller-impl-event-handler.cpp b/dali-toolkit/internal/text/text-controller-impl-event-handler.cpp index 22525db..1ed8c7f 100644 --- a/dali-toolkit/internal/text/text-controller-impl-event-handler.cpp +++ b/dali-toolkit/internal/text/text-controller-impl-event-handler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,8 @@ bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl) return false; } + unsigned int oldPos = eventData->mPrimaryCursorPosition; + if(eventData->mDecorator) { for(std::vector::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->CaretMoved(eventData->mPrimaryCursorPosition); + impl.mEditableControlInterface->CursorPositionChanged(oldPos, eventData->mPrimaryCursorPosition); } if(eventData->mUpdateCursorHookPosition) @@ -155,7 +164,10 @@ bool ControllerImplEventHandler::ProcessInputEvents(Controller::Impl& impl) eventData->mUpdateCursorPosition = false; eventData->mUpdateGrabHandlePosition = false; } - else + + if(eventData->mUpdateHighlightBox || + eventData->mUpdateLeftSelectionPosition || + eventData->mUpdateRightSelectionPosition) { CursorInfo leftHandleInfo; CursorInfo rightHandleInfo; @@ -274,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; @@ -320,6 +334,8 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const const LineIndex lineIndex = visualModel->GetLineOfCharacter(characterIndex); const LineIndex previousLineIndex = (lineIndex > 0 ? lineIndex - 1u : lineIndex); + const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0); + const bool isLastLine = (previousLineIndex == lastLineIndex); // Retrieve the cursor position info. CursorInfo cursorInfo; @@ -330,7 +346,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, isLastLine); // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. bool matchedCharacter = false; @@ -363,10 +379,15 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const impl.GetCursorPosition(primaryCursorPosition, cursorInfo); // Get the line below. - const LineRun& line = *(visualModel->mLines.Begin() + lineIndex + 1u); + const LineRun& nextline = *(visualModel->mLines.Begin() + lineIndex + 1u); + const LineRun& currline = *(visualModel->mLines.Begin() + lineIndex); + + // Get last line index + const LineIndex lastLineIndex = (visualModel->mLines.Size() > 0 ? visualModel->mLines.Size() - 1u : 0); + const bool isLastLine = (lineIndex + 1u == lastLineIndex); // Get the next hit 'y' point. - const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * (line.ascender - line.descender); + const float hitPointY = cursorInfo.lineOffset + GetLineHeight(currline, false) + 0.5f * GetLineHeight(nextline, isLastLine); // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. bool matchedCharacter = false; @@ -385,6 +406,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) @@ -399,8 +425,23 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const if(cursorPositionDelta > 0 || eventData.mRightSelectionPosition > 0u) // Check the boundary { eventData.mRightSelectionPosition += cursorPositionDelta; + eventData.mPrimaryCursorPosition = eventData.mRightSelectionPosition; + + if(impl.mSelectableControlInterface != nullptr) + { + impl.mSelectableControlInterface->SelectionChanged(oldSelStart, oldSelEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition); + } + } + + if(impl.mSelectableControlInterface != nullptr && eventData.mLeftSelectionPosition == eventData.mRightSelectionPosition) + { + // If left selection position and right selection position are the same, the selection is canceled. + selecting = false; + } + else + { + selecting = true; } - selecting = true; } else if(eventData.mLeftSelectionPosition != eventData.mRightSelectionPosition) { @@ -430,6 +471,12 @@ void ControllerImplEventHandler::OnCursorKeyEvent(Controller::Impl& impl, const eventData.mDecorator->SetPopupActive(false); } } + else + { + // If no selection, set a normal cursor. + impl.ChangeState(EventData::EDITING); + eventData.mUpdateCursorPosition = true; + } } else { @@ -457,8 +504,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; @@ -473,6 +522,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(); } @@ -655,7 +709,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; @@ -665,8 +719,17 @@ 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(); + eventData.mPrimaryCursorPosition = eventData.mRightSelectionPosition; + + if(impl.mSelectableControlInterface != nullptr) + { + impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData.mLeftSelectionPosition, eventData.mRightSelectionPosition); + } } } } @@ -680,12 +743,51 @@ 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(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; + impl.mEventData->mPrimaryCursorPosition = end; + + if(impl.mSelectableControlInterface != nullptr) + { + impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, start, end); + } } } } @@ -710,6 +812,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) { @@ -769,6 +873,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) @@ -794,6 +903,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) { @@ -850,6 +961,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; } @@ -964,6 +1080,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) { @@ -994,6 +1112,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;