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>
// 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();
}
}
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();
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),
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
#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.
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;
// 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();
}
}
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),
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
#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.
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();
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;
#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.
mEmbossDefaults(NULL),
mOutlineDefaults(NULL),
mEventData(NULL),
+ mIdleCallback(NULL),
mFontClient(),
mClipboard(),
mView(),
mTextFitChanged(false),
mTextFitArrayEnabled(false),
mIsLayoutDirectionChanged(false),
- mIsUserInteractionEnabled(true)
+ mIsUserInteractionEnabled(true),
+ mProcessorRegistered(false)
{
mModel = Model::New();
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.
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;
/*
- * 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.
// 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>
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>
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()
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,
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
#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.
#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
*
* 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.
/**
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.
/**
*/
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.