[3.0] Fix for cursor size and position. 06/114506/2
authorVictor Cebollada <v.cebollada@samsung.com>
Mon, 13 Feb 2017 09:27:19 +0000 (09:27 +0000)
committerPaul Wisbey <p.wisbey@samsung.com>
Mon, 13 Feb 2017 18:48:32 +0000 (10:48 -0800)
* If the cursor is bigger than the height of the text control it's
  set as not visible.
* The patch updates the size and position of the cursor to make
  a portion of it visible.

Change-Id: I5cb258325d8692d8248e32efe42367c5c9d19e1f
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/text/decorator/text-decorator.cpp

index 40d49a7..db5fe0b 100644 (file)
@@ -1865,3 +1865,113 @@ int utcDaliTextFieldStyleWhilstSelected(void)
 
   END_TEST;
 }
+
+int utcDaliTextFieldCursorVisibility(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldCursorVisibility");
+
+  // Load a font.
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" );
+
+  // Checks if the right number of actors are created.
+
+  TextField field = TextField::New();
+  field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
+  DALI_TEST_CHECK( field );
+
+  field.SetProperty( TextField::Property::ENABLE_MARKUP, true );
+  field.SetProperty( TextField::Property::TEXT, "<font family='TizenSans' size='18'>Hello <font family='TizenSansHebrew' size='18'>שלום עולם</font> world</font>" );
+
+  Stage::GetCurrent().Add( field );
+
+  field.SetSize( 300.f, 30.f );
+  field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Check there are the expected number of children ( stencil ).
+  DALI_TEST_EQUALS( field.GetChildCount(), 1u, TEST_LOCATION );
+
+  Actor stencil = field.GetChildAt( 0u );
+  DALI_TEST_EQUALS( stencil.GetChildCount(), 1u, TEST_LOCATION ); // The text renderer.
+
+  // Create a tap event to touch the text field.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 56.0f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 56.0f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Actor layer = field.GetChildAt( 1u );
+  DALI_TEST_CHECK( layer.IsLayer() );
+
+  DALI_TEST_EQUALS( layer.GetChildCount(), 2u, TEST_LOCATION ); // The two cursors.
+  DALI_TEST_EQUALS( stencil.GetChildCount(), 1u, TEST_LOCATION ); // The text renderer.
+
+  Control cursor = Control::DownCast( layer.GetChildAt( 0u ) );
+  DALI_TEST_CHECK( cursor );
+
+  Vector3 size = cursor.GetCurrentSize();
+  Vector3 position = cursor.GetCurrentPosition();
+
+  DALI_TEST_EQUALS( position, Vector3(56.f, 0.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( size, Vector3(1.f, 14.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Change the size of the control (with a height smaller than the size of the cursor).
+  field.SetSize( 300.f, 20.f );
+
+  // Create a tap event to touch the text field.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 56.0f, 15.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 56.0f, 15.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  size = cursor.GetCurrentSize();
+  position = cursor.GetCurrentPosition();
+
+  // Checks the size of the cursor fits the control's height.
+  DALI_TEST_EQUALS( position, Vector3(56.f, 0.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( size, Vector3(1.f, 5.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Change the size of the control (with a height smaller than the size of the secondary cursor).
+  field.SetSize( 300.f, 10.f );
+
+  // Create a tap event to touch the text field.
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 56.0f, 5.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 56.0f, 5.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Control cursor2 = Control::DownCast( layer.GetChildAt( 1u ) );
+  DALI_TEST_CHECK( cursor2 );
+
+  size = cursor2.GetCurrentSize();
+  position = cursor2.GetCurrentPosition();
+
+  // Checks the size of the cursor fits the control's height.
+  DALI_TEST_EQUALS( position, Vector3(155.f, 0.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( size, Vector3(1.f, 10.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  END_TEST;
+}
index 8040d74..2bc0a77 100644 (file)
@@ -285,30 +285,60 @@ struct Decorator::Impl : public ConnectionTracker
     if( mPrimaryCursor )
     {
       const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
+      const float cursorBottom = cursor.position.y + cursor.cursorHeight;
+
       mPrimaryCursorVisible = ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) &&
                                 ( cursor.position.x > -Math::MACHINE_EPSILON_1000 ) &&
-                                ( mControlSize.height - ( cursor.position.y + cursor.cursorHeight ) > -Math::MACHINE_EPSILON_1000 ) &&
-                                ( cursor.position.y > -Math::MACHINE_EPSILON_1000 ) );
+                                ( cursor.position.y < mControlSize.height ) &&
+                                ( cursorBottom > -Math::MACHINE_EPSILON_1000 ) );
+
       if( mPrimaryCursorVisible )
       {
-        mPrimaryCursor.SetPosition( cursor.position.x,
-                                    cursor.position.y );
-        mPrimaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) );
+        Size size( mCursorWidth, cursor.cursorHeight );
+        Vector2 position( cursor.position.x, cursor.position.y );
+        if( cursor.position.y < Math::MACHINE_EPSILON_1000 )
+        {
+          size.height += cursor.position.y;
+          position.y = 0.f;
+        }
+        if( cursorBottom > mControlSize.height )
+        {
+          size.height -= ( cursorBottom - mControlSize.height );
+        }
+
+        mPrimaryCursor.SetPosition( position.x, position.y );
+
+        mPrimaryCursor.SetSize( size );
       }
       mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus );
     }
+
     if( mSecondaryCursor )
     {
       const CursorImpl& cursor = mCursor[SECONDARY_CURSOR];
+      const float cursorBottom = cursor.position.y + cursor.cursorHeight;
+
       mSecondaryCursorVisible = ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) &&
                                   ( cursor.position.x > -Math::MACHINE_EPSILON_1000 ) &&
-                                  ( mControlSize.height - ( cursor.position.y + cursor.cursorHeight ) > -Math::MACHINE_EPSILON_1000 ) &&
-                                  ( cursor.position.y > -Math::MACHINE_EPSILON_1000 ) );
+                                  ( cursor.position.y < mControlSize.height ) &&
+                                  ( cursorBottom > -Math::MACHINE_EPSILON_1000 ) );
+
       if( mSecondaryCursorVisible )
       {
-        mSecondaryCursor.SetPosition( cursor.position.x,
-                                      cursor.position.y );
-        mSecondaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) );
+        Size size( mCursorWidth, cursor.cursorHeight );
+        Vector2 position( cursor.position.x, cursor.position.y );
+        if( cursor.position.y < Math::MACHINE_EPSILON_1000 )
+        {
+          size.height += cursor.position.y;
+          position.y = 0.f;
+        }
+        if( cursorBottom > mControlSize.height )
+        {
+          size.height -= ( cursorBottom - mControlSize.height );
+        }
+
+        mSecondaryCursor.SetPosition( position.x, position.y );
+        mSecondaryCursor.SetSize( size );
       }
       mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus );
     }