/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
static uint32_t oldSelectionStart;
static uint32_t oldSelectionEnd;
static bool gSelectionClearedCallbackCalled;
+static bool gSelectionStartedCallbackCalled;
static bool gAnchorClickedCallBackCalled;
static bool gAnchorClickedCallBackNotCalled;
static bool gTextChangedCallBackCalled;
bool* mCallbackFlag;
};
+static void TestSelectionStartedCallback(TextEditor control)
+{
+ tet_infoline(" TestSelectionStartedCallback");
+
+ gSelectionStartedCallbackCalled = true;
+}
+
static void TestSelectionClearedCallback(TextEditor control)
{
tet_infoline(" TestSelectionClearedCallback");
END_TEST;
}
+int utcDaliTextEditorSelectionStartedSignal(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorSelectionStartedSignal");
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK(editor);
+
+ application.GetScene().Add(editor);
+
+ // connect to the selection changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextEditor::SelectionStartedSignal(editor).Connect(&TestSelectionStartedCallback);
+ bool selectionStartedSignal = false;
+ editor.ConnectSignal(testTracker, "selectionStarted", CallbackFunctor(&selectionStartedSignal));
+
+ editor.SetProperty(TextEditor::Property::TEXT, "Hello\nworld\nHello world");
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10.f);
+ editor.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ editor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ editor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Tap on the text editor
+ TestGenerateTap(application, 3.0f, 25.0f);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Move to second line of the text & Select some text in the right of the current cursor position
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_CURSOR_RIGHT, KEY_SHIFT_MODIFIER, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gSelectionStartedCallbackCalled);
+
+ // remove selection
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::UP, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ gSelectionStartedCallbackCalled = false;
+
+ DevelTextEditor::SelectText(editor, 1, 3);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gSelectionStartedCallbackCalled);
+
+ END_TEST;
+}
+
int utcDaliTextEditorSelectionWithSecondaryCursor(void)
{
ToolkitTestApplication application;
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
static uint32_t oldSelectionStart;
static uint32_t oldSelectionEnd;
static bool gSelectionClearedCallbackCalled;
+static bool gSelectionStartedCallbackCalled;
static bool gAnchorClickedCallBackCalled;
static bool gAnchorClickedCallBackNotCalled;
static bool gTextChangedCallBackCalled;
gSelectionClearedCallbackCalled = true;
}
+static void TestSelectionStartedCallback(TextField control)
+{
+ tet_infoline(" TestSelectionStartedCallback");
+
+ gSelectionStartedCallbackCalled = true;
+}
+
static void TestSelectionChangedCallback(TextField control, uint32_t oldStart, uint32_t oldEnd)
{
tet_infoline(" TestSelectionChangedCallback");
END_TEST;
}
+int utcDaliTextFieldSelectionStartedSignal(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldSelectionStartedSignal");
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK(field);
+
+ application.GetScene().Add(field);
+
+ // connect to the selection changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextField::SelectionStartedSignal(field).Connect(&TestSelectionStartedCallback);
+ bool selectionStartedSignal = false;
+ field.ConnectSignal(testTracker, "selectionStarted", CallbackFunctor(&selectionStartedSignal));
+
+ field.SetProperty(TextField::Property::TEXT, "Hello\nworld\nHello world");
+ field.SetProperty(TextField::Property::POINT_SIZE, 10.f);
+ field.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ field.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Tap on the text field
+ TestGenerateTap(application, 3.0f, 25.0f);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Move to second line of the text & Select some text in the right of the current cursor position
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_CURSOR_RIGHT, KEY_SHIFT_MODIFIER, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gSelectionStartedCallbackCalled);
+
+ // remove selection
+ application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::UP, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ gSelectionStartedCallbackCalled = false;
+
+ DevelTextField::SelectText(field, 1, 3);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gSelectionStartedCallbackCalled);
+
+ END_TEST;
+}
+
int utcDaliTextFieldSelectionChangedSignal(void)
{
ToolkitTestApplication application;
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
return GetImpl(textEditor).SelectionClearedSignal();
}
+SelectionStartedSignalType& SelectionStartedSignal(TextEditor textEditor)
+{
+ return GetImpl(textEditor).SelectionStartedSignal();
+}
+
void SelectWholeText(TextEditor textEditor)
{
GetImpl(textEditor).SelectWholeText();
*/
DALI_TOOLKIT_API SelectionClearedSignalType& SelectionClearedSignal(TextEditor textEditor);
+/**
+ * @brief selection start signal type.
+ */
+using SelectionStartedSignalType = Signal<void(TextEditor)>;
+
+/**
+ * @brief This signal is emitted when the selection start.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName( TextEditor textEditor);
+ * @endcode
+ * @param[in] textEditor The instance of TextEditor.
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API SelectionStartedSignalType& SelectionStartedSignal(TextEditor textEditor);
+
/**
* @brief Select the whole text of TextEditor.
*
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
return GetImpl(textField).SelectionClearedSignal();
}
+SelectionStartedSignalType& SelectionStartedSignal(TextField textField)
+{
+ return GetImpl(textField).SelectionStartedSignal();
+}
+
void SelectWholeText(TextField textField)
{
GetImpl(textField).SelectWholeText();
*/
DALI_TOOLKIT_API SelectionClearedSignalType& SelectionClearedSignal(TextField textField);
+/**
+ * @brief selection start signal type.
+ */
+using SelectionStartedSignalType = Signal<void(TextField)>;
+
+/**
+ * @brief This signal is emitted when the selection start.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName( TextField textField);
+ * @endcode
+ * @param[in] textField The instance of TextField.
+ * @return The signal to connect to
+ */
+DALI_TOOLKIT_API SelectionStartedSignalType& SelectionStartedSignal(TextField textField);
+
/**
* @brief Get the rendered size of a specific text range.
* if the requested text is at multilines, multiple sizes will be returned for each text located in a separate line.
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED)
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionChanged", SIGNAL_SELECTION_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionCleared", SIGNAL_SELECTION_CLEARED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionStarted", SIGNAL_SELECTION_STARTED )
DALI_TYPE_REGISTRATION_END()
// clang-format on
return mSelectionClearedSignal;
}
+DevelTextEditor::SelectionStartedSignalType& TextEditor::SelectionStartedSignal()
+{
+ return mSelectionStartedSignal;
+}
+
Text::ControllerPtr TextEditor::GetTextController()
{
return mController;
editorImpl.SelectionClearedSignal().Connect(tracker, functor);
}
}
+ else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_STARTED))
+ {
+ if(editor)
+ {
+ Internal::TextEditor& editorImpl(GetImpl(editor));
+ editorImpl.SelectionStartedSignal().Connect(tracker, functor);
+ }
+ }
else
{
// signalName does not match any signal
EmitCursorPositionChangedSignal();
}
+ if(mSelectionStarted)
+ {
+ EmitSelectionStartedSignal();
+ }
+
if(mSelectionChanged)
{
EmitSelectionChangedSignal();
mSelectionCleared = false;
}
+void TextEditor::EmitSelectionStartedSignal()
+{
+ Dali::Toolkit::TextEditor handle(GetOwner());
+ mSelectionStartedSignal.Emit(handle);
+ mSelectionStarted = false;
+}
+
void TextEditor::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t newStart, uint32_t newEnd)
{
if(((oldStart != newStart) || (oldEnd != newEnd)) && !mSelectionChanged)
{
mSelectionCleared = true;
}
+ else
+ {
+ if(oldStart == oldEnd)
+ {
+ mSelectionStarted = true;
+ }
+ }
mSelectionChanged = true;
mOldSelectionStart = oldStart;
mSelectionCleared(false),
mOldPosition(0u),
mOldSelectionStart(0u),
- mOldSelectionEnd(0u)
+ mOldSelectionEnd(0u),
+ mSelectionStarted(false)
{
}
#define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
*/
DevelTextEditor::SelectionClearedSignalType& SelectionClearedSignal();
+ /**
+ * @copydoc Dali::Toollkit::TextEditor::SelectionStartedSignal()
+ */
+ DevelTextEditor::SelectionStartedSignalType& SelectionStartedSignal();
+
/**
* Connects a callback function with the object's signals.
* @param[in] object The object providing the signal.
*/
void EmitSelectionClearedSignal();
+ /**
+ * @brief Emits SelectionStarted signal.
+ */
+ void EmitSelectionStartedSignal();
+
/**
* @brief set RenderActor's position with new scrollPosition
*
Toolkit::DevelTextEditor::CursorPositionChangedSignalType mCursorPositionChangedSignal;
Toolkit::DevelTextEditor::SelectionChangedSignalType mSelectionChangedSignal;
Toolkit::DevelTextEditor::SelectionClearedSignalType mSelectionClearedSignal;
+ Toolkit::DevelTextEditor::SelectionStartedSignalType mSelectionStartedSignal;
InputMethodContext mInputMethodContext;
Text::ControllerPtr mController;
uint32_t mOldSelectionStart;
uint32_t mOldSelectionEnd;
+ bool mSelectionStarted : 1; ///< If true, emits SelectionStartedSignal at the end of OnRelayout().
+
struct PropertyHandler;
/**
DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED)
DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionChanged", SIGNAL_SELECTION_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionCleared", SIGNAL_SELECTION_CLEARED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionStarted", SIGNAL_SELECTION_STARTED )
DALI_TYPE_REGISTRATION_END()
// clang-format on
fieldImpl.SelectionClearedSignal().Connect(tracker, functor);
}
}
+ else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_STARTED))
+ {
+ if(field)
+ {
+ Internal::TextField& fieldImpl(GetImpl(field));
+ fieldImpl.SelectionStartedSignal().Connect(tracker, functor);
+ }
+ }
else
{
// signalName does not match any signal
return mSelectionClearedSignal;
}
+DevelTextField::SelectionStartedSignalType& TextField::SelectionStartedSignal()
+{
+ return mSelectionStartedSignal;
+}
+
void TextField::OnAccessibilityStatusChanged()
{
CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors);
EmitCursorPositionChangedSignal();
}
+ if(mSelectionStarted)
+ {
+ EmitSelectionStartedSignal();
+ }
+
if(mSelectionChanged)
{
EmitSelectionChangedSignal();
mSelectionCleared = false;
}
+void TextField::EmitSelectionStartedSignal()
+{
+ Dali::Toolkit::TextField handle(GetOwner());
+ mSelectionStartedSignal.Emit(handle);
+ mSelectionStarted = false;
+}
+
void TextField::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t newStart, uint32_t newEnd)
{
if(((oldStart != newStart) || (oldEnd != newEnd)) && !mSelectionChanged)
{
mSelectionCleared = true;
}
+ else
+ {
+ if(oldStart == oldEnd)
+ {
+ mSelectionStarted = true;
+ }
+ }
mSelectionChanged = true;
mOldSelectionStart = oldStart;
mSelectionCleared(false),
mOldPosition(0u),
mOldSelectionStart(0u),
- mOldSelectionEnd(0u)
+ mOldSelectionEnd(0u),
+ mSelectionStarted(false)
{
}
#define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
*/
DevelTextField::SelectionClearedSignalType& SelectionClearedSignal();
+ /**
+ * @copydoc TextField::SelectionStartedSignal()
+ */
+ DevelTextField::SelectionStartedSignalType& SelectionStartedSignal();
+
private: // From Control
/**
* @copydoc Control::OnInitialize()
*/
void EmitSelectionClearedSignal();
+ /**
+ * @brief Emits SelectionStarted signal.
+ */
+ void EmitSelectionStartedSignal();
+
/**
* @brief Callback function for when the layout is changed.
* @param[in] actor The actor whose layoutDirection is changed.
Toolkit::DevelTextField::CursorPositionChangedSignalType mCursorPositionChangedSignal;
Toolkit::DevelTextField::SelectionChangedSignalType mSelectionChangedSignal;
Toolkit::DevelTextField::SelectionClearedSignalType mSelectionClearedSignal;
+ Toolkit::DevelTextField::SelectionStartedSignalType mSelectionStartedSignal;
InputMethodContext mInputMethodContext;
Text::ControllerPtr mController;
uint32_t mOldSelectionStart;
uint32_t mOldSelectionEnd;
+ bool mSelectionStarted : 1; ///< If true, emits SelectionStartedSignal at the end of OnRelayout().
+
protected:
struct PropertyHandler;