diff options
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r-- | scene/gui/text_edit.cpp | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 245e7e04be..ade665b418 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3,7 +3,7 @@ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ -/* http://www.godotengine.org */ +/* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ @@ -27,13 +27,12 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ - #include "text_edit.h" + +#include "message_queue.h" #include "os/input.h" #include "os/keyboard.h" #include "os/os.h" - -#include "message_queue.h" #include "project_settings.h" #include "scene/main/viewport.h" @@ -215,8 +214,8 @@ void TextEdit::Text::_update_line_cache(int p_line) const { const Map<int, TextEdit::Text::ColorRegionInfo> &TextEdit::Text::get_color_region_info(int p_line) { - Map<int, ColorRegionInfo> *cri = NULL; - ERR_FAIL_INDEX_V(p_line, text.size(), *cri); //enjoy your crash + static Map<int, ColorRegionInfo> cri; + ERR_FAIL_INDEX_V(p_line, text.size(), cri); if (text[p_line].width_cache == -1) { _update_line_cache(p_line); @@ -431,7 +430,7 @@ void TextEdit::_notification(int p_what) { double dist = sqrt(target_y * target_y); double vel = ((target_y / dist) * v_scroll_speed) * get_fixed_process_delta_time(); - if (vel >= dist) { + if (Math::abs(vel) >= dist) { v_scroll->set_value(target_v_scroll); scrolling = false; set_fixed_process(false); @@ -2114,7 +2113,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { //keep indentation int space_count = 0; - for (int i = 0; i < text[cursor.line].length(); i++) { + for (int i = 0; i < cursor.column; i++) { if (text[cursor.line][i] == '\t') { if (indent_using_spaces) { ins += space_indent; @@ -2736,6 +2735,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { else undo(); } break; + case KEY_Y: { + + if (!k->get_command()) { + scancode_handled = false; + break; + } + + redo(); + } break; case KEY_V: { if (readonly) { break; @@ -3181,6 +3189,11 @@ void TextEdit::adjust_viewport_to_cursor() { if (cursor.line < cursor.line_ofs) cursor.line_ofs = cursor.line; + if (cursor.line_ofs + visible_rows > text.size() && !scroll_past_end_of_file_enabled) { + cursor.line_ofs = text.size() - visible_rows; + v_scroll->set_value(text.size() - visible_rows); + } + int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]); if (cursor_x > (cursor.x_ofs + visible_width)) @@ -3653,10 +3666,10 @@ void TextEdit::cut() { String clipboard = _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); OS::get_singleton()->set_clipboard(clipboard); - cursor_set_line(selection.from_line); + _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); + cursor_set_line(selection.from_line); // set afterwards else it causes the view to be offset cursor_set_column(selection.from_column); - _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); selection.active = false; selection.selecting_mode = Selection::MODE_NONE; update(); @@ -4319,6 +4332,7 @@ void TextEdit::_cancel_completion() { return; completion_active = false; + completion_forced = false; update(); } @@ -4386,13 +4400,19 @@ void TextEdit::_update_completion_candidates() { } } - if (cursor.column > 0 && l[cursor.column - 1] == '(' && !pre_keyword && !completion_strings[0].begins_with("\"")) { + if (cursor.column > 0 && l[cursor.column - 1] == '(' && !pre_keyword && !completion_forced) { cancel = true; } update(); - if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !completion_prefixes.has(String::chr(l[cofs - 1]))))) { + bool prev_is_prefix = false; + if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1]))) + prev_is_prefix = true; + if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2]))) //check with one space before prefix, to allow indent + prev_is_prefix = true; + + if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !prev_is_prefix))) { //none to complete, cancel _cancel_completion(); return; @@ -4450,18 +4470,6 @@ void TextEdit::_update_completion_candidates() { // The top of the list is the best match completion_current = completion_options[0]; - -#if 0 // even there's only one option, user still get the chance to choose using it or not - if (completion_options.size()==1) { - //one option to complete, just complete it automagically - _confirm_completion(); - //insert_text_at_cursor(completion_options[0].substr(s.length(),completion_options[0].length()-s.length())); - _cancel_completion(); - return; - - } -#endif - completion_enabled = true; } @@ -4481,6 +4489,8 @@ void TextEdit::query_code_comple() { if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1])))) emit_signal("request_completion"); + else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) //make it work with a space too, it's good enough + emit_signal("request_completion"); } void TextEdit::set_code_hint(const String &p_hint) { @@ -4492,12 +4502,13 @@ void TextEdit::set_code_hint(const String &p_hint) { update(); } -void TextEdit::code_complete(const Vector<String> &p_strings) { +void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) { VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); raised_from_completion = true; completion_strings = p_strings; completion_active = true; + completion_forced = p_forced; completion_current = ""; completion_index = 0; _update_completion_candidates(); @@ -4520,7 +4531,7 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const { bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this bool inside_quotes = false; - int qbegin, qend; + int qbegin = 0, qend = 0; for (int i = 0; i < s.length(); i++) { if (s[i] == '"') { if (inside_quotes) { @@ -4885,24 +4896,6 @@ TextEdit::TextEdit() { click_select_held->set_wait_time(0.05); click_select_held->connect("timeout", this, "_click_selection_held"); -#if 0 - syntax_coloring=true; - keywords["void"]=Color(0.3,0.0,0.1); - keywords["int"]=Color(0.3,0.0,0.1); - keywords["function"]=Color(0.3,0.0,0.1); - keywords["class"]=Color(0.3,0.0,0.1); - keywords["extends"]=Color(0.3,0.0,0.1); - keywords["constructor"]=Color(0.3,0.0,0.1); - symbol_color=Color(0.1,0.0,0.3,1.0); - - color_regions.push_back(ColorRegion("/*","*/",Color(0.4,0.6,0,4))); - color_regions.push_back(ColorRegion("//","",Color(0.6,0.6,0.4))); - color_regions.push_back(ColorRegion("\"","\"",Color(0.4,0.7,0.7))); - color_regions.push_back(ColorRegion("'","'",Color(0.4,0.8,0.8))); - color_regions.push_back(ColorRegion("#","",Color(0.2,1.0,0.2))); - -#endif - current_op.type = TextOperation::TYPE_NONE; undo_enabled = true; undo_stack_pos = NULL; |