+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::UpdateCursorPosition\n" );
+}
+
+void Controller::Impl::UpdateSelectionHandle( HandleType handleType )
+{
+ if( ( LEFT_SELECTION_HANDLE != handleType ) &&
+ ( RIGHT_SELECTION_HANDLE != handleType ) )
+ {
+ return;
+ }
+
+ const bool leftSelectionHandle = LEFT_SELECTION_HANDLE == handleType;
+ const CharacterIndex index = leftSelectionHandle ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition;
+
+ CursorInfo cursorInfo;
+ GetCursorPosition( index,
+ cursorInfo );
+
+ const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
+ const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
+
+ // Sets the grab handle position.
+ mEventData->mDecorator->SetPosition( handleType,
+ cursorPosition.x,
+ cursorPosition.y,
+ cursorInfo.lineHeight );
+}
+
+void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize )
+{
+ // Clamp between -space & 0 (and the text alignment).
+ if( actualSize.width > mControlSize.width )
+ {
+ const float space = ( actualSize.width - mControlSize.width ) + mAlignmentOffset.x;
+ mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x < -space ) ? -space : mEventData->mScrollPosition.x;
+ mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x > -mAlignmentOffset.x ) ? -mAlignmentOffset.x : mEventData->mScrollPosition.x;
+
+ mEventData->mDecoratorUpdated = true;
+ }
+ else
+ {
+ mEventData->mScrollPosition.x = 0.f;
+ }
+}
+
+void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize )
+{
+ // Clamp between -space & 0 (and the text alignment).
+ if( actualSize.height > mControlSize.height )
+ {
+ const float space = ( actualSize.height - mControlSize.height ) + mAlignmentOffset.y;
+ mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y < -space ) ? -space : mEventData->mScrollPosition.y;
+ mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y > -mAlignmentOffset.y ) ? -mAlignmentOffset.y : mEventData->mScrollPosition.y;
+
+ mEventData->mDecoratorUpdated = true;
+ }
+ else
+ {
+ mEventData->mScrollPosition.y = 0.f;
+ }
+}
+
+void Controller::Impl::ScrollToMakeCursorVisible()
+{
+ if( NULL == mEventData )
+ {
+ // Nothing to do if there is no text input.
+ return;
+ }
+
+ const Vector2& primaryCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
+
+ Vector2 offset;
+ bool updateDecorator = false;
+ if( primaryCursorPosition.x < 0.f )
+ {
+ offset.x = -primaryCursorPosition.x;
+ mEventData->mScrollPosition.x += offset.x;
+ updateDecorator = true;
+ }
+ else if( primaryCursorPosition.x > mControlSize.width )
+ {
+ offset.x = mControlSize.width - primaryCursorPosition.x;
+ mEventData->mScrollPosition.x += offset.x;
+ updateDecorator = true;
+ }
+
+ if( updateDecorator && mEventData->mDecorator )
+ {
+ mEventData->mDecorator->UpdatePositions( offset );
+ }