From 3dd8cfe76a2684d18b11c06609893894cb6dd735 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Mon, 29 Jan 2024 21:01:28 +0900 Subject: [PATCH] Add editable text's idler function at PostProcessor time, instead of whenever we want 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 --- .../controls/text-controls/text-editor-impl.cpp | 34 +----------- .../controls/text-controls/text-editor-impl.h | 11 ++-- .../controls/text-controls/text-field-impl.cpp | 33 +---------- .../controls/text-controls/text-field-impl.h | 18 ++---- .../text/controller/text-controller-impl.h | 8 ++- .../internal/text/controller/text-controller.cpp | 64 ++++++++++++++++++++-- .../internal/text/controller/text-controller.h | 40 ++++++++++++-- 7 files changed, 113 insertions(+), 95 deletions(-) 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 ee04c2e..dcb33d7 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -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 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 7b30c17..0eb9f6f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -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 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; 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 d26dded..1714946 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -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 TextField::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const 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 afaed24..215fd10 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -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 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; diff --git a/dali-toolkit/internal/text/controller/text-controller-impl.h b/dali-toolkit/internal/text/controller/text-controller-impl.h index 1024869..56ca85b 100644 --- a/dali-toolkit/internal/text/controller/text-controller-impl.h +++ b/dali-toolkit/internal/text/controller/text-controller-impl.h @@ -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; diff --git a/dali-toolkit/internal/text/controller/text-controller.cpp b/dali-toolkit/internal/text/controller/text-controller.cpp index 203d242..5402115 100644 --- a/dali-toolkit/internal/text/controller/text-controller.cpp +++ b/dali-toolkit/internal/text/controller/text-controller.cpp @@ -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 #include +#include #include #include #include @@ -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 @@ -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 diff --git a/dali-toolkit/internal/text/controller/text-controller.h b/dali-toolkit/internal/text/controller/text-controller.h index ad37df0..0364335 100644 --- a/dali-toolkit/internal/text/controller/text-controller.h +++ b/dali-toolkit/internal/text/controller/text-controller.h @@ -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 #include #include +#include #include // INTERNAL INCLUDES @@ -70,7 +71,12 @@ typedef IntrusivePtr 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. -- 2.7.4