Add Text Preedit Style
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index b40dba5..2c9a78d
@@ -67,9 +67,9 @@ namespace Toolkit
 namespace Text
 {
 
-EventData::EventData( DecoratorPtr decorator )
+EventData::EventData( DecoratorPtr decorator, InputMethodContext& inputMethodContext )
 : mDecorator( decorator ),
-  mImfManager(),
+  mInputMethodContext( inputMethodContext ),
   mPlaceholderFont( NULL ),
   mPlaceholderTextActive(),
   mPlaceholderTextInactive(),
@@ -106,12 +106,13 @@ EventData::EventData( DecoratorPtr decorator )
   mAllTextSelected( false ),
   mUpdateInputStyle( false ),
   mPasswordInput( false ),
+  mCheckScrollAmount( false ),
   mIsPlaceholderPixelSize( false ),
   mIsPlaceholderElideEnabled( false ),
   mPlaceholderEllipsisFlag( false ),
-  mShiftSelectionFlag( true )
+  mShiftSelectionFlag( true ),
+  mUpdateAlignment( false )
 {
-  mImfManager = ImfManager::Get();
 }
 
 EventData::~EventData()
@@ -179,7 +180,7 @@ bool Controller::Impl::ProcessInputEvents()
   if( mEventData->mUpdateCursorPosition ||
       mEventData->mUpdateHighlightBox )
   {
-    NotifyImfManager();
+    NotifyInputMethodContext();
   }
 
   // The cursor must also be repositioned after inserts into the model
@@ -328,9 +329,9 @@ bool Controller::Impl::ProcessInputEvents()
   return decoratorUpdated;
 }
 
-void Controller::Impl::NotifyImfManager()
+void Controller::Impl::NotifyInputMethodContext()
 {
-  if( mEventData && mEventData->mImfManager )
+  if( mEventData && mEventData->mInputMethodContext )
   {
     CharacterIndex cursorPosition = GetLogicalCursorPosition();
 
@@ -346,17 +347,17 @@ void Controller::Impl::NotifyImfManager()
       cursorPosition -= numberOfWhiteSpaces;
     }
 
-    mEventData->mImfManager.SetCursorPosition( cursorPosition );
-    mEventData->mImfManager.NotifyCursorPosition();
+    mEventData->mInputMethodContext.SetCursorPosition( cursorPosition );
+    mEventData->mInputMethodContext.NotifyCursorPosition();
   }
 }
 
-void Controller::Impl::NotifyImfMultiLineStatus()
+void Controller::Impl::NotifyInputMethodContextMultiLineStatus()
 {
-  if ( mEventData )
+  if ( mEventData && mEventData->mInputMethodContext )
   {
     Text::Layout::Engine::Type layout = mLayoutEngine.GetLayout();
-    mEventData->mImfManager.NotifyTextInputMultiLine( layout == Text::Layout::Engine::MULTI_LINE_BOX );
+    mEventData->mInputMethodContext.NotifyTextInputMultiLine( layout == Text::Layout::Engine::MULTI_LINE_BOX );
   }
 }
 
@@ -814,7 +815,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
   // Check whether the indices for updating the text is valid
   if ( numberOfCharacters > 0u &&
-       ( mTextUpdateInfo.mParagraphCharacterIndex >= numberOfCharacters ||
+       ( mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
          mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters ) )
   {
     std::string currentText;
@@ -932,7 +933,15 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
       {
         // Set the normal font and the placeholder font.
         defaultFontDescription = mFontDefaults->mFontDescription;
-        defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
+
+        if( mTextFitEnabled )
+        {
+          defaultPointSize = mFontDefaults->mFitPointSize * 64u;
+        }
+        else
+        {
+          defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
+        }
       }
 
       // Validates the fonts. If there is a character with no assigned font it sets a default one.
@@ -963,7 +972,9 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                           lineBreakInfo,
                           startIndex,
                           requestedNumberOfCharacters,
-                          bidirectionalInfo );
+                          bidirectionalInfo,
+                          mModel->mMatchSystemLanguageDirection,
+                          mLayoutDirection );
 
     if( 0u != bidirectionalInfo.Count() )
     {
@@ -1061,21 +1072,35 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
       mEventData->mPreEditFlag &&
       ( 0u != mModel->mVisualModel->mCharactersToGlyph.Count() ) )
   {
-    // Add the underline for the pre-edit text.
-    const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
-    const Length* const glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
+    Dali::InputMethodContext::PreeditStyle type = mEventData->mInputMethodContext.GetPreeditStyle();
+
+    switch( type )
+    {
+      case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
+      {
+        // Add the underline for the pre-edit text.
+        const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+        const Length* const glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
 
-    const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition );
-    const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u );
-    const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter );
-    const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u );
+        const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition );
+        const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u );
+        const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter );
+        const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u );
 
