From f6c466b8b87ca95014ce563d1a5b905cd82c8d6f Mon Sep 17 00:00:00 2001 From: Paul Wisbey Date: Thu, 4 Jun 2015 11:57:59 +0100 Subject: [PATCH] Added TextChanged signal to TextField Change-Id: I7e0560b289d321db65d3a71de273b407c2f1f0f5 --- .../src/dali-toolkit/utc-Dali-TextField.cpp | 64 +++++++++++++++++++++- .../controls/text-controls/text-field-impl.cpp | 18 +++++- .../controls/text-controls/text-field-impl.h | 11 ++++ .../controls/text-controls/text-label-impl.cpp | 5 ++ .../controls/text-controls/text-label-impl.h | 5 ++ .../internal/text/text-control-interface.h | 5 ++ dali-toolkit/internal/text/text-controller-impl.h | 6 ++ dali-toolkit/internal/text/text-controller.cpp | 29 +++++++--- .../controls/text-controls/text-field.cpp | 5 ++ .../public-api/controls/text-controls/text-field.h | 13 +++++ 10 files changed, 151 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 a8be49e..d19b3a1 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -55,11 +55,19 @@ const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decoration-bounding-b const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT = "horizontal-alignment"; const char* const PROPERTY_NAME_VERTICAL_ALIGNMENT = "vertical-alignment"; +static bool gTextChangedCallBackCalled; static bool gMaxCharactersCallBackCalled; +static void TestTextChangedCallback( TextField control ) +{ + tet_infoline(" TestTextChangedCallback"); + + gTextChangedCallBackCalled = true; +} + static void TestMaxLengthReachedCallback( TextField control ) { - tet_infoline(" TestMaxLengthReachedCallbackCallback"); + tet_infoline(" TestMaxLengthReachedCallback"); gMaxCharactersCallBackCalled = true; } @@ -332,6 +340,60 @@ int utcDaliTextFieldAtlasRenderP(void) END_TEST; } +// Positive test for the text-changed signal. +int utcDaliTextFieldTextChangedP(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextFieldTextChangedP"); + TextField field = TextField::New(); + DALI_TEST_CHECK( field ); + + Stage::GetCurrent().Add(field); + + field.TextChangedSignal().Connect(&TestTextChangedCallback); + + gTextChangedCallBackCalled = false; + field.SetProperty( TextField::Property::TEXT, "ABC" ); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + + application.SendNotification(); + + field.SetKeyInputFocus(); + + Dali::Integration::KeyEvent keyevent; + keyevent.keyName = "D"; + keyevent.keyString = "D"; + keyevent.keyCode = 0; + keyevent.keyModifier = 0; + keyevent.time = 0; + keyevent.state = Integration::KeyEvent::Down; + + gTextChangedCallBackCalled = false; + application.ProcessEvent( keyevent ); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + + END_TEST; +} + +// Negative test for the text-changed signal. +int utcDaliTextFieldTextChangedN(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextFieldTextChangedN"); + TextField field = TextField::New(); + DALI_TEST_CHECK( field ); + + Stage::GetCurrent().Add(field); + + field.TextChangedSignal().Connect(&TestTextChangedCallback); + + gTextChangedCallBackCalled = false; + field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT + DALI_TEST_CHECK( ! gTextChangedCallBackCalled ); + + END_TEST; +} + // Positive test for Max Characters reached signal. int utcDaliTextFieldMaxCharactersReachedP(void) { diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 11ec5c2..753d347 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -119,6 +119,7 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-highlight-color", DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decoration-bounding-box", RECTANGLE, DECORATION_BOUNDING_BOX ) DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "input-method-settings", MAP, INPUT_METHOD_SETTINGS ) +DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "text-changed", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "max-length-reached", SIGNAL_MAX_LENGTH_REACHED ) DALI_TYPE_REGISTRATION_END() @@ -825,7 +826,11 @@ bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* bool connected( true ); Toolkit::TextField field = Toolkit::TextField::DownCast( handle ); - if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) ) + if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) ) + { + field.TextChangedSignal().Connect( tracker, functor ); + } + else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) ) { field.MaxLengthReachedSignal().Connect( tracker, functor ); } @@ -838,6 +843,11 @@ bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* return connected; } +Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal() +{ + return mTextChangedSignal; +} + Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal() { return mMaxLengthReachedSignal; @@ -1032,6 +1042,12 @@ void TextField::RequestTextRelayout() RelayoutRequest(); } +void TextField::TextChanged() +{ + Dali::Toolkit::TextField handle( GetOwner() ); + mTextChangedSignal.Emit( handle ); +} + void TextField::MaxLengthReached() { Dali::Toolkit::TextField handle( GetOwner() ); diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index 5e0df24..85b88e2 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -80,6 +80,11 @@ public: static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ); /** + * @copydoc TextField::TextChangedSignal() + */ + Toolkit::TextField::TextChangedSignalType& TextChangedSignal(); + + /** * @copydoc TextField::MaxLengthReachedSignal() */ Toolkit::TextField::MaxLengthReachedSignalType& MaxLengthReachedSignal(); @@ -147,6 +152,11 @@ private: // From Control virtual void RequestTextRelayout(); /** + * @copydoc Text::ControlInterface::TextChanged() + */ + virtual void TextChanged(); + + /** * @copydoc Text::ControlInterface::MaxLengthReached() */ virtual void MaxLengthReached(); @@ -193,6 +203,7 @@ private: // Implementation private: // Data // Signals + Toolkit::TextField::TextChangedSignalType mTextChangedSignal; Toolkit::TextField::MaxLengthReachedSignalType mMaxLengthReachedSignal; Text::ControllerPtr mController; diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 35761df..004609f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -494,6 +494,11 @@ void TextLabel::RequestTextRelayout() RelayoutRequest(); } +void TextLabel::TextChanged() +{ + // TextLabel does not provide a signal for this +} + void TextLabel::MaxLengthReached() { // Pure Virtual from TextController Interface, only needed when inputting text diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/dali-toolkit/internal/controls/text-controls/text-label-impl.h index 3e0fd35..54b30dd 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -98,6 +98,11 @@ private: // From Control virtual void RequestTextRelayout(); /** + * @copydoc Text::ControlInterface::TextChanged() + */ + virtual void TextChanged(); + + /** * @copydoc Text::ControlInterface::MaxLengthReached() */ virtual void MaxLengthReached(); diff --git a/dali-toolkit/internal/text/text-control-interface.h b/dali-toolkit/internal/text/text-control-interface.h index d7ed8f4..e485be9 100644 --- a/dali-toolkit/internal/text/text-control-interface.h +++ b/dali-toolkit/internal/text/text-control-interface.h @@ -50,6 +50,11 @@ public: virtual void RequestTextRelayout() = 0; /** + * @brief Called to signal that text has been inserted or deleted. + */ + virtual void TextChanged() = 0; + + /** * @brief Called when the number of characters to be inserted exceeds the maximum limit */ virtual void MaxLengthReached() = 0; diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 3020e67..ab2764c 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -231,6 +231,12 @@ struct Controller::Impl */ void QueueModifyEvent( ModifyEvent::Type type ) { + if( ModifyEvent::TEXT_REPLACED == type) + { + // Cancel previously queued inserts etc. + mModifyEvents.clear(); + } + ModifyEvent event; event.type = type; mModifyEvents.push_back( event ); diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index e07e29c..889ca68 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -73,9 +73,6 @@ void Controller::EnableTextInput( DecoratorPtr decorator ) void Controller::SetText( const std::string& text ) { - // Cancel previously queued inserts etc. - mImpl->mModifyEvents.clear(); - // Remove the previously set text ResetText(); @@ -126,6 +123,9 @@ void Controller::SetText( const std::string& text ) // Reset keyboard as text changed mImpl->ResetImfManager(); + + // Do this last since it provides callbacks into application code + mImpl->mControlInterface.TextChanged(); } void Controller::GetText( std::string& text ) const @@ -1089,6 +1089,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) { DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected KeyEvent" ); + bool textChanged( false ); + if( mImpl->mEventData && keyEvent.state == KeyEvent::Down ) { @@ -1131,6 +1133,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) { mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED ); } + + textChanged = true; } } else @@ -1141,6 +1145,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) mImpl->ClearPreEditFlag(); InsertText( keyString, COMMIT ); + + textChanged = true; } mImpl->ChangeState( EventData::EDITING ); // todo Confirm this is the best place to change the state of @@ -1148,6 +1154,12 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) mImpl->RequestRelayout(); } + if( textChanged ) + { + // Do this last since it provides callbacks into application code + mImpl->mControlInterface.TextChanged(); + } + return false; } @@ -1261,9 +1273,10 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", mImpl->mLogicalModel->mText.Count() ); - mImpl->mControlInterface.MaxLengthReached(); - mImpl->ResetImfManager(); + + // Do this last since it provides callbacks into application code + mImpl->mControlInterface.MaxLengthReached(); } } @@ -1432,6 +1445,9 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons { mImpl->mOperationsPending = ALL_OPERATIONS; mImpl->RequestRelayout(); + + // Do this last since it provides callbacks into application code + mImpl->mControlInterface.TextChanged(); } ImfManager::ImfCallbackData callbackData( update, cursorPosition, text, false ); @@ -1453,9 +1469,6 @@ void Controller::ShowPlaceholderText() mImpl->mEventData->mIsShowingPlaceholderText = true; - // Cancel previously queued inserts etc. - mImpl->mModifyEvents.clear(); - // Disable handles when showing place-holder text mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false ); mImpl->mEventData->mDecorator->SetHandleActive( LEFT_SELECTION_HANDLE, false ); diff --git a/dali-toolkit/public-api/controls/text-controls/text-field.cpp b/dali-toolkit/public-api/controls/text-controls/text-field.cpp index 5340137..3a833f3 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-field.cpp +++ b/dali-toolkit/public-api/controls/text-controls/text-field.cpp @@ -59,6 +59,11 @@ TextField TextField::DownCast( BaseHandle handle ) return Control::DownCast(handle); } +TextField::TextChangedSignalType& TextField::TextChangedSignal() +{ + return Dali::Toolkit::GetImpl( *this ).TextChangedSignal(); +} + TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal() { return Dali::Toolkit::GetImpl( *this ).MaxLengthReachedSignal(); diff --git a/dali-toolkit/public-api/controls/text-controls/text-field.h b/dali-toolkit/public-api/controls/text-controls/text-field.h index 1f6df9b..4f3da41 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-field.h +++ b/dali-toolkit/public-api/controls/text-controls/text-field.h @@ -38,6 +38,7 @@ class TextField; * * Signals * | %Signal Name | Method | * |------------------------|-----------------------------------------------------| + * | text-changed | @ref TextChangedSignal() | * | max-length-reached | @ref MaxLengthReachedSignal() | * */ @@ -109,6 +110,7 @@ public: // Type Defs /// @brief Max Characters Exceed signal type; + typedef Signal TextChangedSignalType; typedef Signal MaxLengthReachedSignalType; /** @@ -158,6 +160,17 @@ public: // Signals /** + * @brief This signal is emitted when the text changes. + * + * A callback of the following type may be connected: + * @code + * void YourCallbackName( TextField textField ); + * @endcode + * @return The signal to connect to. + */ + TextChangedSignalType& TextChangedSignal(); + + /** * @brief This signal is emitted when inserted text exceeds the maximum character limit. * * A callback of the following type may be connected: -- 2.7.4