Add editable text's idler function at PostProcessor time, instead of whenever we... 84/305184/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 29 Jan 2024 12:01:28 +0000 (21:01 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 29 Jan 2024 12:54:24 +0000 (21:54 +0900)
Since we need to remove whole queued style change signals even if idler add failed,
let we collect duplicated codes into single class, and make TextEditor / TextField just use it.

Change-Id: Ic181814eb8a4bcb12fb17c45dd39e3210bfb136a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
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/controller/text-controller-impl.h
dali-toolkit/internal/text/controller/text-controller.cpp
dali-toolkit/internal/text/controller/text-controller.h

index ee04c2e..dcb33d7 100644 (file)
@@ -817,23 +817,7 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
   // The text-editor adds an idle callback to the adaptor to emit the signals after the size negotiation.
   if(!mController->IsInputStyleChangedSignalsQueueEmpty())
   {
-    if(Adaptor::IsAvailable())
-    {
-      Adaptor& adaptor = Adaptor::Get();
-
-      if(NULL == mIdleCallback)
-      {
-        // @note: The callback manager takes the ownership of the callback object.
-        mIdleCallback = MakeCallback(this, &TextEditor::OnIdleSignal);
-        if(DALI_UNLIKELY(!adaptor.AddIdle(mIdleCallback, false)))
-        {
-          DALI_LOG_ERROR("Fail to add idle callback for text editor queue. Skip these callbacks\n");
-
-          // Set the pointer to null as the callback manager deletes the callback even AddIdle failed.
-          mIdleCallback = NULL;
-        }
-      }
-    }
+    mController->RequestProcessInputStyleChangedSignals();
   }
 }
 
@@ -1325,15 +1309,6 @@ bool TextEditor::OnTouched(Actor actor, const TouchEvent& touch)
   return false;
 }
 
-void TextEditor::OnIdleSignal()
-{
-  // Emits the change of input style signals.
-  mController->ProcessInputStyleChangedSignals();
-
-  // Set the pointer to null as the callback manager deletes the callback after execute it.
-  mIdleCallback = NULL;
-}
-
 void TextEditor::ApplyScrollPosition()
 {
   const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
@@ -1384,7 +1359,6 @@ void TextEditor::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type typ
 TextEditor::TextEditor(ControlBehaviour additionalBehaviour)
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
   mAnimationPeriod(0.0f, 0.0f),
-  mIdleCallback(NULL),
   mAlignmentOffset(0.f),
   mScrollAnimationDuration(0.f),
   mLineSpacing(0.f),
@@ -1407,12 +1381,6 @@ TextEditor::TextEditor(ControlBehaviour additionalBehaviour)
 TextEditor::~TextEditor()
 {
   UnparentAndReset(mStencil);
-
-  if((NULL != mIdleCallback) && Adaptor::IsAvailable())
-  {
-    // Removes the callback from the callback manager in case the text-editor is destroyed before the callback is executed.
-    Adaptor::Get().RemoveIdle(mIdleCallback);
-  }
 }
 
 std::string TextEditor::TextEditorAccessible::GetName() const
index 7b30c17..0eb9f6f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -597,11 +597,10 @@ private: // Data
   std::vector<Toolkit::TextAnchor> mAnchorActors;
   Dali::InputMethodOptions         mInputMethodOptions;
 
-  Actor         mRenderableActor;
-  Actor         mActiveLayer;
-  Actor         mCursorLayer;
-  Actor         mBackgroundActor;
-  CallbackBase* mIdleCallback;
+  Actor mRenderableActor;
+  Actor mActiveLayer;
+  Actor mCursorLayer;
+  Actor mBackgroundActor;
 
   float mAlignmentOffset;
   float mScrollAnimationDuration;
index d26dded..1714946 100644 (file)
@@ -728,23 +728,7 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
   // The text-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
   if(!mController->IsInputStyleChangedSignalsQueueEmpty())
   {
-    if(Adaptor::IsAvailable())
-    {
-      Adaptor& adaptor = Adaptor::Get();
-
-      if(NULL == mIdleCallback)
-      {
-        // @note: The callback manager takes the ownership of the callback object.
-        mIdleCallback = MakeCallback(this, &TextField::OnIdleSignal);
-        if(DALI_UNLIKELY(!adaptor.AddIdle(mIdleCallback, false)))
-        {
-          DALI_LOG_ERROR("Fail to add idle callback for text field queue. Skip these callbacks\n");
-
-          // Set the pointer to null as the callback manager deletes the callback even AddIdle failed.
-          mIdleCallback = NULL;
-        }
-      }
-    }
+    mController->RequestProcessInputStyleChangedSignals();
   }
 }
 
@@ -1163,18 +1147,8 @@ void TextField::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type
   mController->ChangedLayoutDirection();
 }
 
