[3.0] Fix for single line text updates. 08/117308/3
authorVictor Cebollada <v.cebollada@samsung.com>
Fri, 3 Mar 2017 14:41:16 +0000 (14:41 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 3 Mar 2017 18:16:39 +0000 (10:16 -0800)
Change-Id: Idfe7b241c75fb3ec18ac73458bf4db1114ea5d64
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/text/cursor-helper-functions.cpp
dali-toolkit/internal/text/cursor-helper-functions.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller.cpp

index f1c44b0..63a934f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1265,7 +1265,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
   }
 }
 
-  void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
+void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 {
   Actor renderableActor;
 
index 1fbca0d..efeb837 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -421,25 +421,21 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
   return logicalIndex;
 }
 
-
-void GetCursorPosition( VisualModelPtr visualModel,
-                        LogicalModelPtr logicalModel,
-                        MetricsPtr metrics,
-                        CharacterIndex logical,
+void GetCursorPosition( GetCursorPositionParameters& parameters,
                         CursorInfo& cursorInfo )
 {
   // Whether the logical cursor position is at the end of the whole text.
-  const bool isLastPosition = logicalModel->mText.Count() == logical;
+  const bool isLastPosition = parameters.logicalModel->mText.Count() == parameters.logical;
 
   // Get the line where the character is laid-out.
-  const CharacterIndex characterOfLine = isLastPosition ? ( logical - 1u ) : logical;
+  const CharacterIndex characterOfLine = isLastPosition ? ( parameters.logical - 1u ) : parameters.logical;
 
   // Whether the cursor is in the last position and the last position is a new paragraph character.
-  const bool isLastNewParagraph = isLastPosition && TextAbstraction::IsNewParagraph( *( logicalModel->mText.Begin() + characterOfLine ) );
+  const bool isLastNewParagraph = parameters.isMultiline && isLastPosition && TextAbstraction::IsNewParagraph( *( parameters.logicalModel->mText.Begin() + characterOfLine ) );
 
-  const LineRun* const modelLines = visualModel->mLines.Begin();
+  const LineRun* const modelLines = parameters.visualModel->mLines.Begin();
 
-  const LineIndex lineIndex = visualModel->GetLineOfCharacter( characterOfLine );
+  const LineIndex lineIndex = parameters.visualModel->GetLineOfCharacter( characterOfLine );
   const LineRun& line = *( modelLines + lineIndex );
 
   if( isLastNewParagraph )
@@ -451,7 +447,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
     cursorInfo.isSecondaryCursor = false;
 
     // Set the line offset and height.
-    cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines,
+    cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines,
                                                  newLineIndex );
 
     // The line height is the addition of the line ascender and the line descender.
@@ -466,24 +462,24 @@ void GetCursorPosition( VisualModelPtr visualModel,
     cursorInfo.primaryPosition.y = cursorInfo.lineOffset;
 
     // Transform the cursor info from line's coords to text's coords.
-    cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : visualModel->mControlSize.width;
+    cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : parameters.visualModel->mControlSize.width;
   }
   else
   {
     // Whether this line is a bidirectional line.
-    const bool bidiLineFetched = logicalModel->FetchBidirectionalLineInfo( characterOfLine );
+    const bool bidiLineFetched = parameters.logicalModel->FetchBidirectionalLineInfo( characterOfLine );
 
     // Check if the logical position is the first or the last one of the line.
-    const bool isFirstPositionOfLine = line.characterRun.characterIndex == logical;
-    const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == logical;
+    const bool isFirstPositionOfLine = line.characterRun.characterIndex == parameters.logical;
+    const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == parameters.logical;
 
     // 'logical' is the logical 'cursor' index.
     // Get the next and current logical 'character' index.
-    const CharacterIndex characterIndex = isFirstPositionOfLine ? logical : logical - 1u;
-    const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : logical;
+    const CharacterIndex characterIndex = isFirstPositionOfLine ? parameters.logical : parameters.logical - 1u;
+    const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : parameters.logical;
 
     // The character's direction buffer.
-    const CharacterDirection* const directionsBuffer = bidiLineFetched ? logicalModel->mCharacterDirections.Begin() : NULL;
+    const CharacterDirection* const directionsBuffer = bidiLineFetched ? parameters.logicalModel->mCharacterDirections.Begin() : NULL;
 
     CharacterDirection isCurrentRightToLeft = false;
     CharacterDirection isNextRightToLeft = false;
@@ -502,7 +498,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                                      ( isFirstPositionOfLine && ( isRightToLeftParagraph != isCurrentRightToLeft ) ) );
 
     // Set the line offset and height.
-    cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines,
+    cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines,
                                                  lineIndex );
 
     // The line height is the addition of the line ascender and the line descender.
