}
}
-
// The cursor must also be repositioned after inserts into the model
if( mEventData->mUpdateCursorPosition )
{
{
ChangeState ( EventData::SELECTION_HANDLE_PANNING );
- if( handleNewPosition != mEventData->mLeftSelectionPosition )
+ if( ( handleNewPosition != mEventData->mLeftSelectionPosition ) &&
+ ( handleNewPosition != mEventData->mRightSelectionPosition ) )
{
mEventData->mLeftSelectionPosition = handleNewPosition;
{
ChangeState ( EventData::SELECTION_HANDLE_PANNING );
- if( handleNewPosition != mEventData->mRightSelectionPosition )
+ if( ( handleNewPosition != mEventData->mRightSelectionPosition ) &&
+ ( handleNewPosition != mEventData->mLeftSelectionPosition ) )
{
mEventData->mRightSelectionPosition = handleNewPosition;
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 );
}
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 );
}
{
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;
- ChangeState( EventData::SELECTION_HANDLE_PANNING );
+ if( Event::GRAB_HANDLE_EVENT == event.type )
+ {
+ ChangeState( EventData::GRAB_HANDLE_PANNING );
- const Vector2& position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE );
+ Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE );
- // 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 );
+ // Position the grag handle close to either the left or right edge.
+ position.x = scrollRightDirection ? 0.f : mControlSize.width;
- if( leftSelectionHandleEvent )
- {
- mEventData->mUpdateLeftSelectionPosition = handlePosition != mEventData->mLeftSelectionPosition;
- mEventData->mLeftSelectionPosition = handlePosition;
+ // 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 );
+
+ 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 )
}
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 ) );
}
}
}
}
+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<Character>& utf32Characters = mLogicalModel->mText;
+
+ Utf32ToUtf8( &utf32Characters[startOfSelectedText], lengthOfSelectedText, selectedText );
+
+ if ( deleteAfterRetreival ) // Only delete text if copied successfully
+ {
+ // Delete text between handles
+ Vector<Character>& currentText = mLogicalModel->mText;
+
+ Vector<Character>::Iterator first = currentText.Begin() + startOfSelectedText;
+ Vector<Character>::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 )
{
buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
}
+ mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow );
mEventData->mDecorator->SetPopupActive( true );
}
cursorInfo.lineHeight = fontMetrics.ascender - fontMetrics.descender;
cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
- cursorInfo.primaryPosition.x = 0.f;
+ cursorInfo.primaryPosition.x = 1.f;
cursorInfo.primaryPosition.y = 0.f;
// Nothing else to do.
mEventData->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x - mAlignmentOffset.x;
ClampHorizontalScroll( mVisualModel->GetActualSize() );
- bool updateCursorPosition = true;
const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
- if( updateCursorPosition )
- {
- // Sets the cursor position.
- mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
- cursorPosition.x,
- cursorPosition.y,
- cursorInfo.primaryCursorHeight,
- cursorInfo.lineHeight );
+ // Sets the cursor position.
+ mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
+ cursorPosition.x,
+ cursorPosition.y,
+ cursorInfo.primaryCursorHeight,
+ cursorInfo.lineHeight );
- // Sets the grab handle position.
- mEventData->mDecorator->SetPosition( GRAB_HANDLE,
- cursorPosition.x,
- cursorPosition.y,
- cursorInfo.lineHeight );
+ // Sets the grab handle position.
+ mEventData->mDecorator->SetPosition( GRAB_HANDLE,
+ cursorPosition.x,
+ cursorPosition.y,
+ cursorInfo.lineHeight );
- if( cursorInfo.isSecondaryCursor )
- {
- mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_BOTH );
- mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
- cursorInfo.secondaryPosition.x + offset.x,
- cursorInfo.secondaryPosition.y + offset.y,
- cursorInfo.secondaryCursorHeight,
- cursorInfo.lineHeight );
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + offset.x, cursorInfo.secondaryPosition.y + offset.y );
- }
- else
- {
- mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
- }
+ if( cursorInfo.isSecondaryCursor )
+ {
+ mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_BOTH );
+ mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
+ cursorInfo.secondaryPosition.x + offset.x,
+ cursorInfo.secondaryPosition.y + offset.y,
+ cursorInfo.secondaryCursorHeight,
+ cursorInfo.lineHeight );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + offset.x, cursorInfo.secondaryPosition.y + offset.y );
+ }
+ else
+ {
+ mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
}
}