Merge pull request #60438 from Paulb23/text-edit-tests
Add TextEdit unit tests and multiple fixes.
This commit is contained in:
commit
8c2b9801fd
@ -1446,4 +1446,8 @@ Input::Input() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Input::~Input() {
|
||||||
|
singleton = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
@ -331,6 +331,7 @@ public:
|
|||||||
void set_event_dispatch_function(EventDispatchFunc p_function);
|
void set_event_dispatch_function(EventDispatchFunc p_function);
|
||||||
|
|
||||||
Input();
|
Input();
|
||||||
|
~Input();
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(Input::MouseMode);
|
VARIANT_ENUM_CAST(Input::MouseMode);
|
||||||
|
@ -1428,7 +1428,7 @@ void TextEdit::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_placeholder) {
|
if (!draw_placeholder) {
|
||||||
line_drawing_cache[line] = cache_entry;
|
line_drawing_cache[line] = cache_entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1640,7 +1640,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
|
|||||||
set_caret_column(col);
|
set_caret_column(col);
|
||||||
selection.drag_attempt = false;
|
selection.drag_attempt = false;
|
||||||
|
|
||||||
if (mb->is_shift_pressed() && (caret.column != prev_col || caret.line != prev_line)) {
|
if (selecting_enabled && mb->is_shift_pressed() && (caret.column != prev_col || caret.line != prev_line)) {
|
||||||
if (!selection.active) {
|
if (!selection.active) {
|
||||||
selection.active = true;
|
selection.active = true;
|
||||||
selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER;
|
selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER;
|
||||||
@ -1708,7 +1708,6 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
|
|||||||
last_dblclk = OS::get_singleton()->get_ticks_msec();
|
last_dblclk = OS::get_singleton()->get_ticks_msec();
|
||||||
last_dblclk_pos = mb->get_position();
|
last_dblclk_pos = mb->get_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1716,7 +1715,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
|
|||||||
paste_primary_clipboard();
|
paste_primary_clipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mb->get_button_index() == MouseButton::RIGHT && context_menu_enabled) {
|
if (mb->get_button_index() == MouseButton::RIGHT && (context_menu_enabled || is_move_caret_on_right_click_enabled())) {
|
||||||
_reset_caret_blink_timer();
|
_reset_caret_blink_timer();
|
||||||
|
|
||||||
Point2i pos = get_line_column_at_pos(mpos);
|
Point2i pos = get_line_column_at_pos(mpos);
|
||||||
@ -1741,11 +1740,13 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_generate_context_menu();
|
if (context_menu_enabled) {
|
||||||
menu->set_position(get_screen_position() + mpos);
|
_generate_context_menu();
|
||||||
menu->reset_size();
|
menu->set_position(get_screen_position() + mpos);
|
||||||
menu->popup();
|
menu->reset_size();
|
||||||
grab_focus();
|
menu->popup();
|
||||||
|
grab_focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mb->get_button_index() == MouseButton::LEFT) {
|
if (mb->get_button_index() == MouseButton::LEFT) {
|
||||||
@ -2314,15 +2315,7 @@ void TextEdit::_move_caret_to_line_start(bool p_select) {
|
|||||||
}
|
}
|
||||||
if (caret.column == row_start_col || wi == 0) {
|
if (caret.column == row_start_col || wi == 0) {
|
||||||
// Compute whitespace symbols sequence length.
|
// Compute whitespace symbols sequence length.
|
||||||
int current_line_whitespace_len = 0;
|
int current_line_whitespace_len = get_first_non_whitespace_column(caret.line);
|
||||||
while (current_line_whitespace_len < text[caret.line].length()) {
|
|
||||||
char32_t c = text[caret.line][current_line_whitespace_len];
|
|
||||||
if (c != '\t' && c != ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current_line_whitespace_len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_caret_column() == current_line_whitespace_len) {
|
if (get_caret_column() == current_line_whitespace_len) {
|
||||||
set_caret_column(0);
|
set_caret_column(0);
|
||||||
} else {
|
} else {
|
||||||
@ -2460,6 +2453,10 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) {
|
|||||||
int next_column;
|
int next_column;
|
||||||
|
|
||||||
if (p_all_to_right) {
|
if (p_all_to_right) {
|
||||||
|
if (caret.column == curline_len) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete everything to right of caret
|
// Delete everything to right of caret
|
||||||
next_column = curline_len;
|
next_column = curline_len;
|
||||||
next_line = caret.line;
|
next_line = caret.line;
|
||||||
@ -3122,6 +3119,7 @@ void TextEdit::insert_line_at(int p_at, const String &p_text) {
|
|||||||
++selection.to_line;
|
++selection.to_line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEdit::insert_text_at_caret(const String &p_text) {
|
void TextEdit::insert_text_at_caret(const String &p_text) {
|
||||||
@ -3817,7 +3815,7 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_
|
|||||||
|
|
||||||
Point2i TextEdit::get_pos_at_line_column(int p_line, int p_column) const {
|
Point2i TextEdit::get_pos_at_line_column(int p_line, int p_column) const {
|
||||||
Rect2i rect = get_rect_at_line_column(p_line, p_column);
|
Rect2i rect = get_rect_at_line_column(p_line, p_column);
|
||||||
return rect.position + Vector2i(0, get_line_height());
|
return rect.position.x == -1 ? rect.position : rect.position + Vector2i(0, get_line_height());
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect2i TextEdit::get_rect_at_line_column(int p_line, int p_column) const {
|
Rect2i TextEdit::get_rect_at_line_column(int p_line, int p_column) const {
|
||||||
@ -4055,12 +4053,12 @@ void TextEdit::set_caret_column(int p_col, bool p_adjust_viewport) {
|
|||||||
if (p_col < 0) {
|
if (p_col < 0) {
|
||||||
p_col = 0;
|
p_col = 0;
|
||||||
}
|
}
|
||||||
|
if (p_col > get_line(caret.line).length()) {
|
||||||
|
p_col = get_line(caret.line).length();
|
||||||
|
}
|
||||||
|
|
||||||
bool caret_moved = caret.column != p_col;
|
bool caret_moved = caret.column != p_col;
|
||||||
caret.column = p_col;
|
caret.column = p_col;
|
||||||
if (caret.column > get_line(caret.line).length()) {
|
|
||||||
caret.column = get_line(caret.line).length();
|
|
||||||
}
|
|
||||||
|
|
||||||
caret.last_fit_x = _get_column_x_offset_for_line(caret.column, caret.line);
|
caret.last_fit_x = _get_column_x_offset_for_line(caret.column, caret.line);
|
||||||
|
|
||||||
@ -4189,13 +4187,18 @@ void TextEdit::select_word_under_caret() {
|
|||||||
int end = 0;
|
int end = 0;
|
||||||
const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
|
const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
|
||||||
for (int i = 0; i < words.size(); i = i + 2) {
|
for (int i = 0; i < words.size(); i = i + 2) {
|
||||||
if ((words[i] < caret.column && words[i + 1] > caret.column) || (i == words.size() - 2 && caret.column == words[i + 1])) {
|
if ((words[i] <= caret.column && words[i + 1] >= caret.column) || (i == words.size() - 2 && caret.column == words[i + 1])) {
|
||||||
begin = words[i];
|
begin = words[i];
|
||||||
end = words[i + 1];
|
end = words[i + 1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No word found.
|
||||||
|
if (begin == 0 && end == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
select(caret.line, begin, caret.line, end);
|
select(caret.line, begin, caret.line, end);
|
||||||
/* Move the caret to the end of the word for easier editing. */
|
/* Move the caret to the end of the word for easier editing. */
|
||||||
set_caret_column(end, false);
|
set_caret_column(end, false);
|
||||||
@ -4271,10 +4274,12 @@ String TextEdit::get_selected_text() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TextEdit::get_selection_line() const {
|
int TextEdit::get_selection_line() const {
|
||||||
|
ERR_FAIL_COND_V(!selection.active, -1);
|
||||||
return selection.selecting_line;
|
return selection.selecting_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextEdit::get_selection_column() const {
|
int TextEdit::get_selection_column() const {
|
||||||
|
ERR_FAIL_COND_V(!selection.active, -1);
|
||||||
return selection.selecting_column;
|
return selection.selecting_column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4476,9 +4481,13 @@ void TextEdit::set_line_as_center_visible(int p_line, int p_wrap_index) {
|
|||||||
ERR_FAIL_COND(p_wrap_index > get_line_wrap_count(p_line));
|
ERR_FAIL_COND(p_wrap_index > get_line_wrap_count(p_line));
|
||||||
|
|
||||||
int visible_rows = get_visible_line_count();
|
int visible_rows = get_visible_line_count();
|
||||||
Point2i next_line = get_next_visible_line_index_offset_from(p_line, p_wrap_index, -visible_rows / 2);
|
Point2i next_line = get_next_visible_line_index_offset_from(p_line, p_wrap_index, (-visible_rows / 2) - 1);
|
||||||
int first_line = p_line - next_line.x + 1;
|
int first_line = p_line - next_line.x + 1;
|
||||||
|
|
||||||
|
if (first_line < 0) {
|
||||||
|
set_v_scroll(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
set_v_scroll(get_scroll_pos_for_line(first_line, next_line.y));
|
set_v_scroll(get_scroll_pos_for_line(first_line, next_line.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4490,6 +4499,12 @@ void TextEdit::set_line_as_last_visible(int p_line, int p_wrap_index) {
|
|||||||
Point2i next_line = get_next_visible_line_index_offset_from(p_line, p_wrap_index, -get_visible_line_count() - 1);
|
Point2i next_line = get_next_visible_line_index_offset_from(p_line, p_wrap_index, -get_visible_line_count() - 1);
|
||||||
int first_line = p_line - next_line.x + 1;
|
int first_line = p_line - next_line.x + 1;
|
||||||
|
|
||||||
|
// Adding _get_visible_lines_offset is not 100% correct as we end up showing almost p_line + 1, however, it provides a
|
||||||
|
// better user experience. Therefore we need to special case < visible line count, else showing line 0 is impossible.
|
||||||
|
if (get_visible_line_count_in_range(0, p_line) < get_visible_line_count() + 1) {
|
||||||
|
set_v_scroll(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
set_v_scroll(get_scroll_pos_for_line(first_line, next_line.y) + _get_visible_lines_offset());
|
set_v_scroll(get_scroll_pos_for_line(first_line, next_line.y) + _get_visible_lines_offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5899,7 +5914,7 @@ int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line) const {
|
|||||||
int row = 0;
|
int row = 0;
|
||||||
Vector<Vector2i> rows2 = text.get_line_wrap_ranges(p_line);
|
Vector<Vector2i> rows2 = text.get_line_wrap_ranges(p_line);
|
||||||
for (int i = 0; i < rows2.size(); i++) {
|
for (int i = 0; i < rows2.size(); i++) {
|
||||||
if ((p_char >= rows2[i].x) && (p_char < rows2[i].y)) {
|
if ((p_char >= rows2[i].x) && (p_char <= rows2[i].y)) {
|
||||||
row = i;
|
row = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5983,8 +5998,8 @@ void TextEdit::_update_selection_mode_word() {
|
|||||||
selection.selected_word_beg = beg;
|
selection.selected_word_beg = beg;
|
||||||
selection.selected_word_end = end;
|
selection.selected_word_end = end;
|
||||||
selection.selected_word_origin = beg;
|
selection.selected_word_origin = beg;
|
||||||
set_caret_line(selection.to_line, false);
|
set_caret_line(line, false);
|
||||||
set_caret_column(selection.to_column);
|
set_caret_column(end);
|
||||||
} else {
|
} else {
|
||||||
if ((col <= selection.selected_word_origin && line == selection.selecting_line) || line < selection.selecting_line) {
|
if ((col <= selection.selected_word_origin && line == selection.selecting_line) || line < selection.selecting_line) {
|
||||||
selection.selecting_column = selection.selected_word_end;
|
selection.selecting_column = selection.selected_word_end;
|
||||||
@ -6040,6 +6055,10 @@ void TextEdit::_update_selection_mode_line() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextEdit::_pre_shift_selection() {
|
void TextEdit::_pre_shift_selection() {
|
||||||
|
if (!selecting_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!selection.active || selection.selecting_mode == SelectionMode::SELECTION_MODE_NONE) {
|
if (!selection.active || selection.selecting_mode == SelectionMode::SELECTION_MODE_NONE) {
|
||||||
selection.selecting_line = caret.line;
|
selection.selecting_line = caret.line;
|
||||||
selection.selecting_column = caret.column;
|
selection.selecting_column = caret.column;
|
||||||
@ -6050,6 +6069,10 @@ void TextEdit::_pre_shift_selection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextEdit::_post_shift_selection() {
|
void TextEdit::_post_shift_selection() {
|
||||||
|
if (!selecting_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selection.active && selection.selecting_mode == SelectionMode::SELECTION_MODE_SHIFT) {
|
if (selection.active && selection.selecting_mode == SelectionMode::SELECTION_MODE_SHIFT) {
|
||||||
select(selection.selecting_line, selection.selecting_column, caret.line, caret.column);
|
select(selection.selecting_line, selection.selecting_column, caret.line, caret.column);
|
||||||
update();
|
update();
|
||||||
|
@ -40,6 +40,7 @@ namespace TestCodeEdit {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] line gutters") {
|
TEST_CASE("[SceneTree][CodeEdit] line gutters") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
SUBCASE("[CodeEdit] breakpoints") {
|
SUBCASE("[CodeEdit] breakpoints") {
|
||||||
SIGNAL_WATCH(code_edit, "breakpoint_toggled");
|
SIGNAL_WATCH(code_edit, "breakpoint_toggled");
|
||||||
@ -881,6 +882,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] delimiters") {
|
TEST_CASE("[SceneTree][CodeEdit] delimiters") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
const Point2 OUTSIDE_DELIMETER = Point2(-1, -1);
|
const Point2 OUTSIDE_DELIMETER = Point2(-1, -1);
|
||||||
|
|
||||||
@ -1759,6 +1761,7 @@ TEST_CASE("[SceneTree][CodeEdit] delimiters") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] indent") {
|
TEST_CASE("[SceneTree][CodeEdit] indent") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
SUBCASE("[CodeEdit] indent settings") {
|
SUBCASE("[CodeEdit] indent settings") {
|
||||||
code_edit->set_indent_size(10);
|
code_edit->set_indent_size(10);
|
||||||
@ -2288,6 +2291,7 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] folding") {
|
TEST_CASE("[SceneTree][CodeEdit] folding") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
SUBCASE("[CodeEdit] folding settings") {
|
SUBCASE("[CodeEdit] folding settings") {
|
||||||
code_edit->set_line_folding_enabled(true);
|
code_edit->set_line_folding_enabled(true);
|
||||||
@ -2672,6 +2676,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] completion") {
|
TEST_CASE("[SceneTree][CodeEdit] completion") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
SUBCASE("[CodeEdit] auto brace completion") {
|
SUBCASE("[CodeEdit] auto brace completion") {
|
||||||
code_edit->set_auto_brace_completion_enabled(true);
|
code_edit->set_auto_brace_completion_enabled(true);
|
||||||
@ -2991,18 +2996,18 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
|
|||||||
|
|
||||||
Point2 caret_pos = code_edit->get_caret_draw_pos();
|
Point2 caret_pos = code_edit->get_caret_draw_pos();
|
||||||
caret_pos.y -= code_edit->get_line_height();
|
caret_pos.y -= code_edit->get_line_height();
|
||||||
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE);
|
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE, Key::NONE);
|
||||||
CHECK(code_edit->get_code_completion_selected_index() == 1);
|
CHECK(code_edit->get_code_completion_selected_index() == 1);
|
||||||
|
|
||||||
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE);
|
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE, Key::NONE);
|
||||||
CHECK(code_edit->get_code_completion_selected_index() == 0);
|
CHECK(code_edit->get_code_completion_selected_index() == 0);
|
||||||
|
|
||||||
/* Single click selects. */
|
/* Single click selects. */
|
||||||
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT);
|
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE);
|
||||||
CHECK(code_edit->get_code_completion_selected_index() == 2);
|
CHECK(code_edit->get_code_completion_selected_index() == 2);
|
||||||
|
|
||||||
/* Double click inserts. */
|
/* Double click inserts. */
|
||||||
SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos);
|
SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos, Key::NONE);
|
||||||
CHECK(code_edit->get_code_completion_selected_index() == -1);
|
CHECK(code_edit->get_code_completion_selected_index() == -1);
|
||||||
CHECK(code_edit->get_line(0) == "item_2");
|
CHECK(code_edit->get_line(0) == "item_2");
|
||||||
|
|
||||||
@ -3196,6 +3201,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
|
TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
code_edit->set_symbol_lookup_on_click_enabled(true);
|
code_edit->set_symbol_lookup_on_click_enabled(true);
|
||||||
CHECK(code_edit->is_symbol_lookup_on_click_enabled());
|
CHECK(code_edit->is_symbol_lookup_on_click_enabled());
|
||||||
@ -3208,7 +3214,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
|
|||||||
|
|
||||||
Point2 caret_pos = code_edit->get_caret_draw_pos();
|
Point2 caret_pos = code_edit->get_caret_draw_pos();
|
||||||
caret_pos.x += 58;
|
caret_pos.x += 58;
|
||||||
SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE);
|
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE, Key::NONE);
|
||||||
CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
|
CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
|
||||||
|
|
||||||
SIGNAL_WATCH(code_edit, "symbol_validate");
|
SIGNAL_WATCH(code_edit, "symbol_validate");
|
||||||
@ -3234,6 +3240,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
|
TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
TypedArray<int> guide_lines;
|
TypedArray<int> guide_lines;
|
||||||
|
|
||||||
@ -3254,6 +3261,7 @@ TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
|
TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
/* Backspace with selection on first line. */
|
/* Backspace with selection on first line. */
|
||||||
code_edit->set_text("");
|
code_edit->set_text("");
|
||||||
@ -3301,6 +3309,7 @@ TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
|
|||||||
TEST_CASE("[SceneTree][CodeEdit] New Line") {
|
TEST_CASE("[SceneTree][CodeEdit] New Line") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
/* Add a new line. */
|
/* Add a new line. */
|
||||||
code_edit->set_text("");
|
code_edit->set_text("");
|
||||||
|
3507
tests/scene/test_text_edit.h
Normal file
3507
tests/scene/test_text_edit.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -134,8 +134,10 @@ int register_test_command(String p_command, TestFunc p_function);
|
|||||||
// Requires Message Queue and InputMap to be setup.
|
// Requires Message Queue and InputMap to be setup.
|
||||||
// SEND_GUI_ACTION - takes an object and a input map key. e.g SEND_GUI_ACTION(code_edit, "ui_text_newline").
|
// SEND_GUI_ACTION - takes an object and a input map key. e.g SEND_GUI_ACTION(code_edit, "ui_text_newline").
|
||||||
// SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::CMD).
|
// SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::CMD).
|
||||||
// SEND_GUI_MOUSE_EVENT - takes an object, position, mouse button and mouse mask e.g SEND_GUI_MOUSE_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE);
|
// SEND_GUI_MOUSE_BUTTON_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
|
||||||
// SEND_GUI_DOUBLE_CLICK - takes an object and a position. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50));
|
// SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
|
||||||
|
// SEND_GUI_MOUSE_MOTION_EVENT - takes an object, position, mouse mask and modifiers e.g SEND_GUI_MOUSE_MOTION_EVENT(code_edit, Vector2(50, 50), MouseButton::MASK_LEFT, KeyModifierMask::CMD);
|
||||||
|
// SEND_GUI_DOUBLE_CLICK - takes an object, position and modifiers. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50), KeyModifierMask::CMD);
|
||||||
|
|
||||||
#define SEND_GUI_ACTION(m_object, m_action) \
|
#define SEND_GUI_ACTION(m_object, m_action) \
|
||||||
{ \
|
{ \
|
||||||
@ -143,7 +145,7 @@ int register_test_command(String p_command, TestFunc p_function);
|
|||||||
const List<Ref<InputEvent>>::Element *first_event = events->front(); \
|
const List<Ref<InputEvent>>::Element *first_event = events->front(); \
|
||||||
Ref<InputEventKey> event = first_event->get(); \
|
Ref<InputEventKey> event = first_event->get(); \
|
||||||
event->set_pressed(true); \
|
event->set_pressed(true); \
|
||||||
m_object->gui_input(event); \
|
m_object->get_viewport()->push_input(event); \
|
||||||
MessageQueue::get_singleton()->flush(); \
|
MessageQueue::get_singleton()->flush(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,31 +153,64 @@ int register_test_command(String p_command, TestFunc p_function);
|
|||||||
{ \
|
{ \
|
||||||
Ref<InputEventKey> event = InputEventKey::create_reference(m_input); \
|
Ref<InputEventKey> event = InputEventKey::create_reference(m_input); \
|
||||||
event->set_pressed(true); \
|
event->set_pressed(true); \
|
||||||
m_object->gui_input(event); \
|
m_object->get_viewport()->push_input(event); \
|
||||||
MessageQueue::get_singleton()->flush(); \
|
MessageQueue::get_singleton()->flush(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask) \
|
#define _UPDATE_EVENT_MODIFERS(m_event, m_modifers) \
|
||||||
Ref<InputEventMouseButton> event; \
|
m_event->set_shift_pressed(((m_modifers)&KeyModifierMask::SHIFT) != Key::NONE); \
|
||||||
event.instantiate(); \
|
m_event->set_alt_pressed(((m_modifers)&KeyModifierMask::ALT) != Key::NONE); \
|
||||||
event->set_position(m_local_pos); \
|
m_event->set_ctrl_pressed(((m_modifers)&KeyModifierMask::CTRL) != Key::NONE); \
|
||||||
event->set_button_index(m_input); \
|
m_event->set_command_pressed(((m_modifers)&KeyModifierMask::CMD) != Key::NONE); \
|
||||||
event->set_button_mask(m_mask); \
|
m_event->set_meta_pressed(((m_modifers)&KeyModifierMask::META) != Key::NONE);
|
||||||
|
|
||||||
|
#define _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
|
||||||
|
Ref<InputEventMouseButton> event; \
|
||||||
|
event.instantiate(); \
|
||||||
|
event->set_position(m_local_pos); \
|
||||||
|
event->set_button_index(m_input); \
|
||||||
|
event->set_button_mask(m_mask); \
|
||||||
|
event->set_factor(1); \
|
||||||
|
_UPDATE_EVENT_MODIFERS(event, m_modifers); \
|
||||||
event->set_pressed(true);
|
event->set_pressed(true);
|
||||||
|
|
||||||
#define SEND_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask) \
|
#define SEND_GUI_MOUSE_BUTTON_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
|
||||||
{ \
|
{ \
|
||||||
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask); \
|
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers); \
|
||||||
m_object->get_viewport()->push_input(event); \
|
m_object->get_viewport()->push_input(event); \
|
||||||
MessageQueue::get_singleton()->flush(); \
|
MessageQueue::get_singleton()->flush(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos) \
|
#define SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers) \
|
||||||
{ \
|
{ \
|
||||||
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, MouseButton::LEFT); \
|
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, m_input, m_mask, m_modifers); \
|
||||||
event->set_double_click(true); \
|
event->set_pressed(false); \
|
||||||
m_object->get_viewport()->push_input(event); \
|
m_object->get_viewport()->push_input(event); \
|
||||||
MessageQueue::get_singleton()->flush(); \
|
MessageQueue::get_singleton()->flush(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos, m_modifers) \
|
||||||
|
{ \
|
||||||
|
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, MouseButton::LEFT, m_modifers); \
|
||||||
|
event->set_double_click(true); \
|
||||||
|
m_object->get_viewport()->push_input(event); \
|
||||||
|
MessageQueue::get_singleton()->flush(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// We toogle _print_error_enabled to prevent display server not supported warnings.
|
||||||
|
#define SEND_GUI_MOUSE_MOTION_EVENT(m_object, m_local_pos, m_mask, m_modifers) \
|
||||||
|
{ \
|
||||||
|
bool errors_enabled = _print_error_enabled; \
|
||||||
|
_print_error_enabled = false; \
|
||||||
|
Ref<InputEventMouseMotion> event; \
|
||||||
|
event.instantiate(); \
|
||||||
|
event->set_position(m_local_pos); \
|
||||||
|
event->set_button_mask(m_mask); \
|
||||||
|
event->set_relative(Vector2(10, 10)); \
|
||||||
|
_UPDATE_EVENT_MODIFERS(event, m_modifers); \
|
||||||
|
m_object->get_viewport()->push_input(event); \
|
||||||
|
MessageQueue::get_singleton()->flush(); \
|
||||||
|
_print_error_enabled = errors_enabled; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility class / macros for testing signals
|
// Utility class / macros for testing signals
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
#include "tests/scene/test_curve.h"
|
#include "tests/scene/test_curve.h"
|
||||||
#include "tests/scene/test_gradient.h"
|
#include "tests/scene/test_gradient.h"
|
||||||
#include "tests/scene/test_path_3d.h"
|
#include "tests/scene/test_path_3d.h"
|
||||||
|
#include "tests/scene/test_text_edit.h"
|
||||||
#include "tests/servers/test_text_server.h"
|
#include "tests/servers/test_text_server.h"
|
||||||
#include "tests/test_validate_testing.h"
|
#include "tests/test_validate_testing.h"
|
||||||
|
|
||||||
@ -175,6 +176,8 @@ struct GodotTestCaseListener : public doctest::IReporter {
|
|||||||
|
|
||||||
GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
|
GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
|
||||||
|
|
||||||
|
memnew(Input);
|
||||||
|
|
||||||
Error err = OK;
|
Error err = OK;
|
||||||
OS::get_singleton()->set_has_server_feature_callback(nullptr);
|
OS::get_singleton()->set_has_server_feature_callback(nullptr);
|
||||||
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
|
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
|
||||||
@ -244,6 +247,10 @@ struct GodotTestCaseListener : public doctest::IReporter {
|
|||||||
physics_2d_server = nullptr;
|
physics_2d_server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Input::get_singleton()) {
|
||||||
|
memdelete(Input::get_singleton());
|
||||||
|
}
|
||||||
|
|
||||||
if (RenderingServer::get_singleton()) {
|
if (RenderingServer::get_singleton()) {
|
||||||
RenderingServer::get_singleton()->sync();
|
RenderingServer::get_singleton()->sync();
|
||||||
RenderingServer::get_singleton()->global_variables_clear();
|
RenderingServer::get_singleton()->global_variables_clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user