From 0ba117cfd9c4a0b6f379c74dde8bac4233097ffe Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Mon, 13 Feb 2017 09:27:19 +0000 Subject: [PATCH] [3.0] Fix for cursor size and position. * 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 --- .../src/dali-toolkit/utc-Dali-TextField.cpp | 110 +++++++++++++++++++++ .../internal/text/decorator/text-decorator.cpp | 50 ++++++++-- 2 files changed, 150 insertions(+), 10 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index 40d49a7..db5fe0b 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -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, "Hello שלום עולם world" ); + + 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; +} diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 8040d74..2bc0a77 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -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 ); } -- 2.7.4