Merge "TextField is re-laied out after its properties are changed." into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Mon, 11 Mar 2019 10:35:32 +0000 (10:35 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 11 Mar 2019 10:35:32 +0000 (10:35 +0000)
1  2 
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
dali-toolkit/internal/text/text-controller.cpp

@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 + * Copyright (c) 2019 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.
@@@ -49,6 -49,22 +49,22 @@@ void ContentSelectedCallback( Clipboard
    gClipboardText = notifier.GetContent();
  }
  
+ // Generate a KeyEvent to send to Core.
+ Dali::KeyEvent GenerateKey( const std::string& keyName,
+                             const std::string& keyString,
+                             int keyCode,
+                             int keyModifier,
+                             unsigned long timeStamp,
+                             const Dali::KeyEvent::State& keyState )
+ {
+   return Dali::KeyEvent( keyName,
+                          keyString,
+                          keyCode,
+                          keyModifier,
+                          timeStamp,
+                          keyState );
+ }
  } // namespace
  
  int UtcDaliTextController(void)
@@@ -558,8 -574,8 +574,8 @@@ int UtcDaliTextControllerSetGetLineSpac
    // single line, line spacing = 0px
    {
      const float EXPECTED_SPACING = 0.0f;
 -    const Vector2 EXPECTED_LAYOUT_SIZE( 326.0f, 19.0f);
 -    const Vector3 EXPECTED_NATURAL_SIZE( 326.0f, 20.0f, 0.0f );
 +    const Vector2 EXPECTED_LAYOUT_SIZE( 343.0f, 19.0f);
 +    const Vector3 EXPECTED_NATURAL_SIZE( 344.0f, 20.0f, 0.0f );
  
      controller->SetText(textSingle);
      controller->Relayout(size);
    // single line, line spacing = 20px
    {
      const float EXPECTED_SPACING = 20.0f;
 -    const Vector2 EXPECTED_LAYOUT_SIZE( 326.0f, 19.0f );
 -    const Vector3 EXPECTED_NATURAL_SIZE( 326.0f, 40.0f, 0.0f );
 +    const Vector2 EXPECTED_LAYOUT_SIZE( 343.0f, 19.0f );
 +    const Vector3 EXPECTED_NATURAL_SIZE( 344.0f, 40.0f, 0.0f );
  
      controller->SetText(textSingle);
      controller->Relayout(size);
    // multi-line, line spacing = 0px
    {
      const float EXPECTED_SPACING = 0.0f;
 -    const Vector2 EXPECTED_LAYOUT_SIZE( 318.0f, 39.0f );
 -    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 58.0f, 0.0f );
 +    const Vector2 EXPECTED_LAYOUT_SIZE( 333.0f, 39.0f );
 +    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 58.0f, 0.0f );
  
      controller->SetText(textMulti);
      controller->Relayout(size);
    // multi-line, line spacing = 20px
    {
      const float EXPECTED_SPACING = 20.0f;
 -    const Vector2 EXPECTED_LAYOUT_SIZE( 115.0f, 57.0f );
 -    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 118.0f, 0.0f );
 +    const Vector2 EXPECTED_LAYOUT_SIZE( 119.0f, 57.0f );
 +    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 118.0f, 0.0f );
  
      controller->SetText(textMulti);
      controller->Relayout(size);
    // multi-line, line spacing = 30px
    {
      const float EXPECTED_SPACING = 30.0f;
 -    const Vector2 EXPECTED_LAYOUT_SIZE( 115.0f, 117.0f );
 -    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 148.0f, 0.0f );
 +    const Vector2 EXPECTED_LAYOUT_SIZE( 119.0f, 117.0f );
 +    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 148.0f, 0.0f );
  
      controller->SetText(textMulti);
      controller->Relayout(size);
@@@ -690,3 -706,299 +706,299 @@@ int UtcDaliTextControllerCheckBufferInd
  
    END_TEST;
  }
