+ 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 );
+ }
+ 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 );
+
+ const Vector2& position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_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 );
+
+ 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->mDecoratorUpdated = true;
+ } // end ( HANDLE_SCROLLING == state )
+}
+
+void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart, CharacterIndex selectionEnd )
+{
+ mEventData->mDecorator->ClearHighlights();
+
+ mEventData->mLeftSelectionPosition = selectionStart;
+ mEventData->mRightSelectionPosition = selectionEnd;
+
+ const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
+ const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+ const GlyphInfo* const glyphsBuffer = mVisualModel->mGlyphs.Begin();
+ const Vector2* const positionsBuffer = mVisualModel->mGlyphPositions.Begin();
+
+ // TODO: Better algorithm to create the highlight box.
+ // TODO: Multi-line.
+
+ const Vector<LineRun>& lines = mVisualModel->mLines;
+ const float height = lines[0].ascender + -lines[0].descender;
+
+ const bool indicesSwapped = selectionStart > selectionEnd;
+ if( indicesSwapped )
+ {
+ std::swap( selectionStart, selectionEnd );