@@ -527,7 +523,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
         index = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u;
         if( bidiLineFetched )
         {
-          index = logicalModel->GetLogicalCharacterIndex( index );
+          index = parameters.logicalModel->GetLogicalCharacterIndex( index );
         }
       }
       else if( isFirstPositionOfLine )
@@ -535,7 +531,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
         index = isRightToLeftParagraph ? line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u : line.characterRun.characterIndex;
         if( bidiLineFetched )
         {
-          index = logicalModel->GetLogicalCharacterIndex( index );
+          index = parameters.logicalModel->GetLogicalCharacterIndex( index );
         }
       }
       else
@@ -544,12 +540,12 @@ void GetCursorPosition( VisualModelPtr visualModel,
       }
     }
 
-    const GlyphIndex* const charactersToGlyphBuffer = visualModel->mCharactersToGlyph.Begin();
-    const Length* const glyphsPerCharacterBuffer = visualModel->mGlyphsPerCharacter.Begin();
-    const Length* const charactersPerGlyphBuffer = visualModel->mCharactersPerGlyph.Begin();
-    const CharacterIndex* const glyphsToCharactersBuffer = visualModel->mGlyphsToCharacters.Begin();
-    const Vector2* const glyphPositionsBuffer = visualModel->mGlyphPositions.Begin();
-    const GlyphInfo* const glyphInfoBuffer = visualModel->mGlyphs.Begin();
+    const GlyphIndex* const charactersToGlyphBuffer = parameters.visualModel->mCharactersToGlyph.Begin();
+    const Length* const glyphsPerCharacterBuffer = parameters.visualModel->mGlyphsPerCharacter.Begin();
+    const Length* const charactersPerGlyphBuffer = parameters.visualModel->mCharactersPerGlyph.Begin();
+    const CharacterIndex* const glyphsToCharactersBuffer = parameters.visualModel->mGlyphsToCharacters.Begin();
+    const Vector2* const glyphPositionsBuffer = parameters.visualModel->mGlyphPositions.Begin();
+    const GlyphInfo* const glyphInfoBuffer = parameters.visualModel->mGlyphs.Begin();
 
     // Convert the cursor position into the glyph position.
     const GlyphIndex primaryGlyphIndex = *( charactersToGlyphBuffer + index );
@@ -562,7 +558,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                       primaryNumberOfGlyphs,
                       glyphMetrics,
                       glyphInfoBuffer,
-                      metrics );
+                      parameters.metrics );
 
     // Whether to add the glyph's advance to the cursor position.
     // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added,
@@ -654,7 +650,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                         secondaryNumberOfGlyphs,
                         glyphMetrics,
                         glyphInfoBuffer,
-                        metrics );
+                        parameters.metrics );
 
       // Set the secondary cursor's position.
 
index 5896b4d..1578494 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_TEXT_CURSOR_HELPER_FUNCTIONS_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,6 +57,18 @@ struct CursorInfo
 };
 
 /**
+ * @brief Parameters passed to the GetCursorPosition() function.
+ */
+struct GetCursorPositionParameters
+{
+  VisualModelPtr visualModel;   ///< The visual model.
+  LogicalModelPtr logicalModel; ///< The logical model.
+  MetricsPtr metrics;           ///< A wrapper around FontClient used to get metrics.
+  CharacterIndex logical;       ///< The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+  bool isMultiline;             ///< Whether the text control is multi-line.
+};
+
+/**
  * @brief Retrieves the closest line for a given touch point.
  *
  * It returns the first line if the touch point is above the text and the last line if the touch point is below.
@@ -106,16 +118,10 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
  * It retrieves as well the line's height and the cursor's height and
  * if there is a valid alternative cursor, its position and height.
  *
- * @param[in] visualModel The visual model.
- * @param[in] logicalModel The logical model.
- * @param[in] metrics A wrapper around FontClient used to get metrics.
- * @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+ * @param[in] parameters Parameters used to calculate the cursor's position.
  * @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor.
  */