-void TextField::OnIdleSignal()
-{
-  // Emits the change of input style signals.
-  mController->ProcessInputStyleChangedSignals();
-
-  // Set the pointer to null as the callback manager deletes the callback after execute it.
-  mIdleCallback = NULL;
-}
-
 TextField::TextField(ControlBehaviour additionalBehaviour)
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
-  mIdleCallback(NULL),
   mAlignmentOffset(0.f),
   mRenderingBackend(DEFAULT_RENDERING_BACKEND),
   mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP),
@@ -1193,11 +1167,6 @@ TextField::TextField(ControlBehaviour additionalBehaviour)
 TextField::~TextField()
 {
   UnparentAndReset(mStencil);
-
-  if((NULL != mIdleCallback) && Adaptor::IsAvailable())
-  {
-    Adaptor::Get().RemoveIdle(mIdleCallback);
-  }
 }
 
 Vector<Vector2> TextField::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const
index afaed24..215fd10 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -447,13 +447,6 @@ private: // Implementation
   bool OnTouched(Actor actor, const TouchEvent& touch);
 
   /**
-   * @brief Callbacks called on idle.
-   *
-   * If there are notifications of change of input style on the queue, Toolkit::TextField::InputStyleChangedSignal() are emitted.
-   */
-  void OnIdleSignal();
-
-  /**
    * @brief Emits TextChanged signal.
    */
   void EmitTextChangedSignal();
@@ -548,11 +541,10 @@ private: // Data
   std::vector<Toolkit::TextAnchor> mAnchorActors;
   Dali::InputMethodOptions         mInputMethodOptions;
 
-  Actor         mRenderableActor;
-  Actor         mActiveLayer;
-  Actor         mCursorLayer;
-  Actor         mBackgroundActor;
-  CallbackBase* mIdleCallback;
+  Actor mRenderableActor;
+  Actor mActiveLayer;
+  Actor mCursorLayer;
+  Actor mBackgroundActor;
 
   float mAlignmentOffset;
   int   mRenderingBackend;
index 1024869..56ca85b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -331,6 +331,7 @@ struct Controller::Impl
     mEmbossDefaults(NULL),
     mOutlineDefaults(NULL),
     mEventData(NULL),
+    mIdleCallback(NULL),
     mFontClient(),
     mClipboard(),
     mView(),
@@ -372,7 +373,8 @@ struct Controller::Impl
     mTextFitChanged(false),
     mTextFitArrayEnabled(false),
     mIsLayoutDirectionChanged(false),
-    mIsUserInteractionEnabled(true)
+    mIsUserInteractionEnabled(true),
+    mProcessorRegistered(false)
   {
     mModel = Model::New();
 
@@ -1053,6 +1055,7 @@ public:
   EmbossDefaults*              mEmbossDefaults;             ///< Avoid allocating this when the user does not specify emboss parameters.
   OutlineDefaults*             mOutlineDefaults;            ///< Avoid allocating this when the user does not specify outline parameters.
   EventData*                   mEventData;                  ///< Avoid allocating everything for text input until EnableTextInput().
+  CallbackBase*                mIdleCallback;               ///< Callback what would be called at idler
   TextAbstraction::FontClient  mFontClient;                 ///< Handle to the font client.
   Clipboard                    mClipboard;                  ///< Handle to the system clipboard
   View                         mView;                       ///< The view interface to the rendering back-end.
@@ -1102,6 +1105,7 @@ public:
   bool  mTextFitArrayEnabled : 1;      ///< Whether the text's fit array is enabled.
   bool  mIsLayoutDirectionChanged : 1; ///< Whether the layout has changed.
   bool  mIsUserInteractionEnabled : 1; ///< Whether the user interaction is enabled.
+  bool  mProcessorRegistered : 1;      ///< Whether the text controller registered into processor or not.
 
 private:
   friend ControllerImplEventHandler;
index 203d242..5402115 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 #include <memory.h>
 #include <cmath>
@@ -45,7 +46,7 @@ namespace
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
-const char* EMPTY_STRING = "";
+const char* EMPTY_STRING         = "";
 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
 
 template<typename Type>
@@ -1566,9 +1567,23 @@ bool Controller::IsInputStyleChangedSignalsQueueEmpty()
   return mImpl->IsInputStyleChangedSignalsQueueEmpty();
 }
 
-void Controller::ProcessInputStyleChangedSignals()
+void Controller::RequestProcessInputStyleChangedSignals()
 {
-  mImpl->ProcessInputStyleChangedSignals();
+  if(Dali::Adaptor::IsAvailable() && !mImpl->mProcessorRegistered)
+  {
+    mImpl->mProcessorRegistered = true;
+    Dali::Adaptor::Get().RegisterProcessor(*this, true);
+  }
+}
+
+void Controller::OnIdleSignal()
+{
+  if(mImpl->mIdleCallback)
+  {
+    mImpl->mIdleCallback = NULL;
+
+    mImpl->ProcessInputStyleChangedSignals();
+  }
 }
 
 void Controller::KeyboardFocusGainEvent()
