summaryrefslogtreecommitdiff
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.cpp73
1 files changed, 47 insertions, 26 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 7bfcd0843c..09fbb39866 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -549,16 +549,17 @@ void TextEdit::_notification(int p_what) {
MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit");
if (text_changed_dirty)
MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
- update_wrap_at();
+ _update_wrap_at();
} break;
case NOTIFICATION_RESIZED: {
_update_scrollbars();
- update_wrap_at();
+ call_deferred("_update_wrap_at");
} break;
case NOTIFICATION_THEME_CHANGED: {
_update_caches();
+ _update_wrap_at();
} break;
case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
window_has_focus = true;
@@ -802,6 +803,7 @@ void TextEdit::_notification(int p_what) {
}
Point2 cursor_pos;
+ int cursor_insert_offset_y = 0;
// get the highlighted words
String highlighted_text = get_selection_text();
@@ -846,9 +848,9 @@ void TextEdit::_notification(int p_what) {
bool underlined = false;
+ Vector<String> wrap_rows = get_wrap_rows_text(line);
int line_wrap_amount = times_line_wraps(line);
int last_wrap_column = 0;
- Vector<String> wrap_rows = get_wrap_rows_text(line);
for (int line_wrap_index = 0; line_wrap_index < line_wrap_amount + 1; line_wrap_index++) {
if (line_wrap_index != 0) {
@@ -1108,9 +1110,11 @@ void TextEdit::_notification(int p_what) {
if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) {
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
+ cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
if (insert_mode) {
- cursor_pos.y += (get_row_height() - 3);
+ cursor_insert_offset_y = (cache.font->get_height() - 3);
+ cursor_pos.y += cursor_insert_offset_y;
}
int caret_w = (str[j] == '\t') ? cache.font->get_char_size(' ').width : char_w;
@@ -1155,7 +1159,8 @@ void TextEdit::_notification(int p_what) {
#else
caret_w = (block_caret) ? caret_w : 2;
#endif
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
+
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color);
}
}
}
@@ -1198,9 +1203,11 @@ void TextEdit::_notification(int p_what) {
if (cursor.column == last_wrap_column + str.length() && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) {
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
+ cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
if (insert_mode) {
- cursor_pos.y += (get_row_height() - 3);
+ cursor_insert_offset_y = cache.font->get_height() - 3;
+ cursor_pos.y += cursor_insert_offset_y;
}
if (ime_text.length() > 0) {
int ofs = 0;
@@ -1245,7 +1252,8 @@ void TextEdit::_notification(int p_what) {
#else
int caret_w = (block_caret) ? char_w : 2;
#endif
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
+
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color);
}
}
}
@@ -1287,9 +1295,9 @@ void TextEdit::_notification(int p_what) {
int th = h + csb->get_minimum_size().y;
if (cursor_pos.y + get_row_height() + th > get_size().height) {
- completion_rect.position.y = cursor_pos.y - th;
+ completion_rect.position.y = cursor_pos.y - th - (cache.line_spacing / 2.0f) - cursor_insert_offset_y;
} else {
- completion_rect.position.y = cursor_pos.y + get_row_height() + csb->get_offset().y;
+ completion_rect.position.y = cursor_pos.y + cache.font->get_height() + (cache.line_spacing / 2.0f) + csb->get_offset().y - cursor_insert_offset_y;
completion_below = true;
}
@@ -1323,7 +1331,8 @@ void TextEdit::_notification(int p_what) {
text_color = color_regions[j].color;
}
}
- draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent()), completion_options[l], text_color, completion_rect.size.width);
+ int yofs = (get_row_height() - cache.font->get_height()) / 2;
+ draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs), completion_options[l], text_color, completion_rect.size.width);
}
if (scrollw) {
@@ -1412,7 +1421,6 @@ void TextEdit::_notification(int p_what) {
if (has_focus()) {
OS::get_singleton()->set_ime_active(true);
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
- OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
}
} break;
@@ -1425,7 +1433,6 @@ void TextEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_active(true);
Point2 cursor_pos = Point2(cursor_get_column(), cursor_get_line()) * get_row_height();
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
- OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(), get_global_rect());
@@ -1433,7 +1440,6 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_FOCUS_EXIT: {
OS::get_singleton()->set_ime_position(Point2());
- OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL);
OS::get_singleton()->set_ime_active(false);
ime_text = "";
ime_selection = Point2();
@@ -1441,14 +1447,15 @@ void TextEdit::_notification(int p_what) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
} break;
- }
-}
+ case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
-void TextEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
- TextEdit *self = (TextEdit *)p_self;
- self->ime_text = p_text;
- self->ime_selection = p_selection;
- self->update();
+ if (has_focus()) {
+ ime_text = OS::get_singleton()->get_ime_text();
+ ime_selection = OS::get_singleton()->get_ime_selection();
+ update();
+ }
+ } break;
+ }
}
void TextEdit::_consume_pair_symbol(CharType ch) {
@@ -3254,7 +3261,6 @@ void TextEdit::_scroll_down(real_t p_delta) {
int max_v_scroll = round(v_scroll->get_max() - v_scroll->get_page());
if (target_v_scroll > max_v_scroll) {
target_v_scroll = max_v_scroll;
- v_scroll->set_value(target_v_scroll);
}
if (Math::abs(target_v_scroll - v_scroll->get_value()) < 1.0) {
v_scroll->set_value(target_v_scroll);
@@ -3639,7 +3645,7 @@ int TextEdit::get_total_visible_rows() const {
return total_rows;
}
-void TextEdit::update_wrap_at() {
+void TextEdit::_update_wrap_at() {
wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - wrap_right_offset;
update_cursor_wrap_offset();
@@ -3805,7 +3811,6 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
if (indent_ofs + word_px > wrap_at) {
// not enough space; add it anyway
wrap_substring += word_str;
- px += word_px;
word_str = "";
word_px = 0;
}
@@ -3820,6 +3825,10 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
// line ends before hit wrap_at; add this word to the substring
wrap_substring += word_str;
lines.push_back(wrap_substring);
+
+ // update cache
+ text.set_line_wrap_amount(p_line, lines.size() - 1);
+
return lines;
}
@@ -4264,6 +4273,7 @@ void TextEdit::_clear() {
cursor.line_ofs = 0;
cursor.wrap_ofs = 0;
cursor.last_fit_x = 0;
+ selection.active = false;
}
void TextEdit::clear() {
@@ -5757,6 +5767,7 @@ void TextEdit::_update_completion_candidates() {
completion_base = s;
Vector<float> sim_cache;
bool single_quote = s.begins_with("'");
+ Vector<String> completion_options_casei;
for (int i = 0; i < completion_strings.size(); i++) {
if (single_quote && completion_strings[i].is_quoted()) {
@@ -5765,9 +5776,13 @@ void TextEdit::_update_completion_candidates() {
if (completion_strings[i].begins_with(s)) {
completion_options.push_back(completion_strings[i]);
+ } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) {
+ completion_options_casei.push_back(completion_strings[i]);
}
}
+ completion_options.append_array(completion_options_casei);
+
if (completion_options.size() == 0) {
for (int i = 0; i < completion_strings.size(); i++) {
if (s.is_subsequence_of(completion_strings[i])) {
@@ -6039,7 +6054,10 @@ void TextEdit::menu_option(int p_option) {
case MENU_UNDO: {
undo();
} break;
- };
+ case MENU_REDO: {
+ redo();
+ }
+ }
}
void TextEdit::set_select_identifiers_on_hover(bool p_enable) {
@@ -6074,6 +6092,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_click_selection_held"), &TextEdit::_click_selection_held);
ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &TextEdit::_toggle_draw_caret);
ClassDB::bind_method(D_METHOD("_v_scroll_input"), &TextEdit::_v_scroll_input);
+ ClassDB::bind_method(D_METHOD("_update_wrap_at"), &TextEdit::_update_wrap_at);
BIND_ENUM_CONSTANT(SEARCH_MATCH_CASE);
BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS);
@@ -6215,6 +6234,7 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_CLEAR);
BIND_ENUM_CONSTANT(MENU_SELECT_ALL);
BIND_ENUM_CONSTANT(MENU_UNDO);
+ BIND_ENUM_CONSTANT(MENU_REDO);
BIND_ENUM_CONSTANT(MENU_MAX);
GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3);
@@ -6343,6 +6363,7 @@ TextEdit::TextEdit() {
menu->add_item(RTR("Clear"), MENU_CLEAR);
menu->add_separator();
menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
menu->connect("id_pressed", this, "menu_option");
}