diff options
Diffstat (limited to 'editor/plugins/script_text_editor.cpp')
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 317 |
1 files changed, 168 insertions, 149 deletions
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 58a0160010..b719a2ce30 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* script_text_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* script_text_editor.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "script_text_editor.h" @@ -38,6 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "scene/gui/split_container.h" void ConnectionInfoDialog::ok_pressed() { } @@ -151,7 +152,7 @@ void ScriptTextEditor::set_edited_resource(const Ref<Resource> &p_res) { code_editor->update_line_and_column(); } -void ScriptTextEditor::enable_editor() { +void ScriptTextEditor::enable_editor(Control *p_shortcut_context) { if (editor_enabled) { return; } @@ -161,6 +162,15 @@ void ScriptTextEditor::enable_editor() { _enable_code_editor(); _validate_script(); + + if (p_shortcut_context) { + for (int i = 0; i < edit_hb->get_child_count(); ++i) { + Control *c = cast_to<Control>(edit_hb->get_child(i)); + if (c) { + c->set_shortcut_context(p_shortcut_context); + } + } + } } void ScriptTextEditor::_load_theme_settings() { @@ -316,7 +326,7 @@ bool ScriptTextEditor::show_members_overview() { } void ScriptTextEditor::update_settings() { - code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EditorSettings::get_singleton()->get("text_editor/appearance/gutters/show_info_gutter")); + code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EDITOR_GET("text_editor/appearance/gutters/show_info_gutter")); code_editor->update_editor_settings(); } @@ -689,7 +699,7 @@ static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_curr } void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) { - if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + if (!bool(EDITOR_GET("text_editor/external/use_external_editor"))) { return; } @@ -1213,7 +1223,9 @@ void ScriptTextEditor::_edit_option(int p_op) { code_editor->duplicate_selection(); } break; case EDIT_TOGGLE_FOLD_LINE: { - tx->toggle_foldable_line(tx->get_caret_line()); + for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) { + tx->toggle_foldable_line(tx->get_caret_line(caret_idx)); + } tx->queue_redraw(); } break; case EDIT_FOLD_ALL_LINES: { @@ -1281,28 +1293,28 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case EDIT_EVALUATE: { Expression expression; - Vector<String> lines = code_editor->get_text_editor()->get_selected_text().split("\n"); - PackedStringArray results; - - for (int i = 0; i < lines.size(); i++) { - String line = lines[i]; - String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning - - if (expression.parse(line) == OK) { - Variant result = expression.execute(Array(), Variant(), false, true); - if (expression.get_error_text().is_empty()) { - results.push_back(whitespace + result.get_construct_string()); + tx->begin_complex_operation(); + for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) { + Vector<String> lines = tx->get_selected_text(caret_idx).split("\n"); + PackedStringArray results; + + for (int i = 0; i < lines.size(); i++) { + String line = lines[i]; + String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); // Extract the whitespace at the beginning. + if (expression.parse(line) == OK) { + Variant result = expression.execute(Array(), Variant(), false, true); + if (expression.get_error_text().is_empty()) { + results.push_back(whitespace + result.get_construct_string()); + } else { + results.push_back(line); + } } else { results.push_back(line); } - } else { - results.push_back(line); } + tx->insert_text_at_caret(String("\n").join(results), caret_idx); } - - code_editor->get_text_editor()->begin_complex_operation(); //prevents creating a two-step undo - code_editor->get_text_editor()->insert_text_at_caret(String("\n").join(results)); - code_editor->get_text_editor()->end_complex_operation(); + tx->end_complex_operation(); } break; case SEARCH_FIND: { code_editor->get_find_replace_bar()->popup_search(); @@ -1317,14 +1329,14 @@ void ScriptTextEditor::_edit_option(int p_op) { code_editor->get_find_replace_bar()->popup_replace(); } break; case SEARCH_IN_FILES: { - String selected_text = code_editor->get_text_editor()->get_selected_text(); + String selected_text = tx->get_selected_text(); // Yep, because it doesn't make sense to instance this dialog for every single script open... // So this will be delegated to the ScriptEditor. emit_signal(SNAME("search_in_files_requested"), selected_text); } break; case REPLACE_IN_FILES: { - String selected_text = code_editor->get_text_editor()->get_selected_text(); + String selected_text = tx->get_selected_text(); emit_signal(SNAME("replace_in_files_requested"), selected_text); } break; @@ -1348,10 +1360,12 @@ void ScriptTextEditor::_edit_option(int p_op) { code_editor->remove_all_bookmarks(); } break; case DEBUG_TOGGLE_BREAKPOINT: { - int line = tx->get_caret_line(); - bool dobreak = !tx->is_line_breakpointed(line); - tx->set_line_as_breakpoint(line, dobreak); - EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak); + for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) { + int line = tx->get_caret_line(caret_idx); + bool dobreak = !tx->is_line_breakpointed(line); + tx->set_line_as_breakpoint(line, dobreak); + EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak); + } } break; case DEBUG_REMOVE_ALL_BREAKPOINTS: { PackedInt32Array bpoints = tx->get_breakpointed_lines(); @@ -1369,26 +1383,14 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->remove_secondary_carets(); - int line = tx->get_caret_line(); - - // wrap around - if (line >= (int)bpoints[bpoints.size() - 1]) { - tx->unfold_line(bpoints[0]); - tx->set_caret_line(bpoints[0]); - tx->center_viewport_to_caret(); - } else { - for (int i = 0; i < bpoints.size(); i++) { - int bline = bpoints[i]; - if (bline > line) { - tx->unfold_line(bline); - tx->set_caret_line(bline); - tx->center_viewport_to_caret(); - return; - } + int current_line = tx->get_caret_line(); + int bpoint_idx = 0; + if (current_line < (int)bpoints[bpoints.size() - 1]) { + while (bpoint_idx < bpoints.size() && bpoints[bpoint_idx] <= current_line) { + bpoint_idx++; } } - + code_editor->goto_line_centered(bpoints[bpoint_idx]); } break; case DEBUG_GOTO_PREV_BREAKPOINT: { PackedInt32Array bpoints = tx->get_breakpointed_lines(); @@ -1396,25 +1398,14 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->remove_secondary_carets(); - int line = tx->get_caret_line(); - // wrap around - if (line <= (int)bpoints[0]) { - tx->unfold_line(bpoints[bpoints.size() - 1]); - tx->set_caret_line(bpoints[bpoints.size() - 1]); - tx->center_viewport_to_caret(); - } else { - for (int i = bpoints.size() - 1; i >= 0; i--) { - int bline = bpoints[i]; - if (bline < line) { - tx->unfold_line(bline); - tx->set_caret_line(bline); - tx->center_viewport_to_caret(); - return; - } + int current_line = tx->get_caret_line(); + int bpoint_idx = bpoints.size() - 1; + if (current_line > (int)bpoints[0]) { + while (bpoint_idx >= 0 && bpoints[bpoint_idx] >= current_line) { + bpoint_idx--; } } - + code_editor->goto_line_centered(bpoints[bpoint_idx]); } break; case HELP_CONTEXTUAL: { String text = tx->get_selected_text(0); @@ -1499,14 +1490,6 @@ void ScriptTextEditor::_notification(int p_what) { } } -void ScriptTextEditor::_bind_methods() { - ClassDB::bind_method("_update_connected_methods", &ScriptTextEditor::_update_connected_methods); - - ClassDB::bind_method("_get_drag_data_fw", &ScriptTextEditor::get_drag_data_fw); - ClassDB::bind_method("_can_drop_data_fw", &ScriptTextEditor::can_drop_data_fw); - ClassDB::bind_method("_drop_data_fw", &ScriptTextEditor::drop_data_fw); -} - Control *ScriptTextEditor::get_edit_menu() { return edit_hb; } @@ -1598,9 +1581,24 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const return nullptr; } -void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; +static String _quote_drop_data(const String &str) { + // This function prepares a string for being "dropped" into the script editor. + // The string can be a resource path, node path or property name. + + const bool using_single_quotes = EDITOR_GET("text_editor/completion/use_single_quotes"); + + String escaped = str.c_escape(); + + // If string is double quoted, there is no need to escape single quotes. + // We can revert the extra escaping added in c_escape(). + if (!using_single_quotes) { + escaped = escaped.replace("\\'", "\'"); + } + + return escaped.quote(using_single_quotes ? "'" : "\""); +} +void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { Dictionary d = p_data; CodeEdit *te = code_editor->get_text_editor(); @@ -1638,9 +1636,9 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (preload) { - text_to_drop += "preload(" + String(files[i]).c_escape().quote(quote_style) + ")"; + text_to_drop += "preload(" + _quote_drop_data(String(files[i])) + ")"; } else { - text_to_drop += String(files[i]).c_escape().quote(quote_style); + text_to_drop += _quote_drop_data(String(files[i])); } } @@ -1686,7 +1684,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } for (const String &segment : path.split("/")) { if (!segment.is_valid_identifier()) { - path = path.c_escape().quote(quote_style); + path = _quote_drop_data(path); break; } } @@ -1721,7 +1719,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data for (const String &segment : path.split("/")) { if (!segment.is_valid_identifier()) { - path = path.c_escape().quote(quote_style); + path = _quote_drop_data(path); break; } } @@ -1737,7 +1735,9 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data if (d.has("type") && String(d["type"]) == "obj_property") { te->remove_secondary_carets(); - const String text_to_drop = String(d["property"]).c_escape().quote(quote_style); + // It is unclear whether properties may contain single or double quotes. + // Assume here that double-quotes may not exist. We are escaping single-quotes if necessary. + const String text_to_drop = _quote_drop_data(String(d["property"])); te->set_caret_line(row); te->set_caret_column(col); @@ -1767,7 +1767,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int row = pos.y; int col = pos.x; - tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); + tx->set_move_caret_on_right_click_enabled(EDITOR_GET("text_editor/behavior/navigation/move_caret_on_right_click")); if (tx->is_move_caret_on_right_click_enabled()) { tx->remove_secondary_carets(); if (tx->has_selection()) { @@ -1808,7 +1808,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { base = _find_node_for_script(base, base, script); } ScriptLanguage::LookupResult result; - if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) { + if (script->get_language()->lookup_code(tx->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) { open_docs = true; } } @@ -1834,7 +1834,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { if (valid) { color_args = line.substr(begin, end - begin); String stripped = color_args.replace(" ", "").replace("(", "").replace(")", ""); - Vector<float> color = stripped.split_floats(","); + PackedFloat64Array color = stripped.split_floats(","); if (color.size() > 2) { float alpha = color.size() > 3 ? color[3] : 1.0f; color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha)); @@ -1978,18 +1978,6 @@ void ScriptTextEditor::_enable_code_editor() { add_child(connection_info_dialog); - edit_hb->add_child(search_menu); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); - search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); - edit_hb->add_child(edit_menu); edit_menu->connect("about_to_popup", callable_mp(this, &ScriptTextEditor::_prepare_edit_menu)); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); @@ -2000,38 +1988,73 @@ void ScriptTextEditor::_enable_code_editor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("line_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Line"), "line_menu"); + } + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("folding_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Folding"), "folding_menu"); + } edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("indent_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Indentation"), "indent_menu"); + } edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); edit_menu->get_popup()->add_separator(); - - edit_menu->get_popup()->add_child(convert_case); - edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case"); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KeyModifierMask::SHIFT | Key::F4), EDIT_TO_UPPERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KeyModifierMask::SHIFT | Key::F5), EDIT_TO_LOWERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KeyModifierMask::SHIFT | Key::F6), EDIT_CAPITALIZE); - convert_case->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); - + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("convert_case"); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KeyModifierMask::SHIFT | Key::F4), EDIT_TO_UPPERCASE); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KeyModifierMask::SHIFT | Key::F5), EDIT_TO_LOWERCASE); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KeyModifierMask::SHIFT | Key::F6), EDIT_CAPITALIZE); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case"); + } edit_menu->get_popup()->add_child(highlighter_menu); edit_menu->get_popup()->add_submenu_item(TTR("Syntax Highlighter"), "highlighter_menu"); highlighter_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_change_syntax_highlighter)); + edit_hb->add_child(search_menu); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); + search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + _load_theme_settings(); edit_hb->add_child(goto_menu); @@ -2090,7 +2113,7 @@ ScriptTextEditor::ScriptTextEditor() { update_settings(); - code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); + code_editor->get_text_editor()->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line")); code_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true); code_editor->get_text_editor()->set_context_menu_enabled(false); @@ -2106,9 +2129,6 @@ ScriptTextEditor::ScriptTextEditor() { edit_menu->set_switch_on_hover(true); edit_menu->set_shortcut_context(this); - convert_case = memnew(PopupMenu); - convert_case->set_name("convert_case"); - highlighter_menu = memnew(PopupMenu); highlighter_menu->set_name("highlighter_menu"); @@ -2139,7 +2159,7 @@ ScriptTextEditor::ScriptTextEditor() { connection_info_dialog = memnew(ConnectionInfoDialog); - code_editor->get_text_editor()->set_drag_forwarding(this); + SET_DRAG_FORWARDING_GCD(code_editor->get_text_editor(), ScriptTextEditor); } ScriptTextEditor::~ScriptTextEditor() { @@ -2153,7 +2173,6 @@ ScriptTextEditor::~ScriptTextEditor() { memdelete(color_panel); memdelete(edit_hb); memdelete(edit_menu); - memdelete(convert_case); memdelete(highlighter_menu); memdelete(search_menu); memdelete(goto_menu); |