diff options
-rw-r--r-- | scene/gui/text_edit.cpp | 162 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 13 | ||||
-rw-r--r-- | tools/editor/code_editor.cpp | 24 | ||||
-rw-r--r-- | tools/editor/code_editor.h | 4 | ||||
-rw-r--r-- | tools/editor/editor_settings.cpp | 1 |
5 files changed, 187 insertions, 17 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a6207c5611..87900306d4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -46,7 +46,6 @@ #define TAB_PIXELS - static bool _is_text_char(CharType c) { return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_'; @@ -57,6 +56,42 @@ static bool _is_symbol(CharType c) { return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t'); } +static bool _is_pair_right_symbol(CharType c) { + return + c == '"' || + c == '\'' || + c == ')' || + c == ']' || + c == '}'; +} + +static bool _is_pair_left_symbol(CharType c) { + return + c == '"' || + c == '\'' || + c == '(' || + c == '[' || + c == '{'; +} + +static bool _is_pair_symbol(CharType c) { + return _is_pair_left_symbol(c) || _is_pair_right_symbol(c); +} + +static CharType _get_right_pair_symbol(CharType c) { + if(c == '"') + return '"'; + if(c == '\'') + return '\''; + if(c == '(') + return ')'; + if(c == '[') + return ']'; + if(c == '{') + return '}'; + return 0; +} + void TextEdit::Text::set_font(const Ref<Font>& p_font) { font=p_font; @@ -707,6 +742,94 @@ void TextEdit::_notification(int p_what) { } } +void TextEdit::_consume_pair_symbol(CharType ch) { + + int cursor_position_to_move = cursor_get_column() + 1; + + CharType ch_single[2] = {ch, 0}; + CharType ch_single_pair[2] = {_get_right_pair_symbol(ch), 0}; + CharType ch_pair[3] = {ch, _get_right_pair_symbol(ch), 0}; + + printf("Selectin if active, %d\n", is_selection_active()); + if(is_selection_active()) { + + int new_column,new_line; + + _begin_compex_operation(); + _insert_text(get_selection_from_line(), get_selection_from_column(), + ch_single, + &new_line, &new_column); + + int to_col_offset = 0; + if(get_selection_from_line() == get_selection_to_line()) + to_col_offset = 1; + + _insert_text(get_selection_to_line(), + get_selection_to_column() + to_col_offset, + ch_single_pair, + &new_line,&new_column); + _end_compex_operation(); + + cursor_set_line(get_selection_to_line()); + cursor_set_column(get_selection_to_column() + to_col_offset); + + deselect(); + update(); + return; + } + + if( (ch == '\'' || ch == '"') && + cursor_get_column() > 0 && + _is_text_char(text[cursor.line][cursor_get_column() - 1]) + ) { + insert_text_at_cursor(ch_single); + cursor_set_column(cursor_position_to_move); + return; + } + + if(cursor_get_column() < text[cursor.line].length()) { + if(_is_text_char(text[cursor.line][cursor_get_column()])) { + insert_text_at_cursor(ch_single); + cursor_set_column(cursor_position_to_move); + return; + } + if( _is_pair_right_symbol(ch) && + text[cursor.line][cursor_get_column()] == ch + ) { + cursor_set_column(cursor_position_to_move); + return; + } + } + + + insert_text_at_cursor(ch_pair); + cursor_set_column(cursor_position_to_move); + return; + +} + +void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) { + + bool remove_right_symbol = false; + + if(cursor.column < text[cursor.line].length() && cursor.column > 0) { + + CharType left_char = text[cursor.line][cursor.column - 1]; + CharType right_char = text[cursor.line][cursor.column]; + + if(right_char == _get_right_pair_symbol(left_char)) { + remove_right_symbol = true; + } + + } + if(remove_right_symbol) { + _remove_text(prev_line,prev_column,cursor.line,cursor.column + 1); + } else { + _remove_text(prev_line,prev_column,cursor.line,cursor.column); + } + +} + void TextEdit::backspace_at_cursor() { if (cursor.column==0 && cursor.line==0) @@ -714,7 +837,14 @@ void TextEdit::backspace_at_cursor() { int prev_line = cursor.column?cursor.line:cursor.line-1; int prev_column = cursor.column?(cursor.column-1):(text[cursor.line-1].length()); - _remove_text(prev_line,prev_column,cursor.line,cursor.column); + if(auto_brace_completion_enabled && + cursor.column > 0 && + _is_pair_left_symbol(text[cursor.line][cursor.column - 1])) { + _consume_backspace_for_pair_symbol(prev_line, prev_column); + } else { + _remove_text(prev_line,prev_column,cursor.line,cursor.column); + } + cursor_set_line(prev_line); cursor_set_column(prev_column); @@ -1113,7 +1243,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { default: if (k.unicode>=32 && !k.mod.command && !k.mod.alt && !k.mod.meta) clear=true; - + if (auto_brace_completion_enabled && _is_pair_left_symbol(k.unicode)) + clear=false; } if (unselect) { @@ -1522,14 +1653,35 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (readonly) break; + accept_event(); + } else { + + break; + } + } + + if (!scancode_handled && !k.mod.command && !k.mod.alt) { + + if (k.unicode>=32) { + + if (readonly) + break; + const CharType chr[2] = {k.unicode, 0}; - _insert_text_at_cursor(chr); + + if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { + _consume_pair_symbol(chr[0]); + } else { + _insert_text_at_cursor(chr); + } + accept_event(); } else { break; } } + if (!selection.selecting_test) { @@ -1866,7 +2018,6 @@ void TextEdit::adjust_viewport_to_cursor() { } - void TextEdit::cursor_set_column(int p_col) { if (p_col<0) @@ -2989,6 +3140,7 @@ TextEdit::TextEdit() { tooltip_obj=NULL; line_numbers=false; next_operation_is_complex=false; + auto_brace_completion_enabled=false; } TextEdit::~TextEdit(){ diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 8e9651668b..58d62dea48 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -206,6 +206,8 @@ class TextEdit : public Control { bool text_changed_dirty; bool undo_enabled; bool line_numbers; + + bool auto_brace_completion_enabled; uint64_t last_dblclk; @@ -272,6 +274,10 @@ protected: void _insert_text_at_cursor(const String& p_text); void _input_event(const InputEvent& p_input); void _notification(int p_what); + + void _consume_pair_symbol(CharType ch); + void _consume_backspace_for_pair_symbol(int prev_line, int prev_column); + static void _bind_methods(); @@ -300,8 +306,11 @@ public: String get_text(); String get_line(int line) const; void backspace_at_cursor(); - - + + inline void set_auto_brace_completion(bool p_enabled) { + auto_brace_completion_enabled = p_enabled; + } + void cursor_set_column(int p_col); void cursor_set_line(int p_row); diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index ea87ac625b..a780c0173e 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -510,18 +510,26 @@ void CodeTextEditor::set_error(const String& p_error) { } -void CodeTextEditor::_update_font() { - - String editor_font = EditorSettings::get_singleton()->get("text_editor/font"); +void CodeTextEditor::_on_settings_change() { + + // FONTS + String editor_font = EDITOR_DEF("text_editor/font", ""); + bool font_overrode = false; if (editor_font!="") { Ref<Font> fnt = ResourceLoader::load(editor_font); if (fnt.is_valid()) { text_editor->add_font_override("font",fnt); - return; + font_overrode = true; } } - - text_editor->add_font_override("font",get_font("source","Fonts")); + if(!font_overrode) + text_editor->add_font_override("font",get_font("source","Fonts")); + + // AUTO BRACE COMPLETION + text_editor->set_auto_brace_completion( + EDITOR_DEF("text_editor/auto_brace_complete", false) + ); + } void CodeTextEditor::_text_changed_idle_timeout() { @@ -541,7 +549,7 @@ void CodeTextEditor::_bind_methods() { ObjectTypeDB::bind_method("_line_col_changed",&CodeTextEditor::_line_col_changed); ObjectTypeDB::bind_method("_text_changed",&CodeTextEditor::_text_changed); - ObjectTypeDB::bind_method("_update_font",&CodeTextEditor::_update_font); + ObjectTypeDB::bind_method("_on_settings_change",&CodeTextEditor::_on_settings_change); ObjectTypeDB::bind_method("_text_changed_idle_timeout",&CodeTextEditor::_text_changed_idle_timeout); ObjectTypeDB::bind_method("_complete_request",&CodeTextEditor::_complete_request); } @@ -586,5 +594,5 @@ CodeTextEditor::CodeTextEditor() { text_editor->set_completion(true,cs); idle->connect("timeout", this,"_text_changed_idle_timeout"); - EditorSettings::get_singleton()->connect("settings_changed",this,"_update_font"); + EditorSettings::get_singleton()->connect("settings_changed",this,"_on_settings_change"); } diff --git a/tools/editor/code_editor.h b/tools/editor/code_editor.h index 5a588d2ccb..0ca0e1e234 100644 --- a/tools/editor/code_editor.h +++ b/tools/editor/code_editor.h @@ -55,7 +55,7 @@ public: void set_text_editor(TextEdit *p_text_editor); - GotoLineDialog(); + GotoLineDialog(); }; @@ -131,7 +131,7 @@ class CodeTextEditor : public Control { Label *error; - void _update_font(); + void _on_settings_change(); void _complete_request(const String& p_request,int p_line); protected: diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index e09e090b16..4a58b42a2e 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -402,6 +402,7 @@ void EditorSettings::_load_defaults() { set("text_editor/create_signal_callbacks",true); set("text_editor/autosave_interval_seconds",60); set("text_editor/font",""); + set("text_editor/auto_brace_complete", false); hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); |