X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=d09e1edb91d33002d8dd268560bb54d745282b1b;hb=49156a77e39850cdb7f77143dc54ed2701c476ca;hp=da7d92943081f54548cc1ab935672d82990d64d1;hpb=3705a737006a61c9796ee5f237c88d623fc65cbc;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 da7d929..d09e1ed 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -55,7 +55,6 @@ struct SelectionBoxInfo const float MAX_FLOAT = std::numeric_limits::max(); const float MIN_FLOAT = std::numeric_limits::min(); const Dali::Toolkit::Text::CharacterDirection LTR = false; ///< Left To Right direction -const uint32_t STAR = 0x2A; } // namespace @@ -84,6 +83,8 @@ EventData::EventData( DecoratorPtr decorator ) mPreEditStartPosition( 0u ), mPreEditLength( 0u ), mCursorHookPositionX( 0.f ), + mDoubleTapAction( Controller::NoTextTap::NO_ACTION ), + mLongPressAction( Controller::NoTextTap::SHOW_SELECTION_POPUP ), mIsShowingPlaceholderText( false ), mPreEditFlag( false ), mDecoratorUpdated( false ), @@ -97,6 +98,7 @@ EventData::EventData( DecoratorPtr decorator ) mUpdateLeftSelectionPosition( false ), mUpdateRightSelectionPosition( false ), mIsLeftHandleSelected( false ), + mIsRightHandleSelected( false ), mUpdateHighlightBox( false ), mScrollAfterUpdatePosition( false ), mScrollAfterDelete( false ), @@ -227,10 +229,25 @@ bool Controller::Impl::ProcessInputEvents() if( mEventData->mScrollAfterUpdatePosition && ( mEventData->mIsLeftHandleSelected ? mEventData->mUpdateLeftSelectionPosition : mEventData->mUpdateRightSelectionPosition ) ) { - CursorInfo& info = mEventData->mIsLeftHandleSelected ? leftHandleInfo : rightHandleInfo; + if( mEventData->mIsLeftHandleSelected && mEventData->mIsRightHandleSelected ) + { + CursorInfo& infoLeft = leftHandleInfo; + + const Vector2 currentCursorPositionLeft( infoLeft.primaryPosition.x, infoLeft.lineOffset ); + ScrollToMakePositionVisible( currentCursorPositionLeft, infoLeft.lineHeight ); + + CursorInfo& infoRight = rightHandleInfo; + + const Vector2 currentCursorPositionRight( infoRight.primaryPosition.x, infoRight.lineOffset ); + ScrollToMakePositionVisible( currentCursorPositionRight, infoRight.lineHeight ); + } + else + { + CursorInfo& info = mEventData->mIsLeftHandleSelected ? leftHandleInfo : rightHandleInfo; - const Vector2 currentCursorPosition( info.primaryPosition.x, info.lineOffset ); - ScrollToMakePositionVisible( currentCursorPosition, info.lineHeight ); + const Vector2 currentCursorPosition( info.primaryPosition.x, info.lineOffset ); + ScrollToMakePositionVisible( currentCursorPosition, info.lineHeight ); + } } } @@ -261,6 +278,8 @@ bool Controller::Impl::ProcessInputEvents() mEventData->mUpdateLeftSelectionPosition = false; mEventData->mUpdateRightSelectionPosition = false; mEventData->mUpdateHighlightBox = false; + mEventData->mIsLeftHandleSelected = false; + mEventData->mIsRightHandleSelected = false; } mEventData->mScrollAfterUpdatePosition = false; @@ -769,24 +788,16 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) return false; } - Vector utf32CharactersStar; - const Length characterCount = mModel->mLogicalModel->mText.Count(); - const bool isPasswordInput = ( mEventData != NULL && mEventData->mPasswordInput && - !mEventData->mIsShowingPlaceholderText && characterCount > 0 ); - - if (isPasswordInput) + Vector& srcCharacters = mModel->mLogicalModel->mText; + Vector displayCharacters; + bool useHiddenText = false; + if ( mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText) { - utf32CharactersStar.Resize( characterCount ); - - uint32_t* begin = utf32CharactersStar.Begin(); - uint32_t* end = begin + characterCount; - while ( begin < end ) - { - *begin++ = STAR; - } + mHiddenInput->Substitute( srcCharacters,displayCharacters ); + useHiddenText = true; } - Vector& utf32Characters = isPasswordInput ? utf32CharactersStar : mModel->mLogicalModel->mText; + Vector& utf32Characters = useHiddenText ? displayCharacters : srcCharacters; const Length numberOfCharacters = utf32Characters.Count(); // Index to the first character of the first paragraph to be updated. @@ -1165,13 +1176,16 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) const float hitPointY = cursorInfo.lineOffset - 0.5f * ( line.ascender - line.descender ); // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. + bool matchedCharacter = false; mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, mEventData->mCursorHookPositionX, - hitPointY ); + hitPointY, + CharacterHitTest::TAP, + matchedCharacter ); } - else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode ) + else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode ) { // Get first the line index of the current cursor position index. CharacterIndex characterIndex = 0u; @@ -1197,11 +1211,14 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * ( line.ascender - line.descender ); // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. + bool matchedCharacter = false; mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, mEventData->mCursorHookPositionX, - hitPointY ); + hitPointY, + CharacterHitTest::TAP, + matchedCharacter ); } } @@ -1227,11 +1244,15 @@ void Controller::Impl::OnTapEvent( const Event& event ) // Keep the tap 'x' position. Used to move the cursor. mEventData->mCursorHookPositionX = xPosition; + // Whether to touch point hits on a glyph. + bool matchedCharacter = false; mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, xPosition, - yPosition ); + yPosition, + CharacterHitTest::TAP, + matchedCharacter ); // When the cursor position is changing, delay cursor blinking mEventData->mDecorator->DelayCursorBlink(); @@ -1253,6 +1274,20 @@ void Controller::Impl::OnTapEvent( const Event& event ) mEventData->mImfManager.NotifyCursorPosition(); } } + else if( 2u == tapCount ) + { + if( mEventData->mSelectionEnabled ) + { + // Convert from control's coords to text's coords. + const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x; + const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y; + + // Calculates the logical position from the x,y coords. + RepositionSelectionHandles( xPosition, + yPosition, + mEventData->mDoubleTapAction ); + } + } } } @@ -1323,12 +1358,26 @@ void Controller::Impl::OnLongPressEvent( const Event& event ) { DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::OnLongPressEvent\n" ); - if( EventData::EDITING == mEventData->mState ) + if( !IsShowingRealText() && ( EventData::EDITING == mEventData->mState ) ) { - ChangeState ( EventData::EDITING_WITH_POPUP ); + ChangeState( EventData::EDITING_WITH_POPUP ); mEventData->mDecoratorUpdated = true; mEventData->mUpdateInputStyle = true; } + else + { + if( mEventData->mSelectionEnabled ) + { + // Convert from control's coords to text's coords. + const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x; + const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y; + + // Calculates the logical position from the x,y coords. + RepositionSelectionHandles( xPosition, + yPosition, + mEventData->mLongPressAction ); + } + } } void Controller::Impl::OnHandleEvent( const Event& event ) @@ -1350,11 +1399,14 @@ void Controller::Impl::OnHandleEvent( const Event& event ) const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y; // Need to calculate the handle's new position. + bool matchedCharacter = false; const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, xPosition, - yPosition ); + yPosition, + CharacterHitTest::SCROLL, + matchedCharacter ); if( Event::GRAB_HANDLE_EVENT == event.type ) { @@ -1391,6 +1443,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) // Will define the order to scroll the text to match the handle position. mEventData->mIsLeftHandleSelected = true; + mEventData->mIsRightHandleSelected = false; } else if( Event::RIGHT_SELECTION_HANDLE_EVENT == event.type ) { @@ -1411,6 +1464,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) // Will define the order to scroll the text to match the handle position. mEventData->mIsLeftHandleSelected = false; + mEventData->mIsRightHandleSelected = true; } } // end ( HANDLE_PRESSED == state ) else if( ( HANDLE_RELEASED == state ) || @@ -1423,11 +1477,14 @@ void Controller::Impl::OnHandleEvent( const Event& event ) const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x; const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y; + bool matchedCharacter = false; handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, xPosition, - yPosition ); + yPosition, + CharacterHitTest::SCROLL, + matchedCharacter ); } if( Event::GRAB_HANDLE_EVENT == event.type ) @@ -1539,11 +1596,14 @@ void Controller::Impl::OnHandleEvent( const Event& event ) // Get the new handle position. // The grab handle's position is in decorator's coords. Need to transforms to text's coords. + bool matchedCharacter = false; const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, position.x - mModel->mScrollPosition.x, - position.y - mModel->mScrollPosition.y ); + position.y - mModel->mScrollPosition.y, + CharacterHitTest::SCROLL, + matchedCharacter ); if( mEventData->mPrimaryCursorPosition != handlePosition ) { @@ -1580,11 +1640,14 @@ void Controller::Impl::OnHandleEvent( const Event& event ) // Get the new handle position. // The selection handle's position is in decorator's coords. Need to transform to text's coords. + bool matchedCharacter = false; const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, position.x - mModel->mScrollPosition.x, - position.y - mModel->mScrollPosition.y ); + position.y - mModel->mScrollPosition.y, + CharacterHitTest::SCROLL, + matchedCharacter ); if( leftSelectionHandleEvent ) { @@ -1637,7 +1700,8 @@ void Controller::Impl::OnSelectEvent( const Event& event ) // Calculates the logical position from the x,y coords. RepositionSelectionHandles( xPosition, - yPosition ); + yPosition, + Controller::NoTextTap::HIGHLIGHT ); } } @@ -2168,7 +2232,7 @@ void Controller::Impl::RepositionSelectionHandles() mEventData->mDecoratorUpdated = true; } -void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY ) +void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY, Controller::NoTextTap::Action action ) { if( NULL == mEventData ) { @@ -2194,16 +2258,18 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY // Find which word was selected CharacterIndex selectionStart( 0 ); CharacterIndex selectionEnd( 0 ); - const bool indicesFound = FindSelectionIndices( mModel->mVisualModel, + CharacterIndex noTextHitIndex( 0 ); + const bool characterHit = FindSelectionIndices( mModel->mVisualModel, mModel->mLogicalModel, mMetrics, visualX, visualY, selectionStart, - selectionEnd ); + selectionEnd, + noTextHitIndex ); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p selectionStart %d selectionEnd %d\n", this, selectionStart, selectionEnd ); - if( indicesFound ) + if( characterHit || ( Controller::NoTextTap::HIGHLIGHT == action ) ) { ChangeState( EventData::SELECTING ); @@ -2222,12 +2288,22 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ); } - else + else if( Controller::NoTextTap::SHOW_SELECTION_POPUP == action ) { // Nothing to select. i.e. a white space, out of bounds - ChangeState( EventData::EDITING ); + ChangeState( EventData::EDITING_WITH_POPUP ); + + mEventData->mPrimaryCursorPosition = noTextHitIndex; - mEventData->mPrimaryCursorPosition = selectionEnd; + mEventData->mUpdateCursorPosition = true; + mEventData->mUpdateGrabHandlePosition = true; + mEventData->mScrollAfterUpdatePosition = true; + mEventData->mUpdateInputStyle = true; + } + else if( Controller::NoTextTap::NO_ACTION == action ) + { + // Nothing to select. i.e. a white space, out of bounds + mEventData->mPrimaryCursorPosition = noTextHitIndex; mEventData->mUpdateCursorPosition = true; mEventData->mUpdateGrabHandlePosition = true;