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;
DALI_TEST_EQUALS(DaliTestCheckMaps(underlineMapGet1, underlineMapSet1), true, TEST_LOCATION);
application.GetScene().Add(textEditor1);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+ }
+
+ int UtcDaliTextEditorCharacterSpacing(void)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorCharacterSpacing ");
+
+ TextEditor textEditor = TextEditor::New();
+
+ textEditor.SetProperty(Actor::Property::SIZE, Vector2(150.0f, 300.f));
+
+ application.GetScene().Add(textEditor);
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, "Hi Experiment");
+ textEditor.SetProperty(DevelTextEditor::Property::CHARACTER_SPACING, 10.f);
+ DALI_TEST_EQUALS(textEditor.GetProperty<float>(DevelTextEditor::Property::CHARACTER_SPACING), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
application.SendNotification();
application.Render();
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;
DALI_TEST_EQUALS(DaliTestCheckMaps(underlineMapGet3, underlineMapSet3), true, TEST_LOCATION);
application.GetScene().Add(field3);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+ }
+
+ int UtcDaliTextFieldCharacterSpacing(void)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextFieldCharacterSpacing ");
+
+ TextField textField = TextField::New();
+
+ textField.SetProperty(Actor::Property::SIZE, Vector2(150.0f, 300.f));
+
+ application.GetScene().Add(textField);
+ application.SendNotification();
+ application.Render();
+
+ textField.SetProperty(TextField::Property::TEXT, "Hi Experiment");
+ textField.SetProperty(DevelTextField::Property::CHARACTER_SPACING, 10.f);
+ DALI_TEST_EQUALS(textField.GetProperty<float>(DevelTextField::Property::CHARACTER_SPACING), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
application.SendNotification();
application.Render();
* @details Name "inputStrikethrough", type Property::MAP.
*/
INPUT_STRIKETHROUGH,
+
+ /**
+ * @brief The spaces between characters in Pixels.
+ * @details Name "characterSpacing", type Property::FLOAT.
+ * @note
+ * A positive value will make the characters far apart (expanded) and a negative value will bring them closer (condensed).
+ * The default value is 0.f which does nothing.
+ */
+ CHARACTER_SPACING,
};
} // namespace Property
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.
*
* @param[in] textEditor The instance of TextEditor.
* @details Name "inputStrikethrough", type Property::MAP.
*/
INPUT_STRIKETHROUGH,
+
+ /**
+ * @brief The spaces between characters in Pixels.
+ * @details Name "characterSpacing", type Property::FLOAT.
+ * @note
+ * A positive value will make the characters far apart (expanded) and a negative value will bring them closer (condensed).
+ * The default value is 0.f which does nothing.
+ */
+ CHARACTER_SPACING,
};
} // namespace Property
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.
* if a line contains characters with different directions, multiple sizes will be returned for each block of contiguous characters with the same direction.
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "minLineSize", FLOAT, MIN_LINE_SIZE )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH )
+ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "characterSpacing", FLOAT, CHARACTER_SPACING )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
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)
{
}
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "strikethrough", MAP, STRIKETHROUGH )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH )
+ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "characterSpacing", FLOAT, CHARACTER_SPACING )
DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
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)
{
}