+ int UtcDaliTextControllerCheckInputColorChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputColorChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   const Vector4 inputColor( 0.0f, 0.0f, 0.0f, 1.0f );
+   controller->SetInputColor( inputColor );
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   //  Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input color
+   const Vector4 newInputColor( 1.0f, 0.0f, 0.0f, 1.0f );
+   controller->SetInputColor( newInputColor );
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::COLOR, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::COLOR ), TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
+ int UtcDaliTextControllerCheckInputFontFamilyChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputFontFamilyChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text and font family
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   controller->SetInputFontFamily("SamsungOneUI_200");
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   //  Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input font family
+   controller->SetInputFontFamily("SamsungOneUI_300");
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::VALIDATE_FONTS, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::VALIDATE_FONTS ),
+                     TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
+ int UtcDaliTextControllerCheckInputFontWeightChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputFontWeightChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   controller->SetInputFontWeight( TextAbstraction::FontWeight::NORMAL );
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   // Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input font weight
+   controller->SetInputFontWeight( TextAbstraction::FontWeight::BOLD );
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::VALIDATE_FONTS, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::VALIDATE_FONTS ),
+                     TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
+ int UtcDaliTextControllerCheckInputFontWidthChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputFontWidthChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   controller->SetInputFontWidth( TextAbstraction::FontWidth::NORMAL );
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   // Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input font width
+   controller->SetInputFontWidth( TextAbstraction::FontWidth::EXPANDED );
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::VALIDATE_FONTS, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::VALIDATE_FONTS ),
+                     TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
+ int UtcDaliTextControllerCheckInputFontSlantChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputFontSlantChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   controller->SetInputFontSlant( TextAbstraction::FontSlant::NORMAL );
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   //  Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input font slant
+   controller->SetInputFontSlant( TextAbstraction::FontSlant::ROMAN );
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::VALIDATE_FONTS, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::VALIDATE_FONTS ),
+                     TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
+ int UtcDaliTextControllerCheckInputFontPointSizeChanged(void)
+ {
+   tet_infoline(" UtcDaliTextControllerCheckInputFontPointSizeChanged");
+   ToolkitTestApplication application;
+   // Creates a text controller.
+   ControllerPtr controller = Controller::New();
+   ConfigureTextLabel(controller);
+   // Enable the text input.
+   // Creates a decorator.
+   Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                        *controller );
+   InputMethodContext inputMethodContext = InputMethodContext::New();
+   // Enables the text input.
+   controller->EnableTextInput( decorator, inputMethodContext );
+   // Set the text
+   const std::string text("Hello World!");
+   controller->SetText(text);
+   controller->SetInputFontPointSize( 1.0f );
+   // Get the implementation of the text controller
+   Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+   //  Reset operation
+   mImpl.mOperationsPending = Controller::NO_OPERATION;
+   // simulate a key event.
+   controller->KeyEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Dali::KeyEvent::Down ) );
+   // change the input font point size
+   controller->SetInputFontPointSize( 1.2f );
+   // Check if relayout is requested or not when event state is INACTIVE.
+   DALI_TEST_EQUALS( EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION );
+   DALI_TEST_EQUALS( Controller::VALIDATE_FONTS, static_cast<Controller::OperationsMask>( mImpl.mOperationsPending & Controller::VALIDATE_FONTS ),
+                     TEST_LOCATION );
+   // Perform a relayout
+   const Size size( Dali::Stage::GetCurrent().GetSize() );
+   controller->Relayout(size);
+   tet_result(TET_PASS);
+   END_TEST;
+ }
@@@ -65,7 -65,7 +65,7 @@@ const char * const PLACEHOLDER_ELLIPSI
  float ConvertToEven( float value )
  {
    int intValue(static_cast<int>( value ));
 -  return static_cast<float>(intValue % 2 == 0) ? intValue : (intValue + 1);
 +  return static_cast<float>( intValue + ( intValue & 1 ) );
  }
  
  } // namespace
@@@ -556,8 -556,7 +556,8 @@@ void Controller::SetText( const std::st
      mImpl->mModel->mVisualModel->SetTextColor( mImpl->mTextColor );
  
      MarkupProcessData markupProcessData( mImpl->mModel->mLogicalModel->mColorRuns,
 -                                         mImpl->mModel->mLogicalModel->mFontDescriptionRuns );
 +                                         mImpl->mModel->mLogicalModel->mFontDescriptionRuns,
 +                                         mImpl->mModel->mLogicalModel->mEmbeddedItems );
  
      Length textSize = 0u;
      const uint8_t* utf8 = NULL;
