Merge pull request #96038 from kitbdev/fix-line-edit-caret-word-mode

Fix LineEdit word mode when there are no more words
This commit is contained in:
Rémi Verschelde 2024-09-04 17:12:06 +02:00
commit f69de1c522
No known key found for this signature in database
GPG Key ID: C3336907360768E1
3 changed files with 92 additions and 23 deletions

View File

@ -68,10 +68,15 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
int cc = caret_column;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
if (words.is_empty() || cc <= words[0]) {
// Move to the start when there are no more words.
cc = 0;
} else {
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
}
}
}
@ -101,10 +106,15 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
int cc = caret_column;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
if (words.is_empty() || cc >= words[words.size() - 1]) {
// Move to the end when there are no more words.
cc = text.length();
} else {
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
}
}
}
@ -159,10 +169,15 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) {
int cc = caret_column;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
if (words.is_empty() || cc <= words[0]) {
// Delete to the start when there are no more words.
cc = 0;
} else {
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
}
}
}
@ -198,10 +213,15 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
if (p_word) {
int cc = caret_column;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
if (words.is_empty() || cc >= words[words.size() - 1]) {
// Delete to the end when there are no more words.
cc = text.length();
} else {
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
}
}
}

View File

@ -2393,7 +2393,7 @@ void TextEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
} else {
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(get_caret_line(i))->get_rid());
if (words.is_empty() || cc <= words[0]) {
// This solves the scenario where there are no words but glyfs that can be ignored.
// Move to the start when there are no more words.
cc = 0;
} else {
for (int j = words.size() - 2; j >= 0; j = j - 2) {
@ -2450,7 +2450,7 @@ void TextEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
} else {
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(get_caret_line(i))->get_rid());
if (words.is_empty() || cc >= words[words.size() - 1]) {
// This solves the scenario where there are no words but glyfs that can be ignored.
// Move to the end when there are no more words.
cc = text[get_caret_line(i)].length();
} else {
for (int j = 1; j < words.size(); j = j + 2) {
@ -2666,7 +2666,7 @@ void TextEdit::_do_backspace(bool p_word, bool p_all_to_left) {
// Get a list with the indices of the word bounds of the given text line.
const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(get_caret_line(caret_index))->get_rid());
if (words.is_empty() || column <= words[0]) {
// If "words" is empty, meaning no words are left, we can remove everything until the beginning of the line.
// Delete to the start when there are no more words.
column = 0;
} else {
// Otherwise search for the first word break that is smaller than the index from we're currently deleting.
@ -2731,10 +2731,15 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) {
int column = get_caret_column(caret_index);
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int j = 1; j < words.size(); j = j + 2) {
if (words[j] > column) {
column = words[j];
break;
if (words.is_empty() || column >= words[words.size() - 1]) {
// Delete to the end when there are no more words.
column = text[get_caret_line(i)].length();
} else {
for (int j = 1; j < words.size(); j = j + 2) {
if (words[j] > column) {
column = words[j];
break;
}
}
}

View File

@ -4232,6 +4232,18 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 4);
text_edit->remove_secondary_carets();
// Remove when there are no words, only symbols.
text_edit->set_text("#{}");
text_edit->set_caret_line(0);
text_edit->set_caret_column(3);
SEND_GUI_ACTION("ui_text_backspace_word");
CHECK(text_edit->get_viewport()->is_input_handled());
CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_text() == "");
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 0);
}
SUBCASE("[TextEdit] ui_text_backspace_word same line") {
@ -4891,6 +4903,18 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 2);
text_edit->remove_secondary_carets();
// Remove when there are no words, only symbols.
text_edit->set_text("#{}");
text_edit->set_caret_line(0);
text_edit->set_caret_column(0);
SEND_GUI_ACTION("ui_text_delete_word");
CHECK(text_edit->get_viewport()->is_input_handled());
CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_text() == "");
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 0);
}
SUBCASE("[TextEdit] ui_text_delete_word same line") {
@ -5301,6 +5325,16 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_CHECK("caret_changed", empty_signal_args);
SIGNAL_CHECK_FALSE("text_changed");
SIGNAL_CHECK_FALSE("lines_edited_from");
// Move when there are no words, only symbols.
text_edit->set_text("#{}");
text_edit->set_caret_line(0);
text_edit->set_caret_column(3);
SEND_GUI_ACTION("ui_text_caret_word_left");
CHECK(text_edit->get_viewport()->is_input_handled());
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 0);
}
SUBCASE("[TextEdit] ui_text_caret_left") {
@ -5563,6 +5597,16 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_CHECK("caret_changed", empty_signal_args);
SIGNAL_CHECK_FALSE("text_changed");
SIGNAL_CHECK_FALSE("lines_edited_from");
// Move when there are no words, only symbols.
text_edit->set_text("#{}");
text_edit->set_caret_line(0);
text_edit->set_caret_column(0);
SEND_GUI_ACTION("ui_text_caret_word_right");
CHECK(text_edit->get_viewport()->is_input_handled());
CHECK(text_edit->get_caret_line(0) == 0);
CHECK(text_edit->get_caret_column(0) == 3);
}
SUBCASE("[TextEdit] ui_text_caret_right") {