Fix the cursor position when retrieving the selected text.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
index 55b5893..795a929 100644 (file)
@@ -33,7 +33,7 @@ namespace
 {
 
 #if defined(DEBUG_ENABLED)
-  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
 /**
@@ -58,8 +58,6 @@ struct GlyphMetrics
   float xBearing;   ///< The x bearing of the first glyph.
 };
 
-const std::string EMPTY_STRING("");
-
 } // namespace
 
 namespace Dali
@@ -279,6 +277,8 @@ bool Controller::Impl::ProcessInputEvents()
 
 void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::UpdateModel\n" );
+
   // Calculate the operations to be done.
   const OperationsMask operations = static_cast<OperationsMask>( mOperationsPending & operationsRequired );
 
@@ -463,6 +463,7 @@ void Controller::Impl::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfC
 {
   if( mFontDefaults )
   {
+    DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::GetDefaultFonts font family(%s)\n", mFontDefaults->mFontDescription.family.c_str() );
     FontRun fontRun;
     fontRun.characterRun.characterIndex = 0;
     fontRun.characterRun.numberOfCharacters = numberOfCharacters;
@@ -478,8 +479,8 @@ float Controller::Impl::GetDefaultFontLineHeight()
   FontId defaultFontId = 0u;
   if( NULL == mFontDefaults )
   {
-    defaultFontId = mFontClient.GetFontId( EMPTY_STRING,
-                                           EMPTY_STRING );
+    TextAbstraction::FontDescription fontDescription;
+    defaultFontId = mFontClient.GetFontId( fontDescription );
   }
   else
   {
@@ -876,9 +877,11 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
     return;
   }
 
+  const bool handlesCrossed = mEventData->mLeftSelectionPosition > mEventData->mRightSelectionPosition;
+
   //Get start and end position of selection
-  uint32_t startOfSelectedText = mEventData->mLeftSelectionPosition;
-  uint32_t lengthOfSelectedText =  mEventData->mRightSelectionPosition - startOfSelectedText;
+  uint32_t startOfSelectedText = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
+  uint32_t lengthOfSelectedText =  ( handlesCrossed ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition ) - startOfSelectedText;
 
   // Validate the start and end selection points
   if(  ( startOfSelectedText + lengthOfSelectedText ) <=  mLogicalModel->mText.Count() )
@@ -896,10 +899,12 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
       Vector<Character>::Iterator first = currentText.Begin() + startOfSelectedText;
       Vector<Character>::Iterator last  = first + lengthOfSelectedText;
       currentText.Erase( first, last );
+
+      // Scroll after delete.
+      mEventData->mPrimaryCursorPosition = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
+      mEventData->mScrollAfterDelete = true;
+      mEventData->mDecoratorUpdated = true;
     }
-    mEventData->mPrimaryCursorPosition = mEventData->mLeftSelectionPosition;
-    mEventData->mScrollAfterDelete = true;
-    mEventData->mDecoratorUpdated = true;
   }
 }
 
@@ -970,8 +975,16 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
   const LineRun& firstLine = *lines.Begin();
   const float height = firstLine.ascender + -firstLine.descender;
 
+  const bool isLastCharacter = selectionEnd >= mLogicalModel->mText.Count();
+  const bool startDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + selectionStart ) );
+  const bool endDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + ( selectionEnd - ( isLastCharacter ? 1u : 0u ) ) ) );
+
   // Swap the indices if the start is greater than the end.
-  const bool indicesSwapped = ( selectionStart > selectionEnd );
+  const bool indicesSwapped = selectionStart > selectionEnd;
+
+  // Tell the decorator to flip the selection handles if needed.
+  mEventData->mDecorator->SetSelectionHandleFlipState( indicesSwapped, startDirection, endDirection );
+
   if( indicesSwapped )
   {
     std::swap( selectionStart, selectionEnd );
@@ -991,9 +1004,6 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
   const Length numberOfCharactersEnd = *( charactersPerGlyphBuffer + glyphEnd );
   bool splitEndGlyph = ( glyphStart != glyphEnd ) && ( numberOfCharactersEnd > 1u ) && HasLigatureMustBreak( mLogicalModel->GetScript( selectionEndMinusOne ) );
 
-  // Tell the decorator to swap the selection handles if needed.
-  mEventData->mDecorator->SwapSelectionHandlesEnabled( firstLine.direction != indicesSwapped );
-
   const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
 
   // Traverse the glyphs.
@@ -1078,7 +1088,7 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
   mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, secondaryPosition.x, secondaryPosition.y, secondaryCursorInfo.lineHeight );
 
   // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection
-  mEventData->mPrimaryCursorPosition = (indicesSwapped)?mEventData->mLeftSelectionPosition:mEventData->mRightSelectionPosition;
+  mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition;
 
   // Set the flag to update the decorator.
   mEventData->mDecoratorUpdated = true;
@@ -1519,7 +1529,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
-    cursorInfo.primaryPosition.x = mEventData->mDecorator->GetCursorWidth();
+    cursorInfo.primaryPosition.x = 0.f;
     cursorInfo.primaryPosition.y = 0.f;
 
     // Nothing else to do.
@@ -1768,8 +1778,8 @@ void Controller::Impl::UpdateCursorPosition()
     FontId defaultFontId = 0u;
     if( NULL == mFontDefaults )
     {
-      defaultFontId = mFontClient.GetFontId( EMPTY_STRING,
-                                             EMPTY_STRING );
+      TextAbstraction::FontDescription fontDescription;
+      defaultFontId = mFontClient.GetFontId( fontDescription );
     }
     else
     {
@@ -1788,7 +1798,7 @@ void Controller::Impl::UpdateCursorPosition()
     {
       case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
       {
-        cursorPosition.x = mEventData->mDecorator->GetCursorWidth();
+        cursorPosition.x = 0.f;
         break;
       }
       case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
@@ -1798,7 +1808,7 @@ void Controller::Impl::UpdateCursorPosition()
       }
       case LayoutEngine::HORIZONTAL_ALIGN_END:
       {
-        cursorPosition.x = mVisualModel->mControlSize.width;
+        cursorPosition.x = mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
         break;
       }
     }