From 4806a59f8d57a12e5e6c7f91385a5f9231d0f493 Mon Sep 17 00:00:00 2001 From: Paul Wisbey Date: Fri, 21 Aug 2015 16:31:22 +0100 Subject: [PATCH] Changed the cursor behavior to match other solutions 1) When the TextField is empty, repeatedly tapping should not affect the cursor blinking 2) When entering/deleting text, the cursor should not be blinking 3) When moving the cursor position, the cursor should not be blinking Change-Id: Ib6dac81683edc7d54b3e96dbd47d7ce83c849c25 --- .../internal/text/decorator/text-decorator.cpp | 36 +++++++++++++++----- .../internal/text/decorator/text-decorator.h | 5 +++ .../internal/text/text-controller-impl.cpp | 5 ++- dali-toolkit/internal/text/text-controller.cpp | 39 +++++++++++++++++----- 4 files changed, 67 insertions(+), 18 deletions(-) diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 3e67d8c..9ec055e 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -260,6 +260,7 @@ struct Decorator::Impl : public ConnectionTracker mTextDepth( 0u ), mActiveCopyPastePopup( false ), mCursorBlinkStatus( true ), + mDelayCursorBlink( false ), mPrimaryCursorVisible( false ), mSecondaryCursorVisible( false ), mSwapSelectionHandles( false ), @@ -294,7 +295,7 @@ struct Decorator::Impl : public ConnectionTracker position.y ); mPrimaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) ); } - mPrimaryCursor.SetVisible( mPrimaryCursorVisible ); + mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); } if( mSecondaryCursor ) { @@ -306,7 +307,7 @@ struct Decorator::Impl : public ConnectionTracker cursor.position.y ); mSecondaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) ); } - mSecondaryCursor.SetVisible( mSecondaryCursorVisible ); + mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); } // Show or hide the grab handle @@ -535,18 +536,26 @@ struct Decorator::Impl : public ConnectionTracker bool OnCursorBlinkTimerTick() { - // Cursor blinking - if ( mPrimaryCursor ) + if( !mDelayCursorBlink ) { - mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); + // Cursor blinking + if ( mPrimaryCursor ) + { + mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); + } + if ( mSecondaryCursor ) + { + mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); + } + + mCursorBlinkStatus = !mCursorBlinkStatus; } - if ( mSecondaryCursor ) + else { - mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); + // Resume blinking + mDelayCursorBlink = false; } - mCursorBlinkStatus = !mCursorBlinkStatus; - return true; } @@ -1312,6 +1321,7 @@ struct Decorator::Impl : public ConnectionTracker bool mActiveCopyPastePopup : 1; bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off. + bool mDelayCursorBlink : 1; ///< Used to avoid cursor blinking when entering text. bool mPrimaryCursorVisible : 1; ///< Whether the primary cursor is visible. bool mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible. bool mSwapSelectionHandles : 1; ///< Whether to swap the selection handle images. @@ -1408,6 +1418,14 @@ void Decorator::StopCursorBlink() { mImpl->mCursorBlinkTimer.Stop(); } + + mImpl->mCursorBlinkStatus = true; // Keep cursor permanently shown +} + +void Decorator::DelayCursorBlink() +{ + mImpl->mCursorBlinkStatus = true; // Show cursor for a bit longer + mImpl->mDelayCursorBlink = true; } void Decorator::SetCursorBlinkInterval( float seconds ) diff --git a/dali-toolkit/internal/text/decorator/text-decorator.h b/dali-toolkit/internal/text/decorator/text-decorator.h index ae90e90..1587703 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.h +++ b/dali-toolkit/internal/text/decorator/text-decorator.h @@ -270,6 +270,11 @@ public: void StopCursorBlink(); /** + * @brief Temporarily stops the cursor from blinking. + */ + void DelayCursorBlink(); + + /** * @brief Set the interval between cursor blinks. * * @param[in] seconds The interval in seconds. diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index ef5ceef..5e64f87 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -537,13 +537,16 @@ void Controller::Impl::OnTapEvent( const Event& event ) if( 1u == tapCount ) { - if( ! IsShowingPlaceholderText() ) + if( IsShowingRealText() ) { const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x; const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y; mEventData->mPrimaryCursorPosition = GetClosestCursorIndex( xPosition, yPosition ); + + // When the cursor position is changing, delay cursor blinking + mEventData->mDecorator->DelayCursorBlink(); } else { diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index bce657c..58a8217 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -681,6 +681,13 @@ void Controller::ProcessModifyEvents() } } + if( mImpl->mEventData && + 0 != events.size() ) + { + // When the text is being modified, delay cursor blinking + mImpl->mEventData->mDecorator->DelayCursorBlink(); + } + // Discard temporary text events.clear(); } @@ -1374,24 +1381,40 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y ) { if( 1u == tapCount ) { + // This is to avoid unnecessary relayouts when tapping an empty text-field + bool relayoutNeeded( false ); + if( mImpl->IsShowingRealText() && EventData::EDITING == mImpl->mEventData->mState ) { + // Show grab handle on second tap mImpl->ChangeState( EventData::EDITING_WITH_GRAB_HANDLE ); + relayoutNeeded = true; } - else if( EventData::EDITING_WITH_GRAB_HANDLE != mImpl->mEventData->mState ) + else if( EventData::EDITING != mImpl->mEventData->mState && + EventData::EDITING_WITH_GRAB_HANDLE != mImpl->mEventData->mState ) { - // Handles & cursors must be repositioned after Relayout() i.e. after the Model has been updated + // Show cursor on first tap mImpl->ChangeState( EventData::EDITING ); + relayoutNeeded = true; + } + else if( mImpl->IsShowingRealText() ) + { + // Move the cursor + relayoutNeeded = true; } - Event event( Event::TAP_EVENT ); - event.p1.mUint = tapCount; - event.p2.mFloat = x; - event.p3.mFloat = y; - mImpl->mEventData->mEventQueue.push_back( event ); + // Handles & cursors must be repositioned after Relayout() i.e. after the Model has been updated + if( relayoutNeeded ) + { + Event event( Event::TAP_EVENT ); + event.p1.mUint = tapCount; + event.p2.mFloat = x; + event.p3.mFloat = y; + mImpl->mEventData->mEventQueue.push_back( event ); - mImpl->RequestRelayout(); + mImpl->RequestRelayout(); + } } else if( 2u == tapCount ) { -- 2.7.4