-    GlyphRun underlineRun;
-    underlineRun.glyphIndex = glyphStart;
-    underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
+        GlyphRun underlineRun;
+        underlineRun.glyphIndex = glyphStart;
+        underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
 
-    // TODO: At the moment the underline runs are only for pre-edit.
-    mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
+        mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
+        break;
+      }
+      // TODO :  At this moment, other styles for preedit are not implemented yet.
+      case Dali::InputMethodContext::PreeditStyle::REVERSE:
+      case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
+      case Dali::InputMethodContext::PreeditStyle::NONE:
+      default:
+        break;
+    }
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
@@ -1319,11 +1344,11 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
 
     if ( selecting )
     {
-      // Notify the cursor position to the imf manager.
-      if( mEventData->mImfManager )
+      // Notify the cursor position to the InputMethodContext.
+      if( mEventData->mInputMethodContext )
       {
-        mEventData->mImfManager.SetCursorPosition( mEventData->mPrimaryCursorPosition );
-        mEventData->mImfManager.NotifyCursorPosition();
+        mEventData->mInputMethodContext.SetCursorPosition( mEventData->mPrimaryCursorPosition );
+        mEventData->mInputMethodContext.NotifyCursorPosition();
       }
 
       ChangeState( EventData::SELECTING );
@@ -1395,11 +1420,11 @@ void Controller::Impl::OnTapEvent( const Event& event )
       mEventData->mScrollAfterUpdatePosition = true;
       mEventData->mUpdateInputStyle = true;
 
-      // Notify the cursor position to the imf manager.
-      if( mEventData->mImfManager )
+      // Notify the cursor position to the InputMethodContext.
+      if( mEventData->mInputMethodContext )
       {
-        mEventData->mImfManager.SetCursorPosition( mEventData->mPrimaryCursorPosition );
-        mEventData->mImfManager.NotifyCursorPosition();
+        mEventData->mInputMethodContext.SetCursorPosition( mEventData->mPrimaryCursorPosition );
+        mEventData->mInputMethodContext.NotifyCursorPosition();
       }
     }
     else if( 2u == tapCount )
@@ -1845,15 +1870,13 @@ void Controller::Impl::OnSelectAllEvent()
 
   if( mEventData->mSelectionEnabled )
   {
-    ChangeState( EventData::SELECTING );
+    // Calculates the logical position from the start.
+    RepositionSelectionHandles( 0.f - mModel->mScrollPosition.x,
+                                0.f - mModel->mScrollPosition.y,
+                                Controller::NoTextTap::HIGHLIGHT );
 
     mEventData->mLeftSelectionPosition = 0u;
     mEventData->mRightSelectionPosition = mModel->mLogicalModel->mText.Count();
-
-    mEventData->mScrollAfterUpdatePosition = true;
-    mEventData->mUpdateLeftSelectionPosition = true;
-    mEventData->mUpdateRightSelectionPosition = true;
-    mEventData->mUpdateHighlightBox = true;
   }
 }
 
@@ -2417,8 +2440,8 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY,
     mEventData->mUpdateRightSelectionPosition = true;
     mEventData->mUpdateHighlightBox = true;
 
-    // It may happen an IMF commit event arrives before the selection event
-    // if the IMF manager is in pre-edit state. The commit event will set the
+    // It may happen an InputMethodContext commit event arrives before the selection event
+    // if the InputMethodContext is in pre-edit state. The commit event will set the
     // mEventData->mUpdateCursorPosition flag to true. If it's not set back
     // to false, the highlight box won't be updated.
     mEventData->mUpdateCursorPosition = false;
@@ -2739,11 +2762,24 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
+    bool isRTL = false;
+    if( mModel->mMatchSystemLanguageDirection )
+    {
+      isRTL = mLayoutDirection == LayoutDirection::RIGHT_TO_LEFT;
+    }
+
     switch( mModel->mHorizontalAlignment )
     {
       case Text::HorizontalAlignment::BEGIN :
       {
-        cursorInfo.primaryPosition.x = 0.f;
+        if( isRTL )
+        {
+          cursorInfo.primaryPosition.x = mModel->mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
+        }
+        else
+        {
+          cursorInfo.primaryPosition.x = 0.f;
+        }
         break;
       }
       case Text::HorizontalAlignment::CENTER:
@@ -2753,7 +2789,14 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
       }
       case Text::HorizontalAlignment::END:
       {
-        cursorInfo.primaryPosition.x = mModel->mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
+        if( isRTL )
+        {
+          cursorInfo.primaryPosition.x = 0.f;
+        }
+        else
+        {
+          cursorInfo.primaryPosition.x = mModel->mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
+        }
         break;
       }
     }