diff options
Diffstat (limited to 'editor/plugins/script_editor_plugin.cpp')
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 389 |
1 files changed, 257 insertions, 132 deletions
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d457906d0c..2f479527f3 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/version.h" +#include "editor/code_editor.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_command_palette.h" @@ -45,12 +46,12 @@ #include "editor/editor_interface.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" -#include "editor/editor_scale.h" #include "editor/editor_script.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/filesystem_dock.h" #include "editor/find_in_files.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_toaster.h" @@ -58,6 +59,8 @@ #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" #include "editor/plugins/text_shader_editor.h" +#include "editor/themes/editor_scale.h" +#include "editor/themes/editor_theme_manager.h" #include "editor/window_wrapper.h" #include "scene/main/node.h" #include "scene/main/window.h" @@ -134,12 +137,22 @@ void EditorStandardSyntaxHighlighter::_update_cache() { } } - const Ref<Script> scr = _get_edited_resource(); - if (scr.is_valid()) { + const ScriptLanguage *scr_lang = script_language; + StringName instance_base; + + if (scr_lang == nullptr) { + const Ref<Script> scr = _get_edited_resource(); + if (scr.is_valid()) { + scr_lang = scr->get_language(); + instance_base = scr->get_instance_base_type(); + } + } + + if (scr_lang != nullptr) { /* Core types. */ const Color basetype_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color"); List<String> core_types; - scr->get_language()->get_core_type_words(&core_types); + scr_lang->get_core_type_words(&core_types); for (const String &E : core_types) { highlighter->add_keyword_color(E, basetype_color); } @@ -148,9 +161,9 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); List<String> keywords; - scr->get_language()->get_reserved_words(&keywords); + scr_lang->get_reserved_words(&keywords); for (const String &E : keywords) { - if (scr->get_language()->is_control_flow_keyword(E)) { + if (scr_lang->is_control_flow_keyword(E)) { highlighter->add_keyword_color(E, control_flow_keyword_color); } else { highlighter->add_keyword_color(E, keyword_color); @@ -159,7 +172,6 @@ void EditorStandardSyntaxHighlighter::_update_cache() { /* Member types. */ const Color member_variable_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color"); - StringName instance_base = scr->get_instance_base_type(); if (instance_base != StringName()) { List<PropertyInfo> plist; ClassDB::get_property_list(instance_base, &plist); @@ -184,17 +196,27 @@ void EditorStandardSyntaxHighlighter::_update_cache() { /* Comments */ const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); List<String> comments; - scr->get_language()->get_comment_delimiters(&comments); + scr_lang->get_comment_delimiters(&comments); for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); highlighter->add_color_region(beg, end, comment_color, end.is_empty()); } + /* Doc comments */ + const Color doc_comment_color = EDITOR_GET("text_editor/theme/highlighting/doc_comment_color"); + List<String> doc_comments; + scr_lang->get_doc_comment_delimiters(&doc_comments); + for (const String &doc_comment : doc_comments) { + String beg = doc_comment.get_slice(" ", 0); + String end = doc_comment.get_slice_count(" ") > 1 ? doc_comment.get_slice(" ", 1) : String(); + highlighter->add_color_region(beg, end, doc_comment_color, end.is_empty()); + } + /* Strings */ const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); List<String> strings; - scr->get_language()->get_string_delimiters(&strings); + scr_lang->get_string_delimiters(&strings); for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); @@ -251,6 +273,7 @@ void ScriptEditorBase::_bind_methods() { ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic"))); ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("request_save_history")); + ADD_SIGNAL(MethodInfo("request_save_previous_state", PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what"))); ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text"))); ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text"))); @@ -410,6 +433,7 @@ ScriptEditorQuickOpen::ScriptEditorQuickOpen() { register_text_enter(search_box); set_hide_on_ok(false); search_options->connect("item_activated", callable_mp(this, &ScriptEditorQuickOpen::_confirmed)); + search_options->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); search_options->set_hide_root(true); search_options->set_hide_folding(true); search_options->add_theme_constant_override("draw_guides", 1); @@ -423,7 +447,11 @@ ScriptEditor *ScriptEditor::script_editor = nullptr; String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) { String val = EditorDebuggerNode::get_singleton()->get_var_value(p_text); + const int display_limit = 300; if (!val.is_empty()) { + if (val.size() > display_limit) { + val = val.left(display_limit) + " [...] truncated!"; + } return p_text + ": " + val; } else { return String(); @@ -431,7 +459,7 @@ String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) { } void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) { - if (bool(EDITOR_GET("text_editor/external/use_external_editor"))) { + if (external_editor_active) { return; } @@ -534,7 +562,7 @@ void ScriptEditor::_set_breakpoint(Ref<RefCounted> p_script, int p_line, bool p_ } state["breakpoints"] = breakpoints; script_editor_cache->set_value(scr->get_path(), "state", state); - EditorDebuggerNode::get_singleton()->set_breakpoint(scr->get_path(), p_line + 1, false); + EditorDebuggerNode::get_singleton()->set_breakpoint(scr->get_path(), p_line + 1, p_enabled); } } @@ -612,6 +640,32 @@ void ScriptEditor::_save_history() { _update_history_arrows(); } +void ScriptEditor::_save_previous_state(Dictionary p_state) { + if (lock_history) { + // Done as a result of a deferred call triggered by set_edit_state(). + lock_history = false; + return; + } + + if (history_pos >= 0 && history_pos < history.size() && history[history_pos].control == tab_container->get_current_tab_control()) { + Node *n = tab_container->get_current_tab_control(); + + if (Object::cast_to<ScriptTextEditor>(n)) { + history.write[history_pos].state = p_state; + } + } + + history.resize(history_pos + 1); + ScriptHistory sh; + sh.control = tab_container->get_current_tab_control(); + sh.state = Variant(); + + history.push_back(sh); + history_pos++; + + _update_history_arrows(); +} + void ScriptEditor::_go_to_tab(int p_idx) { ScriptEditorBase *current = _get_current_editor(); if (current) { @@ -641,8 +695,10 @@ void ScriptEditor::_go_to_tab(int p_idx) { sh.control = c; sh.state = Variant(); - history.push_back(sh); - history_pos++; + if (!lock_history && (history.is_empty() || history[history.size() - 1].control != sh.control)) { + history.push_back(sh); + history_pos++; + } tab_container->set_current_tab(p_idx); @@ -680,7 +736,7 @@ void ScriptEditor::_go_to_tab(int p_idx) { _update_help_overview_visibility(); } -void ScriptEditor::_add_recent_script(String p_path) { +void ScriptEditor::_add_recent_script(const String &p_path) { if (p_path.is_empty()) { return; } @@ -719,7 +775,7 @@ void ScriptEditor::_open_recent_script(int p_idx) { // clear button if (p_idx == recent_scripts->get_item_count() - 1) { EditorSettings::get_singleton()->set_project_metadata("recent_files", "scripts", Array()); - call_deferred(SNAME("_update_recent_scripts")); + callable_mp(this, &ScriptEditor::_update_recent_scripts).call_deferred(); return; } @@ -774,7 +830,7 @@ void ScriptEditor::_open_recent_script(int p_idx) { _show_error_dialog(path); } -void ScriptEditor::_show_error_dialog(String p_path) { +void ScriptEditor::_show_error_dialog(const String &p_path) { error_dialog->set_text(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_path)); error_dialog->popup_centered(); } @@ -836,33 +892,36 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { _save_editor_state(current); } memdelete(tselected); - if (idx >= tab_container->get_tab_count()) { - idx = tab_container->get_tab_count() - 1; - } - if (idx >= 0) { - if (history_pos >= 0) { - idx = tab_container->get_tab_idx_from_control(history[history_pos].control); - } - _go_to_tab(idx); - } else { - _update_selected_editor_menu(); - } if (script_close_queue.is_empty()) { + if (idx >= tab_container->get_tab_count()) { + idx = tab_container->get_tab_count() - 1; + } + if (idx >= 0) { + if (history_pos >= 0) { + idx = tab_container->get_tab_idx_from_control(history[history_pos].control); + } + _go_to_tab(idx); + } else { + _update_selected_editor_menu(); + } + _update_history_arrows(); _update_script_names(); - _update_members_overview_visibility(); - _update_help_overview_visibility(); _save_layout(); _update_find_replace_bar(); } } -void ScriptEditor::_close_current_tab(bool p_save) { - _close_tab(tab_container->get_current_tab(), p_save); +void ScriptEditor::_close_current_tab(bool p_save, bool p_history_back) { + _close_tab(tab_container->get_current_tab(), p_save, p_history_back); } void ScriptEditor::_close_discard_current_tab(const String &p_str) { + Ref<Script> scr = _get_current_script(); + if (scr.is_valid()) { + scr->reload_from_file(); + } _close_tab(tab_container->get_current_tab(), false); erase_tab_confirm->hide(); } @@ -919,7 +978,7 @@ void ScriptEditor::_queue_close_tabs() { } } - _close_current_tab(false); + _close_current_tab(false, false); } _update_find_replace_bar(); } @@ -982,12 +1041,24 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) { } } + if (p_res.is_valid()) { + // In case the Resource has built-in scripts. + _mark_built_in_scripts_as_saved(p_res->get_path()); + } + _update_script_names(); - _trigger_live_script_reload(); + Ref<Script> scr = p_res; + if (scr.is_valid()) { + trigger_live_script_reload(scr->get_path()); + } } void ScriptEditor::_scene_saved_callback(const String &p_path) { // If scene was saved, mark all built-in scripts from that scene as saved. + _mark_built_in_scripts_as_saved(p_path); +} + +void ScriptEditor::_mark_built_in_scripts_as_saved(const String &p_parent_path) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { @@ -1000,7 +1071,7 @@ void ScriptEditor::_scene_saved_callback(const String &p_path) { continue; // External script, who cares. } - if (edited_res->get_path().get_slice("::", 0) == p_path) { + if (edited_res->get_path().get_slice("::", 0) == p_parent_path) { se->tag_saved_version(); } @@ -1011,16 +1082,33 @@ void ScriptEditor::_scene_saved_callback(const String &p_path) { } } -void ScriptEditor::_trigger_live_script_reload() { +void ScriptEditor::trigger_live_script_reload(const String &p_script_path) { + if (!script_paths_to_reload.has(p_script_path)) { + script_paths_to_reload.append(p_script_path); + } + if (!pending_auto_reload && auto_reload_running_scripts) { + callable_mp(this, &ScriptEditor::_live_auto_reload_running_scripts).call_deferred(); + pending_auto_reload = true; + } +} + +void ScriptEditor::trigger_live_script_reload_all() { if (!pending_auto_reload && auto_reload_running_scripts) { call_deferred(SNAME("_live_auto_reload_running_scripts")); pending_auto_reload = true; + reload_all_scripts = true; } } void ScriptEditor::_live_auto_reload_running_scripts() { pending_auto_reload = false; - EditorDebuggerNode::get_singleton()->reload_scripts(); + if (reload_all_scripts) { + EditorDebuggerNode::get_singleton()->reload_all_scripts(); + } else { + EditorDebuggerNode::get_singleton()->reload_scripts(script_paths_to_reload); + } + reload_all_scripts = false; + script_paths_to_reload.clear(); } bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { @@ -1064,14 +1152,14 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { script_editor->reload_scripts(); need_reload = false; } else { - disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.3); + callable_mp((Window *)disk_changed, &Window::popup_centered_ratio).call_deferred(0.3); } } return need_reload; } -void ScriptEditor::_file_dialog_action(String p_file) { +void ScriptEditor::_file_dialog_action(const String &p_file) { switch (file_dialog_option) { case FILE_NEW_TEXTFILE: { Error err; @@ -1175,8 +1263,8 @@ void ScriptEditor::_menu_option(int p_option) { for (const String &E : textfile_extensions) { file_dialog->add_filter("*." + E, E.to_upper()); } - file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("New Text File...")); + file_dialog->popup_file_dialog(); open_textfile_after_create = true; } break; case FILE_OPEN: { @@ -1187,16 +1275,16 @@ void ScriptEditor::_menu_option(int p_option) { List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); file_dialog->clear_filters(); - for (int i = 0; i < extensions.size(); i++) { - file_dialog->add_filter("*." + extensions[i], extensions[i].to_upper()); + for (const String &extension : extensions) { + file_dialog->add_filter("*." + extension, extension.to_upper()); } for (const String &E : textfile_extensions) { file_dialog->add_filter("*." + E, E.to_upper()); } - file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Open File")); + file_dialog->popup_file_dialog(); return; } break; case FILE_REOPEN_CLOSED: { @@ -1319,8 +1407,8 @@ void ScriptEditor::_menu_option(int p_option) { file_dialog->clear_filters(); file_dialog->set_current_dir(text_file->get_path().get_base_dir()); file_dialog->set_current_file(text_file->get_path().get_file()); - file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Save File As...")); + file_dialog->popup_file_dialog(); break; } @@ -1409,11 +1497,7 @@ void ScriptEditor::_menu_option(int p_option) { path = path.get_slice("::", 0); // Show the scene instead. } - FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); - file_system_dock->navigate_to_path(path); - // Ensure that the FileSystem dock is visible. - TabContainer *dock_tab_container = (TabContainer *)file_system_dock->get_parent_control(); - dock_tab_container->set_current_tab(dock_tab_container->get_tab_idx_from_control(file_system_dock)); + FileSystemDock::get_singleton()->navigate_to_path(path); } } break; case CLOSE_DOCS: { @@ -1498,8 +1582,8 @@ void ScriptEditor::_theme_option(int p_option) { file_dialog_option = THEME_IMPORT; file_dialog->clear_filters(); file_dialog->add_filter("*.tet"); - file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Import Theme")); + file_dialog->popup_file_dialog(); } break; case THEME_RELOAD: { EditorSettings::get_singleton()->load_text_editor_theme(); @@ -1524,8 +1608,8 @@ void ScriptEditor::_show_save_theme_as_dialog() { file_dialog->clear_filters(); file_dialog->add_filter("*.tet"); file_dialog->set_current_path(EditorPaths::get_singleton()->get_text_editor_themes_dir().path_join(EDITOR_GET("text_editor/theme/color_theme"))); - file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Save Theme As...")); + file_dialog->popup_file_dialog(); } bool ScriptEditor::_has_docs_tab() const { @@ -1605,7 +1689,7 @@ void ScriptEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); - _editor_settings_changed(); + _apply_editor_settings(); [[fallthrough]]; } @@ -1635,7 +1719,6 @@ void ScriptEditor::_notification(int p_what) { recent_scripts->reset_size(); if (is_inside_tree()) { - _update_script_colors(); _update_script_names(); } } break; @@ -1672,18 +1755,6 @@ void ScriptEditor::_notification(int p_what) { _test_script_times_on_disk(); _update_modified_scripts_for_external_editor(); } break; - - case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: { - if (is_visible()) { - find_in_files_button->show(); - } else { - if (find_in_files->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); - } - find_in_files_button->hide(); - } - - } break; } } @@ -1849,7 +1920,7 @@ struct _ScriptEditorItemData { if (sort_key == id.sort_key) { return index < id.index; } else { - return sort_key.naturalnocasecmp_to(id.sort_key) < 0; + return sort_key.filenocasecmp_to(id.sort_key) < 0; } } else { return category < id.category; @@ -2143,8 +2214,11 @@ void ScriptEditor::_update_script_names() { sd.index = i; sedata.set(i, sd); } + + lock_history = true; _go_to_tab(new_prev_tab); _go_to_tab(new_cur_tab); + lock_history = false; _sort_list_on_update = false; } @@ -2260,7 +2334,7 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, // Don't open dominant script if using an external editor. bool use_external_editor = - EDITOR_GET("text_editor/external/use_external_editor") || + external_editor_active || (scr.is_valid() && scr->get_language()->overrides_external_editor()); use_external_editor = use_external_editor && !(scr.is_valid() && scr->is_built_in()); // Ignore external editor for built-in scripts. const bool open_dominant = EDITOR_GET("text_editor/behavior/files/open_dominant_script_on_scene_change"); @@ -2432,6 +2506,10 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, if (script_editor_cache->has_section(p_resource->get_path())) { se->set_edit_state(script_editor_cache->get_value(p_resource->get_path(), "state")); + ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(se); + if (ste) { + ste->store_previous_state(); + } } _sort_list_on_update = true; @@ -2443,10 +2521,17 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, se->connect("request_open_script_at_line", callable_mp(this, &ScriptEditor::_goto_script_line)); se->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto)); se->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history)); + se->connect("request_save_previous_state", callable_mp(this, &ScriptEditor::_save_previous_state)); se->connect("search_in_files_requested", callable_mp(this, &ScriptEditor::_on_find_in_files_requested)); se->connect("replace_in_files_requested", callable_mp(this, &ScriptEditor::_on_replace_in_files_requested)); se->connect("go_to_method", callable_mp(this, &ScriptEditor::script_goto_method)); + CodeTextEditor *cte = se->get_code_editor(); + if (cte) { + cte->set_zoom_factor(zoom_factor); + cte->connect("zoomed", callable_mp(this, &ScriptEditor::_set_zoom_factor)); + } + //test for modification, maybe the script was not edited but was loaded _test_script_times_on_disk(p_resource); @@ -2502,17 +2587,7 @@ void ScriptEditor::save_current_script() { clear_docs_from_script(scr); } - if (resource->is_built_in()) { - // If built-in script, save the scene instead. - const String scene_path = resource->get_path().get_slice("::", 0); - if (!scene_path.is_empty()) { - Vector<String> scene_to_save; - scene_to_save.push_back(scene_path); - EditorNode::get_singleton()->save_scene_list(scene_to_save); - } - } else { - EditorNode::get_singleton()->save_resource(resource); - } + EditorNode::get_singleton()->save_resource(resource); if (scr.is_valid()) { update_docs_from_script(scr); @@ -2520,7 +2595,7 @@ void ScriptEditor::save_current_script() { } void ScriptEditor::save_all_scripts() { - Vector<String> scenes_to_save; + HashSet<String> scenes_to_save; for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); @@ -2569,7 +2644,7 @@ void ScriptEditor::save_all_scripts() { // For built-in scripts, save their scenes instead. const String scene_path = edited_res->get_path().get_slice("::", 0); if (!scene_path.is_empty() && !scenes_to_save.has(scene_path)) { - scenes_to_save.push_back(scene_path); + scenes_to_save.insert(scene_path); } } } @@ -2592,6 +2667,9 @@ void ScriptEditor::apply_scripts() const { } void ScriptEditor::reload_scripts(bool p_refresh_only) { + if (external_editor_active) { + return; + } for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { @@ -2699,6 +2777,10 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const Ref<Script> scr = p_obj->get_script(); ERR_FAIL_COND(!scr.is_valid()); + if (!scr->get_language()->can_make_function()) { + return; + } + EditorNode::get_singleton()->push_item(scr.ptr()); for (int i = 0; i < tab_container->get_tab_count(); i++) { @@ -2748,6 +2830,17 @@ void ScriptEditor::_save_layout() { } void ScriptEditor::_editor_settings_changed() { + if (!EditorThemeManager::is_generated_theme_outdated() && + !EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor") && + !EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor") && + !EditorSettings::get_singleton()->check_changed_settings_in_group("docks/filesystem")) { + return; + } + + _apply_editor_settings(); +} + +void ScriptEditor::_apply_editor_settings() { textfile_extensions.clear(); const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { @@ -2759,6 +2852,7 @@ void ScriptEditor::_editor_settings_changed() { members_overview_enabled = EDITOR_GET("text_editor/script_list/show_members_overview"); help_overview_enabled = EDITOR_GET("text_editor/help/show_help_index"); + external_editor_active = EDITOR_GET("text_editor/external/use_external_editor"); _update_members_overview_visibility(); _update_help_overview_visibility(); @@ -2771,6 +2865,10 @@ void ScriptEditor::_editor_settings_changed() { EditorSettings::get_singleton()->load_text_editor_theme(); } + _update_script_names(); + + ScriptServer::set_reload_scripts_on_save(EDITOR_GET("text_editor/behavior/files/auto_reload_and_parse_scripts_on_save")); + for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { @@ -2779,10 +2877,6 @@ void ScriptEditor::_editor_settings_changed() { se->update_settings(); } - _update_script_colors(); - _update_script_names(); - - ScriptServer::set_reload_scripts_on_save(EDITOR_GET("text_editor/behavior/files/auto_reload_and_parse_scripts_on_save")); } void ScriptEditor::_filesystem_changed() { @@ -2865,7 +2959,7 @@ void ScriptEditor::_tree_changed() { } waiting_update_names = true; - call_deferred(SNAME("_update_script_names")); + callable_mp(this, &ScriptEditor::_update_script_names).call_deferred(); } void ScriptEditor::_split_dragged(float) { @@ -2955,7 +3049,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data } for (int i = 0; i < files.size(); i++) { - String file = files[i]; + const String &file = files[i]; if (file.is_empty() || !FileAccess::exists(file)) { continue; } @@ -3035,7 +3129,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co } int num_tabs_before = tab_container->get_tab_count(); for (int i = 0; i < files.size(); i++) { - String file = files[i]; + const String &file = files[i]; if (file.is_empty() || !FileAccess::exists(file)) { continue; } @@ -3285,6 +3379,8 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { } } + _set_zoom_factor(p_layout->get_value("ScriptEditor", "zoom_factor", 1.0f)); + restoring_layout = false; _update_script_names(); @@ -3334,6 +3430,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { p_layout->set_value("ScriptEditor", "open_help", helps); p_layout->set_value("ScriptEditor", "script_split_offset", script_split->get_split_offset()); p_layout->set_value("ScriptEditor", "list_split_offset", list_split->get_split_offset()); + p_layout->set_value("ScriptEditor", "zoom_factor", zoom_factor); // Save the cache. script_editor_cache->save(EditorPaths::get_singleton()->get_project_settings_dir().path_join("script_editor_cache.cfg")); @@ -3361,6 +3458,7 @@ void ScriptEditor::_help_class_open(const String &p_class) { _go_to_tab(tab_container->get_tab_count() - 1); eh->go_to_class(p_class); eh->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto)); + eh->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history)); _add_recent_script(p_class); _sort_list_on_update = true; _update_script_names(); @@ -3378,7 +3476,6 @@ void ScriptEditor::_help_class_goto(const String &p_desc) { eh->set_name(cname); tab_container->add_child(eh); - _go_to_tab(tab_container->get_tab_count() - 1); eh->go_to_help(p_desc); eh->connect("go_to_help", callable_mp(this, &ScriptEditor::_help_class_goto)); _add_recent_script(eh->get_class()); @@ -3386,7 +3483,7 @@ void ScriptEditor::_help_class_goto(const String &p_desc) { _update_script_names(); _save_layout(); - call_deferred("_help_tab_goto", cname, p_desc); + callable_mp(this, &ScriptEditor::_help_tab_goto).call_deferred(cname, p_desc); } bool ScriptEditor::_help_tab_goto(const String &p_name, const String &p_desc) { @@ -3490,6 +3587,7 @@ void ScriptEditor::_update_history_pos(int p_new_pos) { ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(n); if (seb) { + lock_history = true; seb->set_edit_state(history[history_pos].state); seb->ensure_focus(); @@ -3499,9 +3597,10 @@ void ScriptEditor::_update_history_pos(int p_new_pos) { } } - if (Object::cast_to<EditorHelp>(n)) { - Object::cast_to<EditorHelp>(n)->set_scroll(history[history_pos].state); - Object::cast_to<EditorHelp>(n)->set_focused(); + EditorHelp *eh = Object::cast_to<EditorHelp>(n); + if (eh) { + eh->set_scroll(history[history_pos].state); + eh->set_focused(); } n->set_meta("__editor_pass", ++edit_pass); @@ -3555,7 +3654,7 @@ TypedArray<ScriptEditorBase> ScriptEditor::_get_open_script_editors() const { void ScriptEditor::set_scene_root_script(Ref<Script> p_script) { // Don't open dominant script if using an external editor. bool use_external_editor = - EDITOR_GET("text_editor/external/use_external_editor") || + external_editor_active || (p_script.is_valid() && p_script->get_language()->overrides_external_editor()); use_external_editor = use_external_editor && !(p_script.is_valid() && p_script->is_built_in()); // Ignore external editor for built-in scripts. const bool open_dominant = EDITOR_GET("text_editor/behavior/files/open_dominant_script_on_scene_change"); @@ -3579,7 +3678,7 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) { auto_reload_running_scripts = p_enabled; } -void ScriptEditor::_help_search(String p_text) { +void ScriptEditor::_help_search(const String &p_text) { help_search_dialog->popup_dialog(p_text); } @@ -3630,20 +3729,20 @@ void ScriptEditor::_script_changed() { NodeDock::get_singleton()->update_lists(); } -void ScriptEditor::_on_find_in_files_requested(String text) { +void ScriptEditor::_on_find_in_files_requested(const String &text) { find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::SEARCH_MODE); find_in_files_dialog->set_search_text(text); find_in_files_dialog->popup_centered(); } -void ScriptEditor::_on_replace_in_files_requested(String text) { +void ScriptEditor::_on_replace_in_files_requested(const String &text) { find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::REPLACE_MODE); find_in_files_dialog->set_search_text(text); find_in_files_dialog->set_replace_text(""); find_in_files_dialog->popup_centered(); } -void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) { +void ScriptEditor::_on_find_in_files_result_selected(const String &fpath, int line_number, int begin, int end) { if (ResourceLoader::exists(fpath)) { Ref<Resource> res = ResourceLoader::load(fpath); @@ -3715,6 +3814,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor()); if (ste) { + EditorInterface::get_singleton()->set_main_screen_editor("Script"); ste->goto_line_selection(line_number, begin, end); } } @@ -3729,6 +3829,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor()); if (ste) { + EditorInterface::get_singleton()->set_main_screen_editor("Script"); ste->goto_line_selection(line_number - 1, begin, end); } return; @@ -3762,14 +3863,44 @@ void ScriptEditor::_start_find_in_files(bool with_replace) { find_in_files->set_replace_text(find_in_files_dialog->get_replace_text()); find_in_files->start_search(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(find_in_files); + if (find_in_files_button->get_index() != find_in_files_button->get_parent()->get_child_count()) { + find_in_files_button->get_parent()->move_child(find_in_files_button, -1); + } + if (!find_in_files_button->is_visible()) { + find_in_files_button->show(); + } + + EditorNode::get_bottom_panel()->make_item_visible(find_in_files); } -void ScriptEditor::_on_find_in_files_modified_files(PackedStringArray paths) { +void ScriptEditor::_on_find_in_files_modified_files(const PackedStringArray &paths) { _test_script_times_on_disk(); _update_modified_scripts_for_external_editor(); } +void ScriptEditor::_set_zoom_factor(float p_zoom_factor) { + if (zoom_factor == p_zoom_factor) { + return; + } + zoom_factor = p_zoom_factor; + for (int i = 0; i < tab_container->get_tab_count(); i++) { + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); + if (se) { + CodeTextEditor *cte = se->get_code_editor(); + if (cte) { + if (zoom_factor != cte->get_zoom_factor()) { + cte->set_zoom_factor(zoom_factor); + } + } + } + } +} + +void ScriptEditor::_on_find_in_files_close_button_clicked() { + EditorNode::get_bottom_panel()->hide_bottom_panel(); + find_in_files_button->hide(); +} + void ScriptEditor::_window_changed(bool p_visible) { make_floating->set_visible(!p_visible); is_floating = p_visible; @@ -3784,18 +3915,7 @@ void ScriptEditor::_filter_methods_text_changed(const String &p_newtext) { } void ScriptEditor::_bind_methods() { - ClassDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab); - ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs); - ClassDB::bind_method("_close_other_tabs", &ScriptEditor::_close_other_tabs); - ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2); - ClassDB::bind_method("_copy_script_path", &ScriptEditor::_copy_script_path); - - ClassDB::bind_method("_help_class_open", &ScriptEditor::_help_class_open); ClassDB::bind_method("_help_tab_goto", &ScriptEditor::_help_tab_goto); - ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts); - ClassDB::bind_method("_update_members_overview", &ScriptEditor::_update_members_overview); - ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts); - ClassDB::bind_method("get_current_editor", &ScriptEditor::_get_current_editor); ClassDB::bind_method("get_open_script_editors", &ScriptEditor::_get_open_script_editors); @@ -3807,6 +3927,8 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts); ClassDB::bind_method(D_METHOD("open_script_create_dialog", "base_name", "base_path"), &ScriptEditor::open_script_create_dialog); + ClassDB::bind_method(D_METHOD("goto_help", "topic"), &ScriptEditor::goto_help); + ADD_SIGNAL(MethodInfo("editor_script_changed", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); } @@ -3823,6 +3945,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { waiting_update_names = false; pending_auto_reload = false; auto_reload_running_scripts = true; + external_editor_active = false; members_overview_enabled = EDITOR_GET("text_editor/script_list/show_members_overview"); help_overview_enabled = EDITOR_GET("text_editor/help/show_help_index"); @@ -3851,6 +3974,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { scripts_vbox->add_child(filter_scripts); script_list = memnew(ItemList); + script_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); scripts_vbox->add_child(script_list); script_list->set_custom_minimum_size(Size2(150, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing script_list->set_v_size_flags(SIZE_EXPAND_FILL); @@ -3895,6 +4019,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { overview_vbox->add_child(filter_methods); members_overview = memnew(ItemList); + members_overview->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); overview_vbox->add_child(members_overview); members_overview->set_allow_reselect(true); @@ -3903,6 +4028,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { members_overview->set_allow_rmb_select(true); help_overview = memnew(ItemList); + help_overview->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); overview_vbox->add_child(help_overview); help_overview->set_allow_reselect(true); help_overview->set_custom_minimum_size(Size2(0, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing @@ -3941,17 +4067,16 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::N), FILE_NEW_TEXTFILE); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::T), FILE_REOPEN_CLOSED); - file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT); recent_scripts = memnew(PopupMenu); - recent_scripts->set_name("RecentScripts"); - file_menu->get_popup()->add_child(recent_scripts); + file_menu->get_popup()->add_submenu_node_item(TTR("Open Recent"), recent_scripts, FILE_OPEN_RECENT); recent_scripts->connect("id_pressed", callable_mp(this, &ScriptEditor::_open_recent_script)); + _update_recent_scripts(); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KeyModifierMask::CMD_OR_CTRL | Key::S), FILE_SAVE); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::S), FILE_SAVE_AS); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KeyModifierMask::ALT | KeyModifierMask::CMD_OR_CTRL | Key::S), FILE_SAVE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As...")), FILE_SAVE_AS); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KeyModifierMask::SHIFT | KeyModifierMask::ALT | Key::S), FILE_SAVE_ALL); ED_SHORTCUT_OVERRIDE("script_editor/save_all", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::S); file_menu->get_popup()->add_separator(); @@ -3964,14 +4089,11 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KeyModifierMask::ALT | Key::RIGHT), WINDOW_NEXT); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_submenu_item(TTR("Theme"), "Theme", FILE_THEME); - theme_submenu = memnew(PopupMenu); - theme_submenu->set_name("Theme"); - file_menu->get_popup()->add_child(theme_submenu); - theme_submenu->connect("id_pressed", callable_mp(this, &ScriptEditor::_theme_option)); theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme...")), THEME_IMPORT); theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), THEME_RELOAD); + file_menu->get_popup()->add_submenu_node_item(TTR("Theme"), theme_submenu, FILE_THEME); + theme_submenu->connect("id_pressed", callable_mp(this, &ScriptEditor::_theme_option)); theme_submenu->add_separator(); theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), THEME_SAVE); @@ -4009,8 +4131,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { debugger->connect("set_execution", callable_mp(this, &ScriptEditor::_set_execution)); debugger->connect("clear_execution", callable_mp(this, &ScriptEditor::_clear_execution)); debugger->connect("breaked", callable_mp(this, &ScriptEditor::_breaked)); - debugger->get_default_debugger()->connect("set_breakpoint", callable_mp(this, &ScriptEditor::_set_breakpoint)); - debugger->get_default_debugger()->connect("clear_breakpoints", callable_mp(this, &ScriptEditor::_clear_breakpoints)); + debugger->connect("breakpoint_set_in_tree", callable_mp(this, &ScriptEditor::_set_breakpoint)); + debugger->connect("breakpoints_cleared_in_tree", callable_mp(this, &ScriptEditor::_clear_breakpoints)); menu_hb->add_spacer(); @@ -4054,24 +4176,25 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { script_forward->set_disabled(true); script_forward->set_tooltip_text(TTR("Go to next edited document.")); - if (p_wrapper->is_window_available()) { - menu_hb->add_child(memnew(VSeparator)); + menu_hb->add_child(memnew(VSeparator)); - make_floating = memnew(ScreenSelect); - make_floating->set_flat(true); + make_floating = memnew(ScreenSelect); + make_floating->set_flat(true); + make_floating->connect("request_open_in_screen", callable_mp(window_wrapper, &WindowWrapper::enable_window_on_screen).bind(true)); + if (!make_floating->is_disabled()) { + // Override default ScreenSelect tooltip if multi-window support is available. make_floating->set_tooltip_text(TTR("Make the script editor floating.")); - make_floating->connect("request_open_in_screen", callable_mp(window_wrapper, &WindowWrapper::enable_window_on_screen).bind(true)); - - menu_hb->add_child(make_floating); - p_wrapper->connect("window_visibility_changed", callable_mp(this, &ScriptEditor::_window_changed)); } + menu_hb->add_child(make_floating); + p_wrapper->connect("window_visibility_changed", callable_mp(this, &ScriptEditor::_window_changed)); + tab_container->connect("tab_changed", callable_mp(this, &ScriptEditor::_tab_changed)); erase_tab_confirm = memnew(ConfirmationDialog); erase_tab_confirm->set_ok_button_text(TTR("Save")); erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); - erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab).bind(true)); + erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab).bind(true, true)); erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab)); add_child(erase_tab_confirm); @@ -4099,6 +4222,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { disk_changed_list = memnew(Tree); vbc->add_child(disk_changed_list); + disk_changed_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts).bind(false)); @@ -4129,10 +4253,11 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files).bind(true)); add_child(find_in_files_dialog); find_in_files = memnew(FindInFilesPanel); - find_in_files_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Search Results"), find_in_files); + find_in_files_button = EditorNode::get_bottom_panel()->add_item(TTR("Search Results"), find_in_files, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_search_results_bottom_panel", TTR("Toggle Search Results Bottom Panel"))); find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE); find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, callable_mp(this, &ScriptEditor::_on_find_in_files_result_selected)); find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, callable_mp(this, &ScriptEditor::_on_find_in_files_modified_files)); + find_in_files->connect(FindInFilesPanel::SIGNAL_CLOSE_BUTTON_CLICKED, callable_mp(this, &ScriptEditor::_on_find_in_files_close_button_clicked)); find_in_files->hide(); find_in_files_button->hide(); @@ -4160,7 +4285,7 @@ void ScriptEditorPlugin::_focus_another_editor() { } } -void ScriptEditorPlugin::_save_last_editor(String p_editor) { +void ScriptEditorPlugin::_save_last_editor(const String &p_editor) { if (p_editor != get_name()) { last_editor = p_editor; } |