From: Victor Cebollada Date: Wed, 18 May 2016 07:42:11 +0000 (+0100) Subject: Fix for pre-edit text. X-Git-Tag: dali_1.1.37~11^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=677d489c37efac76c7449f7e22d66b3fc92c4af1 Fix for pre-edit text. * When editing with predictive text enabled, the imf manager removes the current pre-edited text and inserts the new string. The new string can be longer if text is being added, or smaller if text is being removed. The text needs to be scrolled to the cursor position if text is smaller. * Similarly, the text-controller can remove a group of characters when a ImfManager::DELETESURROUNDING event arrives. The text also needs to be scrolled to the cursor position. * If text is not added at the end of the string, the text must not be scrolled unless the cursor becomes not visible. Change-Id: I6ed4b9ea122cd0b8fac4111c732625bf636eb52d Signed-off-by: Victor Cebollada --- diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index e77f00d..d4d8fdc 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -154,16 +154,19 @@ bool Controller::Impl::ProcessInputEvents() GetCursorPosition( mEventData->mPrimaryCursorPosition, cursorInfo ); - if( mEventData->mScrollAfterUpdatePosition ) + // Scroll first the text after delete ... + if( mEventData->mScrollAfterDelete ) { - ScrollToMakePositionVisible( cursorInfo.primaryPosition ); - mEventData->mScrollAfterUpdatePosition = false; + ScrollTextToMatchCursor( cursorInfo ); } - else if( mEventData->mScrollAfterDelete ) + + // ... then, text can be scrolled to make the cursor visible. + if( mEventData->mScrollAfterUpdatePosition ) { - ScrollTextToMatchCursor( cursorInfo ); - mEventData->mScrollAfterDelete = false; + ScrollToMakePositionVisible( cursorInfo.primaryPosition ); } + mEventData->mScrollAfterUpdatePosition = false; + mEventData->mScrollAfterDelete = false; UpdateCursorPosition( cursorInfo ); @@ -1302,6 +1305,7 @@ void Controller::Impl::OnSelectEvent( const Event& event ) mEventData->mUpdateLeftSelectionPosition = true; mEventData->mUpdateRightSelectionPosition = true; + mEventData->mUpdateCursorPosition = false; mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ); } @@ -1370,12 +1374,7 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete // Scroll after delete. mEventData->mPrimaryCursorPosition = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition; - mEventData->mScrollAfterDelete = true; } - // Udpade the cursor position and the decorator. - // Scroll after the position is updated if is not scrolling after delete. - mEventData->mUpdateCursorPosition = true; - mEventData->mScrollAfterUpdatePosition = !mEventData->mScrollAfterDelete; mEventData->mDecoratorUpdated = true; } } @@ -2454,8 +2453,10 @@ void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize ) void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position ) { + const float cursorWidth = mEventData->mDecorator ? mEventData->mDecorator->GetCursorWidth() : 0.f; + // position is in actor's coords. - const float positionEnd = position.x + ( mEventData->mDecorator ? mEventData->mDecorator->GetCursorWidth() : 0.f ); + const float positionEnd = position.x + cursorWidth; // Transform the position to decorator coords. const float alignment = IsShowingRealText() ? mAlignmentOffset.x : 0.f; @@ -2482,6 +2483,9 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo ) mEventData->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x - mAlignmentOffset.x; ClampHorizontalScroll( mVisualModel->GetLayoutSize() ); + + // Makes the new cursor position visible if needed. + ScrollToMakePositionVisible( cursorInfo.primaryPosition ); } void Controller::Impl::RequestRelayout() diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 5c1ed0c..3ff675b 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -520,6 +520,12 @@ struct Controller::Impl void OnSelectAllEvent(); + /** + * @brief Retrieves the selected text. It removes the text if the @p deleteAfterRetrieval parameter is @e true. + * + * @param[out] selectedText The selected text encoded in utf8. + * @param[in] deleteAfterRetrieval Whether the text should be deleted after retrieval. + */ void RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval ); void ShowClipboard(); diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 268519b..09a4441 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -614,6 +614,8 @@ bool Controller::RemoveText( int cursorOffset, // Cursor position retreat oldCursorIndex = cursorIndex; + mImpl->mEventData->mScrollAfterDelete = true; + DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfCharacters ); removed = true; } @@ -1434,13 +1436,6 @@ void Controller::TextInsertedEvent() // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; - - // Queue a cursor reposition event; this must wait until after DoRelayout() - if( EventData::IsEditingState( mImpl->mEventData->mState ) ) - { - mImpl->mEventData->mUpdateCursorPosition = true; - mImpl->mEventData->mScrollAfterUpdatePosition = true; - } } void Controller::TextDeletedEvent() @@ -1457,13 +1452,6 @@ void Controller::TextDeletedEvent() // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; - - // Queue a cursor reposition event; this must wait until after DoRelayout() - mImpl->mEventData->mUpdateCursorPosition = true; - if( 0u != mImpl->mLogicalModel->mText.Count() ) - { - mImpl->mEventData->mScrollAfterDelete = true; - } } bool Controller::DoRelayout( const Size& size, @@ -1930,16 +1918,13 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ // TODO: At the moment the underline runs are only for pre-edit. mImpl->mVisualModel->mUnderlineRuns.Clear(); - Vector utf32Characters; - Length characterCount( 0u ); + // Keep the current number of characters. + const Length currentNumberOfCharacters = mImpl->IsShowingRealText() ? mImpl->mLogicalModel->mText.Count() : 0u; - // Remove the previous IMF pre-edit (predicitive text) - if( mImpl->mEventData->mPreEditFlag && - ( 0u != mImpl->mEventData->mPreEditLength ) ) + // Remove the previous IMF pre-edit. + if( mImpl->mEventData->mPreEditFlag && ( 0u != mImpl->mEventData->mPreEditLength ) ) { - const CharacterIndex offset = mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition; - - removedPrevious = RemoveText( -static_cast( offset ), + removedPrevious = RemoveText( -static_cast( mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition ), mImpl->mEventData->mPreEditLength, DONT_UPDATE_INPUT_STYLE ); @@ -1948,10 +1933,13 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ } else { - // Remove the previous Selection + // Remove the previous Selection. removedPrevious = RemoveSelectedText(); } + Vector utf32Characters; + Length characterCount = 0u; + if( !text.empty() ) { // Convert text into UTF-32 @@ -2116,6 +2104,8 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Inserted %d characters, new size %d new cursor %d\n", maxSizeOfNewText, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition ); } + const Length numberOfCharacters = mImpl->IsShowingRealText() ? mImpl->mLogicalModel->mText.Count() : 0u; + if( ( 0u == mImpl->mLogicalModel->mText.Count() ) && mImpl->IsPlaceholderAvailable() ) { @@ -2129,6 +2119,16 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ { // Queue an inserted event mImpl->QueueModifyEvent( ModifyEvent::TEXT_INSERTED ); + + mImpl->mEventData->mUpdateCursorPosition = true; + if( numberOfCharacters < currentNumberOfCharacters ) + { + mImpl->mEventData->mScrollAfterDelete = true; + } + else + { + mImpl->mEventData->mScrollAfterUpdatePosition = true; + } } if( maxLengthReached ) @@ -2441,8 +2441,11 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt else { ShowPlaceholderText(); - mImpl->mEventData->mUpdateCursorPosition = true; } + + mImpl->mEventData->mUpdateCursorPosition = true; + mImpl->mEventData->mScrollAfterDelete = true; + mImpl->RequestRelayout(); mImpl->mControlInterface.TextChanged(); break; @@ -2530,8 +2533,9 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons else { ShowPlaceholderText(); - mImpl->mEventData->mUpdateCursorPosition = true; } + mImpl->mEventData->mUpdateCursorPosition = true; + mImpl->mEventData->mScrollAfterDelete = true; } requestRelayout = true; break; @@ -2618,8 +2622,9 @@ bool Controller::BackspaceKeyEvent() else { ShowPlaceholderText(); - mImpl->mEventData->mUpdateCursorPosition = true; } + mImpl->mEventData->mUpdateCursorPosition = true; + mImpl->mEventData->mScrollAfterDelete = true; } return removed;