@@ -1829,6 +1844,36 @@ int Controller::GetAnchorIndex(size_t characterOffset)
   return mImpl->GetAnchorIndex(characterOffset);
 }
 
+void Controller::Process(bool postProcess)
+{
+  if(Dali::Adaptor::IsAvailable() && mImpl->mProcessorRegistered)
+  {
+    Dali::Adaptor& adaptor = Dali::Adaptor::Get();
+
+    adaptor.UnregisterProcessor(*this, true);
+    mImpl->mProcessorRegistered = false;
+
+    if(NULL == mImpl->mIdleCallback)
+    {
+      // @note: The callback manager takes the ownership of the callback object.
+      mImpl->mIdleCallback = MakeCallback(this, &Controller::OnIdleSignal);
+      if(DALI_UNLIKELY(!adaptor.AddIdle(mImpl->mIdleCallback, false)))
+      {
+        DALI_LOG_ERROR("Fail to add idle callback for text controller style changed signals queue. Skip these callbacks\n");
+
+        // Clear queue forcely.
+        if(mImpl->mEventData)
+        {
+          mImpl->mEventData->mInputStyleChangedQueue.Clear();
+        }
+
+        // Set the pointer to null as the callback manager deletes the callback even AddIdle failed.
+        mImpl->mIdleCallback = NULL;
+      }
+    }
+  }
+}
+
 Controller::Controller(ControlInterface*           controlInterface,
                        EditableControlInterface*   editableControlInterface,
                        SelectableControlInterface* selectableControlInterface,
@@ -1839,6 +1884,17 @@ Controller::Controller(ControlInterface*           controlInterface,
 
 Controller::~Controller()
 {
+  if(Dali::Adaptor::IsAvailable())
+  {
+    if(mImpl->mProcessorRegistered)
+    {
+      Dali::Adaptor::Get().UnregisterProcessor(*this, true);
+    }
+    if(mImpl->mIdleCallback)
+    {
+      Dali::Adaptor::Get().RemoveIdle(mImpl->mIdleCallback);
+    }
+  }
 }
 
 } // namespace Dali::Toolkit::Text
index ad37df0..0364335 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_CONTROLLER_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -22,6 +22,7 @@
 #include <dali-toolkit/devel-api/text/spanned.h>
 #include <dali/devel-api/adaptor-framework/clipboard.h>
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
+#include <dali/integration-api/processor-interface.h>
 #include <dali/public-api/events/gesture.h>
 
 // INTERNAL INCLUDES
@@ -70,7 +71,12 @@ typedef IntrusivePtr<Controller> ControllerPtr;
  *
  * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface.
  */
-class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface, public HiddenText::Observer, public ConnectionTracker
+class Controller : public RefObject,
+                   public Decorator::ControllerInterface,
+                   public TextSelectionPopupCallbackInterface,
+                   public HiddenText::Observer,
+                   public ConnectionTracker,
+                   public Integration::Processor
 {
 public: // Enumerated types.
   /**
@@ -1916,12 +1922,22 @@ public: // Input style change signals.
   bool IsInputStyleChangedSignalsQueueEmpty();
 
   /**
-   * @brief Process all pending input style changed signals.
+   * @brief Request process all pending input style changed signals.
    *
-   * Calls the Text::ControlInterface::InputStyleChanged() method which is overriden by the
+   * Request to calls the Text::ControlInterface::InputStyleChanged() method which is overriden by the
    * text controls. Text controls may send signals to state the input style has changed.
+   *
+   * The signal will be execute next idle time, or skip if we fail to add idler.
    */
-  void ProcessInputStyleChangedSignals();
+  void RequestProcessInputStyleChangedSignals();
+
+private:
+  /**
+   * @brief Callbacks called on idle.
+   *
+   * If there are notifications of change of input style on the queue, Toolkit::TextField::InputStyleChangedSignal() are emitted.
+   */
+  void OnIdleSignal();
 
 public: // Text-input Event Queuing.
   /**
@@ -2168,6 +2184,20 @@ protected: // Inherit from HiddenText.
    */
   void DisplayTimeExpired() override;
 
+protected: // Inherit from Integration::Processor
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process(bool postProcess) override;
+
+  /**
+   * @copydoc Dali::Integration::Processor::GetProcessorName()
+   */
+  std::string_view GetProcessorName() const override
+  {
+    return "Text::Controller";
+  }
+
 private: // Private contructors & copy operator.
   /**
    * @brief Private constructor.