Add parameter (bool immediate) to TextChanged signal in interface 75/255875/3
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 24 Mar 2021 10:17:05 +0000 (19:17 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Fri, 26 Mar 2021 08:36:15 +0000 (17:36 +0900)
virtual void TextChanged(bool immediate) = 0;
using immediate, can decide whether we only emit the signal when OnRelayout() is called next time,
otherwise emits it immediately.

* there is a issue that the timing of callback calls has been delayed
due to a recent patch that limits unnecessary callbacks.
(33ccee79d16a90d5f7ab427de1503ccc5bee4324)

Because of this, there is a problem that the TC like example below fails.
This patch can prevents the following issues.

/* example */

bool textChanged;

...

static void OnTextChanged(TextField control)
{
  textChanged = true;
}

...

field.TextChangedSignal().Connect(&OnTextChanged);
textChanged = false;
field.SetProperty(TextField::Property::TEXT, "hello");
DALI_TEST_CHECK(textChanged); // At this point, textChanged is false, so TC Fail occurs.

/* example */

Change-Id: If0a331c56f35eae931b34d128b4fe4282fc686b6
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/text/text-controller-event-handler.cpp
dali-toolkit/internal/text/text-controller-text-updater.cpp
dali-toolkit/internal/text/text-editable-control-interface.h

index b76a85060d521c6ff0fb156c9b61ca83793c9e86..af5a453b8aa8300ddfa969a792723fbbcdd20674 100644 (file)
@@ -970,36 +970,27 @@ 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;
index 4808f00546441d80b9b853d246e6fb63aa34ef33..05d0009affba5d8fa926c2339a393fdb5f0dfe56 100644 (file)
@@ -1040,36 +1040,27 @@ 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;
index 19c26c590a1b6424b73140c5b3458e9b77b4216d..82f69754eacba0b9a84edb9f003d922a80a6e33e 100644 (file)
@@ -1465,9 +1465,7 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
     // If there is text changed, callback is called.
     if(mTextChanged)
     {
-      Dali::Toolkit::TextEditor handle(GetOwner());
-      mTextChangedSignal.Emit(handle);
-      mTextChanged = false;
+      EmitTextChangedSignal();
     }
   }
 
@@ -1682,9 +1680,23 @@ void TextEditor::CaretMoved(unsigned int position)
   }
 }
 
-void TextEditor::TextChanged()
+void TextEditor::TextChanged(bool immediate)
 {
-  mTextChanged = true;
+  if(immediate) // Emits TextChangedSignal immediately
+  {
+    EmitTextChangedSignal();
+  }
+  else
+  {
+    mTextChanged = true;
+  }
+}
+
+void TextEditor::EmitTextChangedSignal()
+{
+  Dali::Toolkit::TextEditor handle(GetOwner());
+  mTextChangedSignal.Emit(handle);
+  mTextChanged = false;
 }
 
 void TextEditor::MaxLengthReached()
index 4c408cad407a910215bd0cbac74fc0ca00c6405f..a8b9a0c188e97edfa639d7b04eeb9419fce1a69c 100644 (file)
@@ -205,7 +205,7 @@ private: // From Control
   /**
    * @copydoc Text::EditableControlInterface::TextChanged()
    */
-  void TextChanged() override;
+  void TextChanged(bool immediate) override;
 
   /**
    * @copydoc Text::EditableControlInterface::MaxLengthReached()
@@ -328,6 +328,11 @@ private: // Implementation
    */
   void OnIdleSignal();
 
