summaryrefslogtreecommitdiffstats
path: root/scene/gui/text_edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r--scene/gui/text_edit.cpp229
1 files changed, 124 insertions, 105 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5817f70343..79a5f2b557 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -33,7 +33,6 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
#include "core/input/input_map.h"
-#include "core/object/message_queue.h"
#include "core/object/script_language.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -230,7 +229,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
}
text.write[p_line].height = height;
- // If this line has shrunk, this may no longer the the tallest line.
+ // If this line has shrunk, this may no longer the tallest line.
if (old_height == line_height && height < line_height) {
_calculate_line_height();
} else {
@@ -242,7 +241,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
int line_width = get_line_width(p_line);
text.write[p_line].width = line_width;
- // If this line has shrunk, this may no longer the the longest line.
+ // If this line has shrunk, this may no longer the longest line.
if (old_width == max_width && line_width < max_width) {
_calculate_max_line_width();
} else if (!is_hidden(p_line)) {
@@ -428,10 +427,10 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
_update_caches();
if (caret_pos_dirty) {
- MessageQueue::get_singleton()->push_call(this, "_emit_caret_changed");
+ callable_mp(this, &TextEdit::_emit_caret_changed).call_deferred();
}
if (text_changed_dirty) {
- MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ callable_mp(this, &TextEdit::_text_changed_emit).call_deferred();
}
_update_wrap_at_column(true);
} break;
@@ -443,8 +442,8 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
- call_deferred(SNAME("_update_scrollbars"));
- call_deferred(SNAME("_update_wrap_at_column"));
+ callable_mp(this, &TextEdit::_update_scrollbars).call_deferred();
+ callable_mp(this, &TextEdit::_update_wrap_at_column).call_deferred(false);
}
} break;
@@ -732,7 +731,7 @@ void TextEdit::_notification(int p_what) {
// Draw the minimap.
- // Add visual feedback when dragging or hovering the the visible area rectangle.
+ // Add visual feedback when dragging or hovering the visible area rectangle.
float viewport_alpha;
if (dragging_minimap) {
viewport_alpha = 0.25;
@@ -989,18 +988,6 @@ void TextEdit::_notification(int p_what) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
}
}
-
- // Give visual indication of empty selected line.
- for (int c = 0; c < carets.size(); c++) {
- if (has_selection(c) && line >= get_selection_from_line(c) && line <= get_selection_to_line(c) && char_margin >= xmargin_beg) {
- float char_w = theme_cache.font->get_char_size(' ', theme_cache.font_size).width;
- if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), theme_cache.selection_color);
- } else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, char_w, row_height), theme_cache.selection_color);
- }
- }
- }
} else {
// If it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
if (caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index) && highlight_current_line) {
@@ -1093,13 +1080,26 @@ void TextEdit::_notification(int p_what) {
char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
}
+ // Draw selections.
+ float char_w = theme_cache.font->get_char_size(' ', theme_cache.font_size).width;
for (int c = 0; c < carets.size(); c++) {
- if (!clipped && has_selection(c) && line >= get_selection_from_line(c) && line <= get_selection_to_line(c)) { // Selection
+ if (!clipped && has_selection(c) && line >= get_selection_from_line(c) && line <= get_selection_to_line(c)) {
int sel_from = (line > get_selection_from_line(c)) ? TS->shaped_text_get_range(rid).x : get_selection_from_column(c);
int sel_to = (line < get_selection_to_line(c)) ? TS->shaped_text_get_range(rid).y : get_selection_to_column(c);
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to);
+
+ // Show selection at the end of line.
+ if (line < get_selection_to_line(c)) {
+ if (rtl) {
+ sel.push_back(Vector2(-char_w, 0));
+ } else {
+ float line_end = TS->shaped_text_get_size(rid).width;
+ sel.push_back(Vector2(line_end, line_end + char_w));
+ }
+ }
+
for (int j = 0; j < sel.size(); j++) {
- Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
+ Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, Math::ceil(sel[j].y - sel[j].x), row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
continue;
}
@@ -1489,14 +1489,7 @@ void TextEdit::_notification(int p_what) {
}
if (has_focus()) {
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
- DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- Point2 pos = get_global_position() + get_caret_draw_pos();
- if (get_window()->get_embedder()) {
- pos += get_viewport()->get_popup_base_transform().get_origin();
- }
- DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
- }
+ _update_ime_window_position();
}
} break;
@@ -1507,14 +1500,7 @@ void TextEdit::_notification(int p_what) {
draw_caret = true;
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
- DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- Point2 pos = get_global_position() + get_caret_draw_pos();
- if (get_window()->get_embedder()) {
- pos += get_viewport()->get_popup_base_transform().get_origin();
- }
- DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
- }
+ _update_ime_window_position();
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
int caret_start = -1;
@@ -1541,17 +1527,7 @@ void TextEdit::_notification(int p_what) {
caret_blink_timer->stop();
}
- if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
- DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
- DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
- }
- if (!ime_text.is_empty()) {
- ime_text = "";
- ime_selection = Point2();
- for (int i = 0; i < carets.size(); i++) {
- text.invalidate_cache(get_caret_line(i), get_caret_column(i), true, ime_text);
- }
- }
+ apply_ime();
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
@@ -1571,15 +1547,8 @@ void TextEdit::_notification(int p_what) {
delete_selection();
}
- for (int i = 0; i < carets.size(); i++) {
- String t;
- if (get_caret_column(i) >= 0) {
- t = text[get_caret_line(i)].substr(0, get_caret_column(i)) + ime_text + text[get_caret_line(i)].substr(get_caret_column(i), text[get_caret_line(i)].length());
- } else {
- t = ime_text;
- }
- text.invalidate_cache(get_caret_line(i), get_caret_column(i), true, t, structured_text_parser(st_parser, st_args, t));
- }
+ _update_ime_text();
+ adjust_viewport_to_caret(0);
queue_redraw();
}
} break;
@@ -1681,10 +1650,6 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (is_layout_rtl()) {
mpos.x = get_size().x - mpos.x;
}
- if (ime_text.length() != 0) {
- // Ignore mouse clicks in IME input mode.
- return;
- }
if (mb->is_pressed()) {
if (mb->get_button_index() == MouseButton::WHEEL_UP && !mb->is_command_or_control_pressed()) {
@@ -1718,6 +1683,8 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (mb->get_button_index() == MouseButton::LEFT) {
_reset_caret_blink_timer();
+ apply_ime();
+
Point2i pos = get_line_column_at_pos(mpos);
int row = pos.y;
int col = pos.x;
@@ -1865,11 +1832,13 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (is_middle_mouse_paste_enabled() && mb->get_button_index() == MouseButton::MIDDLE && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CLIPBOARD_PRIMARY)) {
+ apply_ime();
paste_primary_clipboard();
}
if (mb->get_button_index() == MouseButton::RIGHT && (context_menu_enabled || is_move_caret_on_right_click_enabled())) {
_reset_caret_blink_timer();
+ apply_ime();
Point2i pos = get_line_column_at_pos(mpos);
int row = pos.y;
@@ -1909,6 +1878,11 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
} else {
+ if (has_ime_text()) {
+ // Ignore mouse up in IME input mode.
+ return;
+ }
+
if (mb->get_button_index() == MouseButton::LEFT) {
if (selection_drag_attempt && is_mouse_over_selection()) {
remove_secondary_carets();
@@ -1967,7 +1941,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
_update_minimap_drag();
}
- if (!dragging_minimap) {
+ if (!dragging_minimap && !has_ime_text()) {
switch (selecting_mode) {
case SelectionMode::SELECTION_MODE_POINTER: {
_update_selection_mode_pointer();
@@ -2012,6 +1986,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (drag_action && can_drop_data(mpos, get_viewport()->gui_get_drag_data())) {
+ apply_ime();
drag_caret_force_displayed = true;
Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
set_caret_line(pos.y, false, true, 0, 0);
@@ -3030,6 +3005,43 @@ void TextEdit::_update_caches() {
}
}
+void TextEdit::_close_ime_window() {
+ if (get_viewport()->get_window_id() == DisplayServer::INVALID_WINDOW_ID || !DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
+ return;
+ }
+ DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
+ DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
+}
+
+void TextEdit::_update_ime_window_position() {
+ if (get_viewport()->get_window_id() == DisplayServer::INVALID_WINDOW_ID || !DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
+ return;
+ }
+ DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
+ Point2 pos = get_global_position() + get_caret_draw_pos();
+ if (get_window()->get_embedder()) {
+ pos += get_viewport()->get_popup_base_transform().get_origin();
+ }
+ // The window will move to the updated position the next time the IME is updated, not immediately.
+ DisplayServer::get_singleton()->window_set_ime_position(pos, get_viewport()->get_window_id());
+}
+
+void TextEdit::_update_ime_text() {
+ if (has_ime_text()) {
+ // Update text to visually include IME text.
+ for (int i = 0; i < get_caret_count(); i++) {
+ String text_with_ime = text[get_caret_line(i)].substr(0, get_caret_column(i)) + ime_text + text[get_caret_line(i)].substr(get_caret_column(i), text[get_caret_line(i)].length());
+ text.invalidate_cache(get_caret_line(i), get_caret_column(i), true, text_with_ime, structured_text_parser(st_parser, st_args, text_with_ime));
+ }
+ } else {
+ // Reset text.
+ for (int i = 0; i < get_caret_count(); i++) {
+ text.invalidate_cache(get_caret_line(i), get_caret_column(i), true);
+ }
+ }
+ queue_redraw();
+}
+
/* General overrides. */
Size2 TextEdit::get_minimum_size() const {
Size2 size = theme_cache.style_normal->get_minimum_size();
@@ -3189,6 +3201,26 @@ bool TextEdit::has_ime_text() const {
return !ime_text.is_empty();
}
+void TextEdit::cancel_ime() {
+ if (!has_ime_text()) {
+ return;
+ }
+ ime_text = String();
+ ime_selection = Point2();
+ _close_ime_window();
+ _update_ime_text();
+}
+
+void TextEdit::apply_ime() {
+ if (!has_ime_text()) {
+ return;
+ }
+ // Force apply the current IME text.
+ String insert_ime_text = ime_text;
+ cancel_ime();
+ insert_text_at_caret(insert_ime_text);
+}
+
void TextEdit::set_editable(const bool p_editable) {
if (editable == p_editable) {
return;
@@ -3568,16 +3600,8 @@ void TextEdit::insert_text_at_caret(const String &p_text, int p_caret) {
adjust_carets_after_edit(i, new_line, new_column, from_line, from_col);
}
- if (!ime_text.is_empty()) {
- for (int i = 0; i < carets.size(); i++) {
- String t;
- if (get_caret_column(i) >= 0) {
- t = text[get_caret_line(i)].substr(0, get_caret_column(i)) + ime_text + text[get_caret_line(i)].substr(get_caret_column(i), text[get_caret_line(i)].length());
- } else {
- t = ime_text;
- }
- text.invalidate_cache(get_caret_line(i), get_caret_column(i), true, t, structured_text_parser(st_parser, st_args, t));
- }
+ if (has_ime_text()) {
+ _update_ime_text();
}
end_complex_operation();
@@ -3927,7 +3951,7 @@ void TextEdit::end_complex_operation() {
if (complex_operation_count > 0) {
return;
}
- ERR_FAIL_COND(undo_stack.size() == 0);
+ ERR_FAIL_COND(undo_stack.is_empty());
undo_stack.back()->get().end_carets = carets;
if (undo_stack.back()->get().chain_forward) {
@@ -4007,7 +4031,7 @@ void TextEdit::undo() {
if (dirty_carets && !caret_pos_dirty) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_emit_caret_changed");
+ callable_mp(this, &TextEdit::_emit_caret_changed).call_deferred();
}
caret_pos_dirty = true;
}
@@ -4062,7 +4086,7 @@ void TextEdit::redo() {
if (dirty_carets && !caret_pos_dirty) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_emit_caret_changed");
+ callable_mp(this, &TextEdit::_emit_caret_changed).call_deferred();
}
caret_pos_dirty = true;
}
@@ -4868,7 +4892,7 @@ void TextEdit::set_caret_line(int p_line, bool p_adjust_viewport, bool p_can_be_
if (caret_moved && !caret_pos_dirty) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_emit_caret_changed");
+ callable_mp(this, &TextEdit::_emit_caret_changed).call_deferred();
}
caret_pos_dirty = true;
}
@@ -4899,7 +4923,7 @@ void TextEdit::set_caret_column(int p_col, bool p_adjust_viewport, int p_caret)
if (caret_moved && !caret_pos_dirty) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_emit_caret_changed");
+ callable_mp(this, &TextEdit::_emit_caret_changed).call_deferred();
}
caret_pos_dirty = true;
}
@@ -5314,8 +5338,7 @@ int TextEdit::get_line_wrap_index_at_column(int p_line, int p_column) const {
Vector<String> lines = get_line_wrapped_text(p_line);
for (int i = 0; i < lines.size(); i++) {
wrap_index = i;
- String s = lines[wrap_index];
- col += s.length();
+ col += lines[wrap_index].length();
if (col > p_column) {
break;
}
@@ -5561,14 +5584,14 @@ void TextEdit::adjust_viewport_to_caret(int p_caret) {
Vector2i caret_pos;
// Get position of the start of caret.
- if (ime_text.length() != 0 && ime_selection.x != 0) {
+ if (has_ime_text() && ime_selection.x != 0) {
caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x, get_caret_line(p_caret), get_caret_column(p_caret));
} else {
caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret), get_caret_line(p_caret), get_caret_column(p_caret));
}
// Get position of the end of caret.
- if (ime_text.length() != 0) {
+ if (has_ime_text()) {
if (ime_selection.y != 0) {
caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret));
} else {
@@ -5613,14 +5636,14 @@ void TextEdit::center_viewport_to_caret(int p_caret) {
Vector2i caret_pos;
// Get position of the start of caret.
- if (ime_text.length() != 0 && ime_selection.x != 0) {
+ if (has_ime_text() && ime_selection.x != 0) {
caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x, get_caret_line(p_caret), get_caret_column(p_caret));
} else {
caret_pos.x = _get_column_x_offset_for_line(get_caret_column(p_caret), get_caret_line(p_caret), get_caret_column(p_caret));
}
// Get position of the end of caret.
- if (ime_text.length() != 0) {
+ if (has_ime_text()) {
if (ime_selection.y != 0) {
caret_pos.y = _get_column_x_offset_for_line(get_caret_column(p_caret) + ime_selection.x + ime_selection.y, get_caret_line(p_caret), get_caret_column(p_caret));
} else {
@@ -6027,13 +6050,11 @@ Color TextEdit::get_font_color() const {
}
void TextEdit::_bind_methods() {
- /* Internal. */
-
- ClassDB::bind_method(D_METHOD("_text_changed_emit"), &TextEdit::_text_changed_emit);
-
/* Text */
// Text properties
ClassDB::bind_method(D_METHOD("has_ime_text"), &TextEdit::has_ime_text);
+ ClassDB::bind_method(D_METHOD("cancel_ime"), &TextEdit::cancel_ime);
+ ClassDB::bind_method(D_METHOD("apply_ime"), &TextEdit::apply_ime);
ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &TextEdit::set_editable);
ClassDB::bind_method(D_METHOD("is_editable"), &TextEdit::is_editable);
@@ -6201,9 +6222,6 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(CARET_TYPE_LINE);
BIND_ENUM_CONSTANT(CARET_TYPE_BLOCK);
- // Internal.
- ClassDB::bind_method(D_METHOD("_emit_caret_changed"), &TextEdit::_emit_caret_changed);
-
ClassDB::bind_method(D_METHOD("set_caret_type", "type"), &TextEdit::set_caret_type);
ClassDB::bind_method(D_METHOD("get_caret_type"), &TextEdit::get_caret_type);
@@ -6291,9 +6309,6 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(LINE_WRAPPING_NONE);
BIND_ENUM_CONSTANT(LINE_WRAPPING_BOUNDARY);
- // Internal.
- ClassDB::bind_method(D_METHOD("_update_wrap_at_column", "force"), &TextEdit::_update_wrap_at_column, DEFVAL(false));
-
ClassDB::bind_method(D_METHOD("set_line_wrapping_mode", "mode"), &TextEdit::set_line_wrapping_mode);
ClassDB::bind_method(D_METHOD("get_line_wrapping_mode"), &TextEdit::get_line_wrapping_mode);
@@ -6858,15 +6873,12 @@ void TextEdit::_generate_context_menu() {
add_child(menu, false, INTERNAL_MODE_FRONT);
menu_dir = memnew(PopupMenu);
- menu_dir->set_name("DirMenu");
menu_dir->add_radio_check_item(RTR("Same as Layout Direction"), MENU_DIR_INHERITED);
menu_dir->add_radio_check_item(RTR("Auto-Detect Direction"), MENU_DIR_AUTO);
menu_dir->add_radio_check_item(RTR("Left-to-Right"), MENU_DIR_LTR);
menu_dir->add_radio_check_item(RTR("Right-to-Left"), MENU_DIR_RTL);
- menu->add_child(menu_dir, false, INTERNAL_MODE_FRONT);
menu_ctl = memnew(PopupMenu);
- menu_ctl->set_name("CTLMenu");
menu_ctl->add_item(RTR("Left-to-Right Mark (LRM)"), MENU_INSERT_LRM);
menu_ctl->add_item(RTR("Right-to-Left Mark (RLM)"), MENU_INSERT_RLM);
menu_ctl->add_item(RTR("Start of Left-to-Right Embedding (LRE)"), MENU_INSERT_LRE);
@@ -6885,7 +6897,6 @@ void TextEdit::_generate_context_menu() {
menu_ctl->add_item(RTR("Zero-Width Non-Joiner (ZWNJ)"), MENU_INSERT_ZWNJ);
menu_ctl->add_item(RTR("Word Joiner (WJ)"), MENU_INSERT_WJ);
menu_ctl->add_item(RTR("Soft Hyphen (SHY)"), MENU_INSERT_SHY);
- menu->add_child(menu_ctl, false, INTERNAL_MODE_FRONT);
menu->add_item(RTR("Cut"), MENU_CUT);
menu->add_item(RTR("Copy"), MENU_COPY);
@@ -6897,10 +6908,10 @@ void TextEdit::_generate_context_menu() {
menu->add_item(RTR("Undo"), MENU_UNDO);
menu->add_item(RTR("Redo"), MENU_REDO);
menu->add_separator();
- menu->add_submenu_item(RTR("Text Writing Direction"), "DirMenu", MENU_SUBMENU_TEXT_DIR);
+ menu->add_submenu_node_item(RTR("Text Writing Direction"), menu_dir, MENU_SUBMENU_TEXT_DIR);
menu->add_separator();
menu->add_check_item(RTR("Display Control Characters"), MENU_DISPLAY_UCC);
- menu->add_submenu_item(RTR("Insert Control Character"), "CTLMenu", MENU_SUBMENU_INSERT_UCC);
+ menu->add_submenu_node_item(RTR("Insert Control Character"), menu_ctl, MENU_SUBMENU_INSERT_UCC);
menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
@@ -7344,7 +7355,7 @@ void TextEdit::_update_scrollbars() {
int visible_rows = get_visible_line_count();
int total_rows = draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_total_visible_line_count();
- if (scroll_past_end_of_file_enabled) {
+ if (scroll_past_end_of_file_enabled && !fit_content_height) {
total_rows += visible_rows - 1;
}
@@ -7691,7 +7702,11 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
op.version = ++version;
op.chain_forward = false;
op.chain_backward = false;
- op.start_carets = carets;
+ if (next_operation_is_complex) {
+ op.start_carets = current_op.start_carets;
+ } else {
+ op.start_carets = carets;
+ }
op.end_carets = carets;
// See if it should just be set as current op.
@@ -7746,7 +7761,11 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
op.version = ++version;
op.chain_forward = false;
op.chain_backward = false;
- op.start_carets = carets;
+ if (next_operation_is_complex) {
+ op.start_carets = current_op.start_carets;
+ } else {
+ op.start_carets = carets;
+ }
op.end_carets = carets;
// See if it should just be set as current op.
@@ -7819,7 +7838,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ callable_mp(this, &TextEdit::_text_changed_emit).call_deferred();
}
text_changed_dirty = true;
}
@@ -7865,7 +7884,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree()) {
- MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ callable_mp(this, &TextEdit::_text_changed_emit).call_deferred();
}
text_changed_dirty = true;
}