X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=7a51b86f374ccbc9167a00db2fca02176373b28d;hb=a3353d4f3763da656966e8e9a1c223c7e9585a13;hp=e3ee4d64d38c57733fbd6ef649dc862057edb39b;hpb=24ab5420ad958de9ba345b504de62881162c754b;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 e3ee4d6..7a51b86 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -196,7 +196,6 @@ bool Controller::Impl::ProcessInputEvents() } } - // The cursor must also be repositioned after inserts into the model if( mEventData->mUpdateCursorPosition ) { @@ -570,7 +569,8 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { ChangeState ( EventData::SELECTION_HANDLE_PANNING ); - if( handleNewPosition != mEventData->mLeftSelectionPosition ) + if( ( handleNewPosition != mEventData->mLeftSelectionPosition ) && + ( handleNewPosition != mEventData->mRightSelectionPosition ) ) { mEventData->mLeftSelectionPosition = handleNewPosition; @@ -584,7 +584,8 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { ChangeState ( EventData::SELECTION_HANDLE_PANNING ); - if( handleNewPosition != mEventData->mRightSelectionPosition ) + if( ( handleNewPosition != mEventData->mRightSelectionPosition ) && + ( handleNewPosition != mEventData->mLeftSelectionPosition ) ) { mEventData->mRightSelectionPosition = handleNewPosition; @@ -626,12 +627,13 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( handleStopScrolling ) { - mEventData->mUpdateLeftSelectionPosition = mEventData->mLeftSelectionPosition != handlePosition; + mEventData->mUpdateLeftSelectionPosition = ( mEventData->mLeftSelectionPosition != handlePosition ) && ( mEventData->mRightSelectionPosition != handlePosition); mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateLeftSelectionPosition; - mEventData->mLeftSelectionPosition = handlePosition; if( mEventData->mUpdateLeftSelectionPosition ) { + mEventData->mLeftSelectionPosition = handlePosition; + RepositionSelectionHandles( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition ); } @@ -643,12 +645,12 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( handleStopScrolling ) { - mEventData->mUpdateRightSelectionPosition = mEventData->mRightSelectionPosition != handlePosition; + mEventData->mUpdateRightSelectionPosition = ( mEventData->mRightSelectionPosition != handlePosition ) && ( mEventData->mLeftSelectionPosition != handlePosition ); mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateRightSelectionPosition; - mEventData->mRightSelectionPosition = handlePosition; if( mEventData->mUpdateRightSelectionPosition ) { + mEventData->mRightSelectionPosition = handlePosition; RepositionSelectionHandles( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition ); } @@ -661,50 +663,80 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { const float xSpeed = event.p2.mFloat; const Vector2& actualSize = mVisualModel->GetActualSize(); + const Vector2 currentScrollPosition = mEventData->mScrollPosition; mEventData->mScrollPosition.x += xSpeed; ClampHorizontalScroll( actualSize ); - const bool leftSelectionHandleEvent = Event::LEFT_SELECTION_HANDLE_EVENT == event.type; - const bool rightSelectionHandleEvent = Event::RIGHT_SELECTION_HANDLE_EVENT == event.type; - - if( Event::GRAB_HANDLE_EVENT == event.type ) + if( Vector2::ZERO == ( currentScrollPosition - mEventData->mScrollPosition ) ) { - ChangeState( EventData::GRAB_HANDLE_PANNING ); + // Notify the decorator there is no more text to scroll. + // The decorator won't send more scroll events. + mEventData->mDecorator->NotifyEndOfScroll(); } - else if( leftSelectionHandleEvent || rightSelectionHandleEvent ) + else { - // TODO: This is recalculating the selection box every time the text is scrolled with the selection handles. - // Think if something can be done to save power. + const bool scrollRightDirection = xSpeed > 0.f; + const bool leftSelectionHandleEvent = Event::LEFT_SELECTION_HANDLE_EVENT == event.type; + const bool rightSelectionHandleEvent = Event::RIGHT_SELECTION_HANDLE_EVENT == event.type; + + if( Event::GRAB_HANDLE_EVENT == event.type ) + { + ChangeState( EventData::GRAB_HANDLE_PANNING ); - ChangeState( EventData::SELECTION_HANDLE_PANNING ); + Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE ); - const Vector2& position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE ); + // Position the grag handle close to either the left or right edge. + position.x = scrollRightDirection ? 0.f : mControlSize.width; - // Get the new handle position. - // The selection handle's position is in decorator coords. Need to transforms to text coords. - const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x, - position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y ); + // Get the new handle position. + // The grab handle's position is in decorator coords. Need to transforms to text coords. + const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x, + position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y ); - if( leftSelectionHandleEvent ) - { - mEventData->mUpdateLeftSelectionPosition = handlePosition != mEventData->mLeftSelectionPosition; - mEventData->mLeftSelectionPosition = handlePosition; + mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition; + mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition; + mEventData->mPrimaryCursorPosition = handlePosition; } - else + else if( leftSelectionHandleEvent || rightSelectionHandleEvent ) { - mEventData->mUpdateRightSelectionPosition = handlePosition != mEventData->mRightSelectionPosition; - mEventData->mRightSelectionPosition = handlePosition; - } + // TODO: This is recalculating the selection box every time the text is scrolled with the selection handles. + // Think if something can be done to save power. - if( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition ) - { - RepositionSelectionHandles( mEventData->mLeftSelectionPosition, - mEventData->mRightSelectionPosition ); + ChangeState( EventData::SELECTION_HANDLE_PANNING ); + + Vector2 position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE ); + + // Position the selection handle close to either the left or right edge. + position.x = scrollRightDirection ? 0.f : mControlSize.width; + + // Get the new handle position. + // The selection handle's position is in decorator coords. Need to transforms to text coords. + const CharacterIndex handlePosition = GetClosestCursorIndex( position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x, + position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y ); + + if( leftSelectionHandleEvent ) + { + mEventData->mUpdateLeftSelectionPosition = handlePosition != mEventData->mLeftSelectionPosition; + mEventData->mLeftSelectionPosition = handlePosition; + } + else + { + mEventData->mUpdateRightSelectionPosition = handlePosition != mEventData->mRightSelectionPosition; + mEventData->mRightSelectionPosition = handlePosition; + } + + if( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition ) + { + RepositionSelectionHandles( mEventData->mLeftSelectionPosition, + mEventData->mRightSelectionPosition ); + + mEventData->mScrollAfterUpdatePosition = true; + } } + mEventData->mDecoratorUpdated = true; } - mEventData->mDecoratorUpdated = true; } // end ( HANDLE_SCROLLING == state ) } @@ -722,12 +754,17 @@ void Controller::Impl::OnSelectEvent( const Event& event ) const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x; const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y; + const CharacterIndex leftPosition = mEventData->mLeftSelectionPosition; + const CharacterIndex rightPosition = mEventData->mRightSelectionPosition; + RepositionSelectionHandles( xPosition, yPosition ); - mEventData->mScrollAfterUpdatePosition = true; - mEventData->mUpdateLeftSelectionPosition = true; - mEventData->mUpdateRightSelectionPosition = true; + mEventData->mUpdateLeftSelectionPosition = leftPosition != mEventData->mLeftSelectionPosition; + mEventData->mUpdateRightSelectionPosition = rightPosition != mEventData->mRightSelectionPosition; + + mEventData->mScrollAfterUpdatePosition = ( ( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition ) && + ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ) ); } } @@ -750,6 +787,64 @@ void Controller::Impl::OnSelectAllEvent() } } +void Controller::Impl::RetrieveSelection( std::string& selectedText, bool deleteAfterRetreival ) +{ + if( mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition ) + { + // Nothing to select if handles are in the same place. + selectedText=""; + return; + } + + //Get start and end position of selection + uint32_t startOfSelectedText = mEventData->mLeftSelectionPosition; + uint32_t lengthOfSelectedText = mEventData->mRightSelectionPosition - startOfSelectedText; + + // Validate the start and end selection points + if( ( startOfSelectedText >= 0 ) && ( ( startOfSelectedText + lengthOfSelectedText ) <= mLogicalModel->mText.Count() ) ) + { + //Get text as a UTF8 string + Vector& utf32Characters = mLogicalModel->mText; + + Utf32ToUtf8( &utf32Characters[startOfSelectedText], lengthOfSelectedText, selectedText ); + + if ( deleteAfterRetreival ) // Only delete text if copied successfully + { + // Delete text between handles + Vector& currentText = mLogicalModel->mText; + + Vector::Iterator first = currentText.Begin() + startOfSelectedText; + Vector::Iterator last = first + lengthOfSelectedText; + currentText.Erase( first, last ); + } + mEventData->mPrimaryCursorPosition = mEventData->mLeftSelectionPosition; + mEventData->mScrollAfterDelete = true; + mEventData->mDecoratorUpdated = true; + } +} + +bool Controller::Impl::CopyStringToClipboard( std::string& source ) +{ + //Send string to clipboard + return ( mClipboard && mClipboard.SetItem( source ) ); +} + +void Controller::Impl::SendSelectionToClipboard( bool deleteAfterSending ) +{ + std::string selectedText; + RetrieveSelection( selectedText, deleteAfterSending ); + CopyStringToClipboard( selectedText ); + ChangeState( EventData::EDITING ); +} + +void Controller::Impl::GetTextFromClipboard( unsigned int itemIndex, std::string& retreivedString ) +{ + if ( mClipboard ) + { + retreivedString = mClipboard.GetItem( itemIndex ); + } +} + void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart, CharacterIndex selectionEnd ) { if( selectionStart == selectionEnd ) @@ -906,6 +1001,7 @@ void Controller::Impl::ChangeState( EventData::State newState ) { buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) ); } + mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE ); mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow ); mEventData->mDecorator->SetPopupActive( true ); }