+  /**
+   * @brief Emits TextChanged signal.
+   */
+  void EmitTextChangedSignal();
+
   /**
    * @brief set RenderActor's position with new scrollPosition
    *
@@ -402,7 +407,7 @@ private: // Data
   bool  mScrollAnimationEnabled : 1;
   bool  mScrollBarEnabled : 1;
   bool  mScrollStarted : 1;
-  bool  mTextChanged : 1;
+  bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
 
   struct AccessibleImpl : public DevelControl::AccessibleImpl,
                           public virtual Dali::Accessibility::Text,
index d29bfad4d1f9bb003cca282514672cca65ccf5d6..d12a708eb8c3d04a74b8a15f74239d7d97ac8fdb 100644 (file)
@@ -1416,9 +1416,7 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
     // If there is text changed, callback is called.
     if(mTextChanged)
     {
-      Dali::Toolkit::TextField handle(GetOwner());
-      mTextChangedSignal.Emit(handle);
-      mTextChanged = false;
+      EmitTextChangedSignal();
     }
   }
 
@@ -1710,9 +1708,23 @@ void TextField::CaretMoved(unsigned int position)
   }
 }
 
-void TextField::TextChanged()
+void TextField::TextChanged(bool immediate)
 {
-  mTextChanged = true;
+  if(immediate) // Emits TextChangedSignal immediately
+  {
+    EmitTextChangedSignal();
+  }
+  else
+  {
+    mTextChanged = true;
+  }
+}
+
+void TextField::EmitTextChangedSignal()
+{
+  Dali::Toolkit::TextField handle(GetOwner());
+  mTextChangedSignal.Emit(handle);
+  mTextChanged = false;
 }
 
 void TextField::MaxLengthReached()
index 07a7a374511c3519f0127def51b00bf6c19bcd7c..8ddc2277e91d2a402f52054003e3e59c39e754f6 100644 (file)
@@ -197,7 +197,7 @@ private: // From Control
   /**
    * @copydoc Text::EditableControlInterface::TextChanged()
    */
-  void TextChanged() override;
+  void TextChanged(bool immediate) override;
 
   /**
    * @copydoc Text::EditableControlInterface::MaxLengthReached()
@@ -298,6 +298,11 @@ private: // Implementation
    */
   void OnIdleSignal();
 
+  /**
+   * @brief Emits TextChanged signal.
+   */
+  void EmitTextChangedSignal();
+
   /**
    * Construct a new TextField.
    */
@@ -357,7 +362,7 @@ private: // Data
   int   mRenderingBackend;
   int   mExceedPolicy;
   bool  mHasBeenStaged : 1;
-  bool  mTextChanged : 1;
+  bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
 
 protected:
   struct AccessibleImpl : public DevelControl::AccessibleImpl,
index c6c40588f5d8f782861d61ad661d114d57efc064..ce0bf598a3d5060c84ca9fb723ea051994886e9b 100644 (file)
@@ -287,7 +287,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE
      (NULL != controller.mImpl->mEditableControlInterface))
   {
     // Do this last since it provides callbacks into application code
-    controller.mImpl->mEditableControlInterface->TextChanged();
+    controller.mImpl->mEditableControlInterface->TextChanged(false);
   }
 
   return true;
@@ -742,7 +742,7 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE
      (NULL != controller.mImpl->mEditableControlInterface))
   {
     // Do this last since it provides callbacks into application code
-    controller.mImpl->mEditableControlInterface->TextChanged();
+    controller.mImpl->mEditableControlInterface->TextChanged(false);
   }
 
   return callbackData;
@@ -852,7 +852,7 @@ void Controller::EventHandler::TextPopupButtonTouched(Controller& controller, Da
 
       if(NULL != controller.mImpl->mEditableControlInterface)
       {
-        controller.mImpl->mEditableControlInterface->TextChanged();
+        controller.mImpl->mEditableControlInterface->TextChanged(true);
       }
       break;
     }
index c22e207b0fb9687b4fc5388429bdcd8a845073f5..6fb472ecc9280e1e4e371fffa92763454e994c14 100644 (file)
@@ -153,7 +153,7 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string&
   // Do this last since it provides callbacks into application code.
   if(NULL != impl.mEditableControlInterface)
   {
-    impl.mEditableControlInterface->TextChanged();
+    impl.mEditableControlInterface->TextChanged(true);
   }
 }
 
@@ -433,7 +433,7 @@ void Controller::TextUpdater::PasteText(Controller& controller, const std::strin
   if(NULL != impl.mEditableControlInterface)
   {
     // Do this last since it provides callbacks into application code
-    impl.mEditableControlInterface->TextChanged();
+    impl.mEditableControlInterface->TextChanged(true);
   }
 }
 
index 0f55494405b9a338422be9dd9cefb716a6dca3a9..4bd0de0adfe7b3b5bd812f45e2e90c23776261cb 100644 (file)
@@ -59,8 +59,10 @@ public:
 
   /**
    * @brief Called to signal that text has been inserted or deleted.
+   * 
+   * @param[in] immediate If true, it immediately emits the signal, if false, only emits once the signal when OnRelayout() is called next time.
    */
-  virtual void TextChanged() = 0;
+  virtual void TextChanged(bool immediate) = 0;
 
   /**
    * @brief Called when the number of characters to be inserted exceeds the maximum limit