-void GetCursorPosition( VisualModelPtr visualModel,
-                        LogicalModelPtr logicalModel,
-                        MetricsPtr metrics,
-                        CharacterIndex logical,
+void GetCursorPosition( GetCursorPositionParameters& parameters,
                         CursorInfo& cursorInfo );
 
 /**
index 46db2dc..2f7dd46 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1695,8 +1695,18 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
       mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
 
       // Mark the paragraphs to be updated.
-      mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
-      mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      if( LayoutEngine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
+      {
+        mTextUpdateInfo.mCharacterIndex = 0;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mTextUpdateInfo.mNumberOfCharactersToAdd = mTextUpdateInfo.mPreviousNumberOfCharacters - lengthOfSelectedText;
+        mTextUpdateInfo.mClearAll = true;
+      }
+      else
+      {
+        mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      }
 
       // Delete text between handles
       Vector<Character>::Iterator first = utf32Characters.Begin() + startOfSelectedText;
@@ -2515,13 +2525,18 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     return;
   }
 
-  Text::GetCursorPosition( mVisualModel,
-                           mLogicalModel,
-                           mMetrics,
-                           logical,
+  const bool isMultiLine = ( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() );
+  GetCursorPositionParameters parameters;
+  parameters.visualModel = mVisualModel;
+  parameters.logicalModel = mLogicalModel;
+  parameters.metrics = mMetrics;
+  parameters.logical = logical;
+  parameters.isMultiline = isMultiLine;
+
+  Text::GetCursorPosition( parameters,
                            cursorInfo );
 
-  if( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
+  if( isMultiLine )
   {
     // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
 
@@ -2737,13 +2752,16 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, flo
     mScrollPosition.x = mVisualModel->mControlSize.width - positionEndX;
   }
 
-  if( decoratorPositionBeginY < 0.f )
-  {
-    mScrollPosition.y = -position.y;
-  }
-  else if( decoratorPositionEndY > mVisualModel->mControlSize.height )
+  if( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
   {
-    mScrollPosition.y = mVisualModel->mControlSize.height - positionEndY;
+    if( decoratorPositionBeginY < 0.f )
+    {
+      mScrollPosition.y = -position.y;
+    }
+    else if( decoratorPositionEndY > mVisualModel->mControlSize.height )
+    {
+      mScrollPosition.y = mVisualModel->mControlSize.height - positionEndY;
+    }
   }
 }
 
@@ -2754,10 +2772,13 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
 
   // Calculate the offset to match the cursor position before the character was deleted.
   mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
-  mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset;
-
   ClampHorizontalScroll( mVisualModel->GetLayoutSize() );
-  ClampVerticalScroll( mVisualModel->GetLayoutSize() );
+
+  if( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
+  {
+    mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset;
+    ClampVerticalScroll( mVisualModel->GetLayoutSize() );
+  }
 
   // Makes the new cursor position visible if needed.
   ScrollToMakePositionVisible( cursorInfo.primaryPosition, cursorInfo.lineHeight );
index d00e079..b52e739 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -2356,8 +2356,18 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     }
 
     // Mark the first paragraph to be updated.
-    mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
-    mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
+    if( LayoutEngine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
+    {
+      mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = numberOfCharactersInModel + maxSizeOfNewText;
+      mImpl->mTextUpdateInfo.mClearAll = true;
+    }
+    else
+    {
+      mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
+    }
 
     // Update the cursor index.
     cursorIndex += maxSizeOfNewText;
@@ -2456,8 +2466,18 @@ bool Controller::RemoveText( int cursorOffset,
         ( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) )
     {
       // Mark the paragraphs to be updated.
-      mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
-      mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters;
+      if( LayoutEngine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
+      {
+        mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters - numberOfCharacters;
+        mImpl->mTextUpdateInfo.mClearAll = true;
+      }
+      else
+      {
+        mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters;
+      }
 
       // Update the input style and remove the text's style before removing the text.