X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=b40dba58c8339ef4def0fdf9fc14fb1841d9a1b1;hb=1c8981a624dad48be2624e39b2a3ff62ebc0d220;hp=874503d200968cd7aeacfa502b705f236bda097d;hpb=80edd36ed742952c427ccb454006d583f8c4218c;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 874503d..b40dba5 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -108,7 +108,8 @@ EventData::EventData( DecoratorPtr decorator ) mPasswordInput( false ), mIsPlaceholderPixelSize( false ), mIsPlaceholderElideEnabled( false ), - mPlaceholderEllipsisFlag( false ) + mPlaceholderEllipsisFlag( false ), + mShiftSelectionFlag( true ) { mImfManager = ImfManager::Get(); } @@ -810,6 +811,36 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) Length paragraphCharacters = 0u; CalculateTextUpdateIndices( paragraphCharacters ); + + // Check whether the indices for updating the text is valid + if ( numberOfCharacters > 0u && + ( mTextUpdateInfo.mParagraphCharacterIndex >= numberOfCharacters || + mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters ) ) + { + std::string currentText; + Utf32ToUtf8( mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText ); + + DALI_LOG_ERROR( "Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n" ); + DALI_LOG_ERROR( "Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str() ); + + // Dump mTextUpdateInfo + DALI_LOG_ERROR( "Dump mTextUpdateInfo:\n" ); + DALI_LOG_ERROR( " mTextUpdateInfo.mCharacterIndex = %u\n", mTextUpdateInfo.mCharacterIndex ); + DALI_LOG_ERROR( " mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", mTextUpdateInfo.mNumberOfCharactersToRemove ); + DALI_LOG_ERROR( " mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", mTextUpdateInfo.mNumberOfCharactersToAdd ); + DALI_LOG_ERROR( " mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", mTextUpdateInfo.mPreviousNumberOfCharacters ); + DALI_LOG_ERROR( " mTextUpdateInfo.mParagraphCharacterIndex = %u\n", mTextUpdateInfo.mParagraphCharacterIndex ); + DALI_LOG_ERROR( " mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", mTextUpdateInfo.mRequestedNumberOfCharacters ); + DALI_LOG_ERROR( " mTextUpdateInfo.mStartGlyphIndex = %u\n", mTextUpdateInfo.mStartGlyphIndex ); + DALI_LOG_ERROR( " mTextUpdateInfo.mStartLineIndex = %u\n", mTextUpdateInfo.mStartLineIndex ); + DALI_LOG_ERROR( " mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", mTextUpdateInfo.mEstimatedNumberOfLines ); + DALI_LOG_ERROR( " mTextUpdateInfo.mClearAll = %d\n", mTextUpdateInfo.mClearAll ); + DALI_LOG_ERROR( " mTextUpdateInfo.mFullRelayoutNeeded = %d\n", mTextUpdateInfo.mFullRelayoutNeeded ); + DALI_LOG_ERROR( " mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", mTextUpdateInfo.mIsLastCharacterNewParagraph ); + + return false; + } + startIndex = mTextUpdateInfo.mParagraphCharacterIndex; if( mTextUpdateInfo.mClearAll || @@ -888,7 +919,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) TextAbstraction::FontDescription defaultFontDescription; TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE; - if( IsShowingPlaceholderText() && ( NULL != mEventData->mPlaceholderFont ) ) + if( IsShowingPlaceholderText() && mEventData && ( NULL != mEventData->mPlaceholderFont ) ) { // If the placeholder font is set specifically, only placeholder font is changed. defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription; @@ -1144,7 +1175,7 @@ float Controller::Impl::GetDefaultFontLineHeight() void Controller::Impl::OnCursorKeyEvent( const Event& event ) { - if( NULL == mEventData ) + if( NULL == mEventData || !IsShowingRealText() ) { // Nothing to do if there is no text input. return; @@ -1159,14 +1190,28 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) { if( mEventData->mPrimaryCursorPosition > 0u ) { - mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition - 1u ); + if ( !isShiftModifier && mEventData->mDecorator->IsHighlightVisible() ) + { + mEventData->mPrimaryCursorPosition = std::min(mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition); + } + else + { + mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition - 1u ); + } } } else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode ) { if( mModel->mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition ) { - mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition ); + if ( !isShiftModifier && mEventData->mDecorator->IsHighlightVisible() ) + { + mEventData->mPrimaryCursorPosition = std::max(mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition); + } + else + { + mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition ); + } } } else if( Dali::DALI_KEY_CURSOR_UP == keyCode && !isShiftModifier ) @@ -1251,7 +1296,7 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition; } - if ( isShiftModifier && IsShowingRealText() ) + if ( isShiftModifier && IsShowingRealText() && mEventData->mShiftSelectionFlag ) { // Handle text selection bool selecting = false; @@ -1940,6 +1985,8 @@ void Controller::Impl::RepositionSelectionHandles() if( selectionStart == selectionEnd ) { // Nothing to select if handles are in the same place. + // So, deactive Highlight box. + mEventData->mDecorator->SetHighlightActive( false ); return; } @@ -2291,7 +2338,7 @@ void Controller::Impl::RepositionSelectionHandles() const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() ); highLightPosition.y = firstSelectionBoxLineInfo.lineOffset; - mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize ); + mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize, static_cast( mModel->GetOutlineWidth() ) ); if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() ) { @@ -2318,9 +2365,6 @@ void Controller::Impl::RepositionSelectionHandles() secondaryCursorInfo.lineHeight ); } - // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection - mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition; - // Set the flag to update the decorator. mEventData->mDecoratorUpdated = true; } @@ -2380,6 +2424,9 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY, mEventData->mUpdateCursorPosition = false; mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ); + + // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection + mEventData->mPrimaryCursorPosition = std::max( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition ); } else if( Controller::NoTextTap::SHOW_SELECTION_POPUP == action ) { @@ -2501,8 +2548,11 @@ void Controller::Impl::ChangeState( EventData::State newState ) mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE ); mEventData->mDecorator->StopCursorBlink(); mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false ); - mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, true ); - mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true ); + if ( mEventData->mGrabHandleEnabled ) + { + mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, true ); + mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true ); + } mEventData->mDecorator->SetHighlightActive( true ); if( mEventData->mGrabHandlePopupEnabled ) { @@ -2546,7 +2596,7 @@ void Controller::Impl::ChangeState( EventData::State newState ) mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHighlightActive( false ); } - else + else if ( mEventData->mGrabHandleEnabled ) { mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); } @@ -2568,7 +2618,10 @@ void Controller::Impl::ChangeState( EventData::State newState ) mEventData->mDecorator->StartCursorBlink(); } // Grab handle is not shown until a tap is received whilst EDITING - mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + if ( mEventData->mGrabHandleEnabled ) + { + mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + } mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHighlightActive( false ); @@ -2584,8 +2637,11 @@ void Controller::Impl::ChangeState( EventData::State newState ) mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE ); mEventData->mDecorator->StopCursorBlink(); mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false ); - mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, true ); - mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true ); + if ( mEventData->mGrabHandleEnabled ) + { + mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, true ); + mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true ); + } mEventData->mDecorator->SetHighlightActive( true ); if( mEventData->mGrabHandlePopupEnabled ) { @@ -2603,7 +2659,10 @@ void Controller::Impl::ChangeState( EventData::State newState ) { mEventData->mDecorator->StartCursorBlink(); } - mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + if ( mEventData->mGrabHandleEnabled ) + { + mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + } mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHighlightActive( false ); @@ -2624,7 +2683,10 @@ void Controller::Impl::ChangeState( EventData::State newState ) mEventData->mDecorator->StartCursorBlink(); } - mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + if ( mEventData->mGrabHandleEnabled ) + { + mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true ); + } mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false ); mEventData->mDecorator->SetHighlightActive( false ); @@ -2711,6 +2773,13 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, Text::GetCursorPosition( parameters, cursorInfo ); + // Adds Outline offset. + const float outlineWidth = static_cast( mModel->GetOutlineWidth() ); + cursorInfo.primaryPosition.x += outlineWidth; + cursorInfo.primaryPosition.y += outlineWidth; + cursorInfo.secondaryPosition.x += outlineWidth; + cursorInfo.secondaryPosition.y += outlineWidth; + if( isMultiLine ) { // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.