@@@ -1242,14 -1241,14 +1242,14 @@@ const Vector4& Controller::GetOutlineCo
    return mImpl->mModel->mVisualModel->GetOutlineColor();
  }
  
 -void Controller::SetOutlineWidth( unsigned int width )
 +void Controller::SetOutlineWidth( uint16_t width )
  {
    mImpl->mModel->mVisualModel->SetOutlineWidth( width );
  
    mImpl->RequestRelayout();
  }
  
 -unsigned int Controller::GetOutlineWidth() const
 +uint16_t Controller::GetOutlineWidth() const
  {
    return mImpl->mModel->mVisualModel->GetOutlineWidth();
  }
@@@ -1341,7 -1340,7 +1341,7 @@@ void Controller::SetInputColor( const V
      mImpl->mEventData->mInputStyle.textColor = color;
      mImpl->mEventData->mInputStyle.isDefaultColor = false;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
  
@@@ -1388,7 -1387,7 +1388,7 @@@ void Controller::SetInputFontFamily( co
      mImpl->mEventData->mInputStyle.familyName = fontFamily;
      mImpl->mEventData->mInputStyle.isFamilyDefined = true;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        CharacterIndex startOfSelectedText = 0u;
        Length lengthOfSelectedText = 0u;
@@@ -1447,7 -1446,7 +1447,7 @@@ void Controller::SetInputFontWeight( Fo
      mImpl->mEventData->mInputStyle.weight = weight;
      mImpl->mEventData->mInputStyle.isWeightDefined = true;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        CharacterIndex startOfSelectedText = 0u;
        Length lengthOfSelectedText = 0u;
@@@ -1513,7 -1512,7 +1513,7 @@@ void Controller::SetInputFontWidth( Fon
      mImpl->mEventData->mInputStyle.width = width;
      mImpl->mEventData->mInputStyle.isWidthDefined = true;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        CharacterIndex startOfSelectedText = 0u;
        Length lengthOfSelectedText = 0u;
@@@ -1579,7 -1578,7 +1579,7 @@@ void Controller::SetInputFontSlant( Fon
      mImpl->mEventData->mInputStyle.slant = slant;
      mImpl->mEventData->mInputStyle.isSlantDefined = true;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        CharacterIndex startOfSelectedText = 0u;
        Length lengthOfSelectedText = 0u;
@@@ -1645,7 -1644,7 +1645,7 @@@ void Controller::SetInputFontPointSize
      mImpl->mEventData->mInputStyle.size = size;
      mImpl->mEventData->mInputStyle.isSizeDefined = true;
  
-     if( EventData::SELECTING == mImpl->mEventData->mState )
+     if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState )
      {
        CharacterIndex startOfSelectedText = 0u;
        Length lengthOfSelectedText = 0u;
@@@ -2626,19 -2625,14 +2626,19 @@@ bool Controller::KeyEvent( const Dali::
      {
        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() );
  
 -      // InputMethodContext is no longer handling key-events
 -      mImpl->ClearPreEditFlag();
 +      if( !keyString.empty() )
 +      {
 +        // InputMethodContext is no longer handling key-events
 +        mImpl->ClearPreEditFlag();
  
 -      InsertText( keyString, COMMIT );
 -      textChanged = true;
 +        InsertText( keyString, COMMIT );
 +
 +        textChanged = true;
 +
 +        // Will request for relayout.
 +        relayoutNeeded = true;
 +      }
  
 -      // Will request for relayout.
 -      relayoutNeeded = true;
      }
  
      if ( ( mImpl->mEventData->mState != EventData::INTERRUPTED ) &&
@@@ -3945,9 -3939,6 +3945,9 @@@ void Controller::ResetText(
    // Reset buffers.
    mImpl->mModel->mLogicalModel->mText.Clear();
  
 +  // Reset the embedded images buffer.
 +  mImpl->mModel->mLogicalModel->ClearEmbeddedImages();
 +
    // We have cleared everything including the placeholder-text
    mImpl->PlaceholderCleared();