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