From: Joogab Yun Date: Mon, 15 Mar 2021 10:17:04 +0000 (+0900) Subject: Unnecessary TextChanged callbacks are being called. X-Git-Tag: dali_2.0.19~14 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=33ccee79d16a90d5f7ab427de1503ccc5bee4324;ds=sidebyside Unnecessary TextChanged callbacks are being called. Change it to be called only once at the end. example) Typing "호두" on the keyboard Whenever COMMIT/PREEDIT in OnInputMethodContextEvent(), TextChanged callback is called OnTextFieldTextChanged(159) > [ㅎ] // PRE_EDIT OnTextFieldTextChanged(159) > [호] // PRE_EDIT OnTextFieldTextChanged(159) > [혿] // PRE_EDIT OnTextFieldTextChanged(159) > [] // PRE_EDIT OnTextFieldTextChanged(159) > [호] // COMMIT OnTextFieldTextChanged(159) > [호두] // PRE_EDIT If you change the text to call the TextChanged callback only once at the end of the change, OnTextFieldTextChanged(159) > [ㅎ] OnTextFieldTextChanged(159) > [호] OnTextFieldTextChanged(159) > [혿] OnTextFieldTextChanged(159) > [호두] Change-Id: I039263bc156f0be161f37eeb1d0e6ecf39f9536c --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index d5a243c..06d3307 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -964,33 +964,113 @@ int utcDaliTextEditorTextChangedP(void) gTextChangedCallBackCalled = false; editor.SetProperty( TextEditor::Property::TEXT, "ABC" ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); DALI_TEST_CHECK( textChangedSignal ); - application.SendNotification(); - editor.SetKeyInputFocus(); gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); // Remove all text editor.SetProperty( TextField::Property::TEXT, "" ); + application.SendNotification(); + application.Render(); // Pressing backspace key: TextChangedCallback should not be called when there is no text in texteditor. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); // Pressing delete key: TextChangedCallback should not be called when there is no text in texteditor. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); END_TEST; } +int utcDaliTextEditorTextChangedWithInputMethodContext(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorTextChangedWithInputMethodContext"); + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + + application.GetScene().Add( editor ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + editor.TextChangedSignal().Connect(&TestTextChangedCallback); + bool textChangedSignal = false; + editor.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) ); + + + // get InputMethodContext + std::string text; + InputMethodContext::EventData imfEvent; + InputMethodContext inputMethodContext = DevelTextEditor::GetInputMethodContext( editor ); + + editor.SetKeyInputFocus(); + editor.SetProperty( DevelTextEditor::Property::ENABLE_EDITING, true ); + + // input text + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "ㅎ", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("ㅎ"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("호"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "혿", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("혿"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::COMMIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "두", 1, 2 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("호두"), TEST_LOCATION ); + + END_TEST; +} + + int utcDaliTextEditorInputStyleChanged01(void) { // The text-editor emits signals when the input style changes. These changes of style are diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index b535059..0795816 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1034,33 +1034,113 @@ int utcDaliTextFieldTextChangedP(void) gTextChangedCallBackCalled = false; field.SetProperty( TextField::Property::TEXT, "ABC" ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); DALI_TEST_CHECK( textChangedSignal ); - application.SendNotification(); - field.SetKeyInputFocus(); gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); // Remove all text field.SetProperty( TextField::Property::TEXT, "" ); + application.SendNotification(); + application.Render(); // Pressing backspace key: TextChangedCallback should not be called when there is no text in textfield. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); // Pressing delete key: TextChangedCallback should not be called when there is no text in textfield. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + END_TEST; +} + +int utcDaliTextFieldTextChangedWithInputMethodContext(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextFieldTextChangedWithInputMethodContext"); + TextField field = TextField::New(); + DALI_TEST_CHECK( field ); + + + application.GetScene().Add( field ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + field.TextChangedSignal().Connect(&TestTextChangedCallback); + bool textChangedSignal = false; + field.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) ); + + + // get InputMethodContext + std::string text; + InputMethodContext::EventData imfEvent; + InputMethodContext inputMethodContext = DevelTextField::GetInputMethodContext( field ); + + field.SetKeyInputFocus(); + field.SetProperty( DevelTextField::Property::ENABLE_EDITING, true ); + + // input text + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "ㅎ", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("ㅎ"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("호"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "혿", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("혿"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::COMMIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "두", 1, 2 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("호두"), TEST_LOCATION ); + END_TEST; } + // Negative test for the textChanged signal. int utcDaliTextFieldTextChangedN(void) { @@ -1079,6 +1159,8 @@ int utcDaliTextFieldTextChangedN(void) gTextChangedCallBackCalled = false; field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); DALI_TEST_CHECK( !textChangedSignal ); diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index 4e7d3f0..3d48333 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -1384,7 +1384,7 @@ float TextEditor::GetHeightForWidth(float width) void TextEditor::ResizeActor(Actor& actor, const Vector2& size) { - if (actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) + if(actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) { actor.SetProperty(Actor::Property::SIZE, size); } @@ -1446,6 +1446,14 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) } RenderText(updateTextType); + + // If there is text changed, callback is called. + if(mTextChanged) + { + Dali::Toolkit::TextEditor handle(GetOwner()); + mTextChangedSignal.Emit(handle); + mTextChanged = false; + } } // The text-editor emits signals when the input style changes. These changes of style are @@ -1661,8 +1669,7 @@ void TextEditor::CaretMoved(unsigned int position) void TextEditor::TextChanged() { - Dali::Toolkit::TextEditor handle(GetOwner()); - mTextChangedSignal.Emit(handle); + mTextChanged = true; } void TextEditor::MaxLengthReached() @@ -1984,7 +1991,8 @@ TextEditor::TextEditor() mHasBeenStaged(false), mScrollAnimationEnabled(false), mScrollBarEnabled(false), - mScrollStarted(false) + mScrollStarted(false), + mTextChanged(false) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h index 866c444..4c408ca 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -362,7 +362,7 @@ private: // Implementation * @param[in] actor The actor to be resized. * @param[in] size Size to change. */ - void ResizeActor( Actor& actor, const Vector2& size ); + void ResizeActor(Actor& actor, const Vector2& size); /** * @brief Render view, create and attach actor(s) to this text editor. @@ -402,6 +402,7 @@ private: // Data bool mScrollAnimationEnabled : 1; bool mScrollBarEnabled : 1; bool mScrollStarted : 1; + bool mTextChanged : 1; struct AccessibleImpl : public DevelControl::AccessibleImpl, public virtual Dali::Accessibility::Text, 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 8b60fbe..47b32e9 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1335,7 +1335,7 @@ float TextField::GetHeightForWidth(float width) void TextField::ResizeActor(Actor& actor, const Vector2& size) { - if (actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) + if(actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) { actor.SetProperty(Actor::Property::SIZE, size); } @@ -1397,6 +1397,14 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container) } RenderText(updateTextType); + + // If there is text changed, callback is called. + if(mTextChanged) + { + Dali::Toolkit::TextField handle(GetOwner()); + mTextChangedSignal.Emit(handle); + mTextChanged = false; + } } // The text-field emits signals when the input style changes. These changes of style are @@ -1689,8 +1697,7 @@ void TextField::CaretMoved(unsigned int position) void TextField::TextChanged() { - Dali::Toolkit::TextField handle(GetOwner()); - mTextChangedSignal.Emit(handle); + mTextChanged = true; } void TextField::MaxLengthReached() @@ -1867,7 +1874,8 @@ TextField::TextField() mAlignmentOffset(0.f), mRenderingBackend(DEFAULT_RENDERING_BACKEND), mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP), - mHasBeenStaged(false) + mHasBeenStaged(false), + mTextChanged(false) { } 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 2fae0bb..07a7a37 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -318,7 +318,7 @@ private: // Implementation * @param[in] actor The actor to be resized. * @param[in] size Size to change. */ - void ResizeActor( Actor& actor, const Vector2& size ); + void ResizeActor(Actor& actor, const Vector2& size); /** * @brief Render view, create and attach actor(s) to this Text Field. @@ -357,6 +357,7 @@ private: // Data int mRenderingBackend; int mExceedPolicy; bool mHasBeenStaged : 1; + bool mTextChanged : 1; protected: struct AccessibleImpl : public DevelControl::AccessibleImpl,