diff options
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r-- | scene/gui/text_edit.cpp | 173 |
1 files changed, 118 insertions, 55 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a22ddb265b..c818633f48 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -161,57 +161,58 @@ void TextEdit::Text::_update_line_cache(int p_line) const { /* BEGIN */ int lr = cr.begin_key.length(); - if (lr == 0 || lr > left) - continue; + const CharType *kc; + bool match; - const CharType *kc = cr.begin_key.c_str(); + if (lr != 0 && lr <= left) { + kc = cr.begin_key.c_str(); - bool match = true; + match = true; - for (int k = 0; k < lr; k++) { - if (kc[k] != str[i + k]) { - match = false; - break; + for (int k = 0; k < lr; k++) { + if (kc[k] != str[i + k]) { + match = false; + break; + } } - } - if (match) { + if (match) { - ColorRegionInfo cri; - cri.end = false; - cri.region = j; - text.write[p_line].region_info[i] = cri; - i += lr - 1; + ColorRegionInfo cri; + cri.end = false; + cri.region = j; + text.write[p_line].region_info[i] = cri; + i += lr - 1; - break; + break; + } } /* END */ lr = cr.end_key.length(); - if (lr == 0 || lr > left) - continue; - - kc = cr.end_key.c_str(); + if (lr != 0 && lr <= left) { + kc = cr.end_key.c_str(); - match = true; + match = true; - for (int k = 0; k < lr; k++) { - if (kc[k] != str[i + k]) { - match = false; - break; + for (int k = 0; k < lr; k++) { + if (kc[k] != str[i + k]) { + match = false; + break; + } } - } - if (match) { + if (match) { - ColorRegionInfo cri; - cri.end = true; - cri.region = j; - text.write[p_line].region_info[i] = cri; - i += lr - 1; + ColorRegionInfo cri; + cri.end = true; + cri.region = j; + text.write[p_line].region_info[i] = cri; + i += lr - 1; - break; + break; + } } } } @@ -268,6 +269,12 @@ void TextEdit::Text::clear_wrap_cache() { } } +void TextEdit::Text::clear_info_icons() { + for (int i = 0; i < text.size(); i++) { + text.write[i].has_info = false; + } +} + void TextEdit::Text::clear() { text.clear(); @@ -302,6 +309,7 @@ void TextEdit::Text::insert(int p_at, const String &p_text) { line.breakpoint = false; line.bookmark = false; line.hidden = false; + line.has_info = false; line.width_cache = -1; line.wrap_amount_cache = -1; line.data = p_text; @@ -935,7 +943,7 @@ void TextEdit::_notification(int p_what) { int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line; if (minimap_line >= 0) { minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi); - minimap_line -= (smooth_scroll_enabled ? 1 : 0); + minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0); } int minimap_draw_amount = minimap_visible_lines + times_line_wraps(minimap_line + 1); @@ -957,6 +965,10 @@ void TextEdit::_notification(int p_what) { } } + if (minimap_line < 0 || minimap_line >= (int)text.size()) { + break; + } + Map<int, HighlighterInfo> color_map; if (syntax_coloring) { color_map = _get_line_syntax_highlighting(minimap_line); @@ -1723,7 +1735,9 @@ void TextEdit::_notification(int p_what) { end = font->get_string_size(l.substr(0, l.rfind(String::chr(0xFFFF)))).x; } - draw_string(font, hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent() + font->get_height() * i + spacing), l.replace(String::chr(0xFFFF), ""), font_color); + Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent() + font->get_height() * i + spacing); + round_ofs = round_ofs.round(); + draw_string(font, round_ofs, l.replace(String::chr(0xFFFF), ""), font_color); if (end > 0) { Vector2 b = hint_ofs + sb->get_offset() + Vector2(begin, font->get_height() + font->get_height() * i + spacing - 1); draw_line(b, b + Vector2(end - begin, 0), font_color); @@ -2146,7 +2160,7 @@ void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line; if (first_visible_line > 0 && minimap_line >= 0) { minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi); - minimap_line -= (smooth_scroll_enabled ? 1 : 0); + minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0); } else { minimap_line = 0; } @@ -2843,19 +2857,51 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { // No need to indent if we are going upwards. if (auto_indent && !(k->get_command() && k->get_shift())) { - // Indent once again if previous line will end with ':' or '{' and the line is not a comment + // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment // (i.e. colon/brace precedes current cursor position). - if (cursor.column > 0 && (text[cursor.line][cursor.column - 1] == ':' || text[cursor.line][cursor.column - 1] == '{') && !is_line_comment(cursor.line)) { - if (indent_using_spaces) { - ins += space_indent; - } else { - ins += "\t"; + if (cursor.column > 0) { + const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(cursor.line); + bool indent_char_found = false; + bool should_indent = false; + char indent_char = ':'; + char c = text[cursor.line][cursor.column]; + + for (int i = 0; i < cursor.column; i++) { + c = text[cursor.line][i]; + switch (c) { + case ':': + case '{': + case '[': + case '(': + indent_char_found = true; + should_indent = true; + indent_char = c; + continue; + } + + if (indent_char_found && cri_map.has(i) && (color_regions[cri_map[i].region].begin_key == "#" || color_regions[cri_map[i].region].begin_key == "//")) { + + should_indent = true; + break; + } else if (indent_char_found && !_is_whitespace(c)) { + should_indent = false; + indent_char_found = false; + } } - // No need to move the brace below if we are not taking the text with us. - if (text[cursor.line][cursor.column] == '}' && !k->get_command()) { - brace_indent = true; - ins += "\n" + ins.substr(1, ins.length() - 2); + if (!is_line_comment(cursor.line) && should_indent) { + if (indent_using_spaces) { + ins += space_indent; + } else { + ins += "\t"; + } + + // No need to move the brace below if we are not taking the text with us. + char closing_char = _get_right_pair_symbol(indent_char); + if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) { + brace_indent = true; + ins += "\n" + ins.substr(1, ins.length() - 2); + } } } } @@ -3882,7 +3928,9 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i if (shift_first_line) { text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line)); text.set_hidden(p_line + 1, text.is_hidden(p_line)); - text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line)); + if (text.has_info_icon(p_line)) { + text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line)); + } text.set_breakpoint(p_line, false); text.set_hidden(p_line, false); @@ -4751,6 +4799,9 @@ void TextEdit::set_text(String p_text) { selection.active = false; } + cursor_set_line(0); + cursor_set_column(0); + update(); setting_text = false; }; @@ -5052,15 +5103,18 @@ Map<int, TextEdit::Text::ColorRegionInfo> TextEdit::_get_line_color_region_info( void TextEdit::clear_colors() { keywords.clear(); + member_keywords.clear(); color_regions.clear(); color_region_cache.clear(); syntax_highlighting_cache.clear(); text.clear_width_cache(); + update(); } void TextEdit::add_keyword_color(const String &p_keyword, const Color &p_color) { keywords[p_keyword] = p_color; + syntax_highlighting_cache.clear(); update(); } @@ -5077,12 +5131,14 @@ Color TextEdit::get_keyword_color(String p_keyword) const { void TextEdit::add_color_region(const String &p_begin_key, const String &p_end_key, const Color &p_color, bool p_line_only) { color_regions.push_back(ColorRegion(p_begin_key, p_end_key, p_color, p_line_only)); + syntax_highlighting_cache.clear(); text.clear_width_cache(); update(); } void TextEdit::add_member_keyword(const String &p_keyword, const Color &p_color) { member_keywords[p_keyword] = p_color; + syntax_highlighting_cache.clear(); update(); } @@ -5096,6 +5152,7 @@ Color TextEdit::get_member_color(String p_member) const { void TextEdit::clear_member_keywords() { member_keywords.clear(); + syntax_highlighting_cache.clear(); update(); } @@ -5388,11 +5445,11 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc PoolVector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const { int col, line; - if (search(p_key, p_search_flags, p_from_line, p_from_column, col, line)) { + if (search(p_key, p_search_flags, p_from_line, p_from_column, line, col)) { PoolVector<int> result; result.resize(2); - result.set(0, line); - result.set(1, col); + result.set(SEARCH_RESULT_COLUMN, col); + result.set(SEARCH_RESULT_LINE, line); return result; } else { @@ -5636,9 +5693,7 @@ void TextEdit::set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info } void TextEdit::clear_info_icons() { - for (int i = 0; i < text.size(); i++) { - text.set_info_icon(i, NULL, ""); - } + text.clear_info_icons(); update(); } @@ -5915,7 +5970,7 @@ void TextEdit::unfold_line(int p_line) { if (!is_folded(p_line) && !is_line_hidden(p_line)) return; - int fold_start = p_line; + int fold_start; for (fold_start = p_line; fold_start > 0; fold_start--) { if (is_folded(fold_start)) break; @@ -6020,6 +6075,7 @@ void TextEdit::undo() { } } + _update_scrollbars(); if (undo_stack_pos->get().type == TextOperation::TYPE_REMOVE) { cursor_set_line(undo_stack_pos->get().to_line); cursor_set_column(undo_stack_pos->get().to_column); @@ -6055,6 +6111,8 @@ void TextEdit::redo() { break; } } + + _update_scrollbars(); cursor_set_line(undo_stack_pos->get().to_line); cursor_set_column(undo_stack_pos->get().to_column); undo_stack_pos = undo_stack_pos->next(); @@ -6330,8 +6388,9 @@ void TextEdit::_confirm_completion() { String line = text[cursor.line]; CharType next_char = line[cursor.column]; CharType last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1]; + CharType last_completion_char_display = completion_current.display[completion_current.display.length() - 1]; - if ((last_completion_char == '"' || last_completion_char == '\'') && last_completion_char == next_char) { + if ((last_completion_char == '"' || last_completion_char == '\'') && (last_completion_char == next_char || last_completion_char_display == next_char)) { _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); } @@ -6478,6 +6537,7 @@ void TextEdit::_update_completion_candidates() { if (inquote && restore_quotes == 1 && !option.display.is_quoted()) { String quote = single_quote ? "'" : "\""; option.display = option.display.quote(quote); + option.insert_text = option.insert_text.quote(quote); } if (option.display.begins_with(s)) { @@ -6903,6 +6963,9 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS); BIND_ENUM_CONSTANT(SEARCH_BACKWARDS); + BIND_ENUM_CONSTANT(SEARCH_RESULT_COLUMN); + BIND_ENUM_CONSTANT(SEARCH_RESULT_LINE); + /* ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char); ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line); |