+ if( Vector2::ZERO == ( currentScrollPosition - mEventData->mScrollPosition ) )
+ {
+ // Notify the decorator there is no more text to scroll.
+ // The decorator won't send more scroll events.
+ mEventData->mDecorator->NotifyEndOfScroll();
+ }
+ else
+ {
+ 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 );
+
+ Vector2 position = mEventData->mDecorator->GetPosition( GRAB_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 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 if( leftSelectionHandleEvent || rightSelectionHandleEvent )
+ {
+ // 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.
+
+ 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;
+ }
+ } // end ( HANDLE_SCROLLING == state )
+}
+
+void Controller::Impl::OnSelectEvent( const Event& event )
+{
+ if( NULL == mEventData )
+ {
+ // Nothing to do if there is no text.
+ return;
+ }
+
+ if( mEventData->mSelectionEnabled )
+ {
+ // The event.p2 and event.p3 are in decorator coords. Need to transforms to text coords.
+ 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->mUpdateLeftSelectionPosition = leftPosition != mEventData->mLeftSelectionPosition;
+ mEventData->mUpdateRightSelectionPosition = rightPosition != mEventData->mRightSelectionPosition;
+
+ mEventData->mScrollAfterUpdatePosition = ( ( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition ) &&
+ ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ) );