diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/code_editor.cpp | 24 | ||||
-rw-r--r-- | editor/code_editor.h | 1 | ||||
-rw-r--r-- | editor/editor_feature_profile.cpp | 17 | ||||
-rw-r--r-- | editor/editor_node.cpp | 5 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 9 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 72 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.h | 6 | ||||
-rw-r--r-- | editor/project_manager.cpp | 104 | ||||
-rw-r--r-- | editor/project_manager.h | 12 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 29 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 1 | ||||
-rw-r--r-- | editor/script_editor_debugger.cpp | 20 |
12 files changed, 206 insertions, 94 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index e471993fc7..8b3c537fe3 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -587,6 +587,26 @@ FindReplaceBar::FindReplaceBar() { /*** CODE EDITOR ****/ +// This function should be used to handle shortcuts that could otherwise +// be handled too late if they weren't handled here. +void CodeTextEditor::_input(const Ref<InputEvent> &event) { + + const Ref<InputEventKey> key_event = event; + if (!key_event.is_valid() || !key_event->is_pressed()) + return; + + if (ED_IS_SHORTCUT("script_text_editor/move_up", key_event)) { + move_lines_up(); + accept_event(); + return; + } + if (ED_IS_SHORTCUT("script_text_editor/move_down", key_event)) { + move_lines_down(); + accept_event(); + return; + } +} + void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; @@ -1375,6 +1395,9 @@ void CodeTextEditor::_notification(int p_what) { warning_button->set_icon(get_icon("NodeWarning", "EditorIcons")); add_constant_override("separation", 4 * EDSCALE); } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + set_process_input(is_visible_in_tree()); + } break; default: break; } @@ -1454,6 +1477,7 @@ void CodeTextEditor::remove_all_bookmarks() { void CodeTextEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("_input"), &CodeTextEditor::_input); ClassDB::bind_method("_text_editor_gui_input", &CodeTextEditor::_text_editor_gui_input); ClassDB::bind_method("_line_col_changed", &CodeTextEditor::_line_col_changed); ClassDB::bind_method("_text_changed", &CodeTextEditor::_text_changed); diff --git a/editor/code_editor.h b/editor/code_editor.h index 0ef8ec7061..ce219f340c 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -165,6 +165,7 @@ class CodeTextEditor : public VBoxContainer { void _font_resize_timeout(); bool _add_font_size(int p_delta); + void _input(const Ref<InputEvent> &event); void _text_editor_gui_input(const Ref<InputEvent> &p_event); void _zoom_in(); void _zoom_out(); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 36a8772faf..c6646eb28b 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -42,7 +42,7 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("Scene Tree Editing"), TTRC("Import Dock"), TTRC("Node Dock"), - TTRC("Filesystem Dock") + TTRC("FileSystem and Import Docks") }; const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { @@ -378,18 +378,21 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { switch (p_action) { case PROFILE_CLEAR: { + EditorSettings::get_singleton()->set("_default_feature_profile", ""); EditorSettings::get_singleton()->save(); current_profile = ""; current.unref(); + _update_profile_list(); + _emit_current_profile_changed(); } break; case PROFILE_SET: { String selected = _get_selected_profile(); ERR_FAIL_COND(selected == String()); if (selected == current_profile) { - return; //nothing to do here + return; // Nothing to do here. } EditorSettings::get_singleton()->set("_default_feature_profile", selected); EditorSettings::get_singleton()->save(); @@ -397,7 +400,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { current = edited; _update_profile_list(); - + _emit_current_profile_changed(); } break; case PROFILE_IMPORT: { @@ -415,6 +418,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { new_profile_name->grab_focus(); } break; case PROFILE_ERASE: { + String selected = _get_selected_profile(); ERR_FAIL_COND(selected == String()); @@ -809,7 +813,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { profile_actions[PROFILE_CLEAR]->set_disabled(true); profile_actions[PROFILE_CLEAR]->connect("pressed", this, "_profile_action", varray(PROFILE_CLEAR)); - main_vbc->add_margin_child(TTR("Current Profile"), name_hbc); + main_vbc->add_margin_child(TTR("Current Profile:"), name_hbc); HBoxContainer *profiles_hbc = memnew(HBoxContainer); profile_list = memnew(OptionButton); @@ -844,7 +848,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { profile_actions[PROFILE_EXPORT]->set_disabled(true); profile_actions[PROFILE_EXPORT]->connect("pressed", this, "_profile_action", varray(PROFILE_EXPORT)); - main_vbc->add_margin_child(TTR("Available Profiles"), profiles_hbc); + main_vbc->add_margin_child(TTR("Available Profiles:"), profiles_hbc); h_split = memnew(HSplitContainer); h_split->set_v_size_flags(SIZE_EXPAND_FILL); @@ -855,9 +859,8 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { class_list_vbc->set_h_size_flags(SIZE_EXPAND_FILL); class_list = memnew(Tree); - class_list_vbc->add_margin_child(TTR("Enabled Classes"), class_list, true); + class_list_vbc->add_margin_child(TTR("Enabled Classes:"), class_list, true); class_list->set_hide_root(true); - class_list->set_hide_folding(true); class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); class_list->connect("cell_selected", this, "_class_list_item_selected"); class_list->connect("item_edited", this, "_class_list_item_edited", varray(), CONNECT_DEFERRED); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b6d28dce29..2d2f67314d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5044,7 +5044,9 @@ void EditorNode::_feature_profile_changed() { main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); main_editor_buttons[EDITOR_ASSETLIB]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB)); - if (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB)) { + if ((profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) && singleton->main_editor_buttons[EDITOR_3D]->is_pressed()) || + (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) && singleton->main_editor_buttons[EDITOR_SCRIPT]->is_pressed()) || + (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) { _editor_select(EDITOR_2D); } } else { @@ -5056,6 +5058,7 @@ void EditorNode::_feature_profile_changed() { node_dock->set_visible(true); filesystem_dock->set_visible(true); main_editor_buttons[EDITOR_3D]->set_visible(true); + main_editor_buttons[EDITOR_SCRIPT]->set_visible(true); main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index fbf01a9405..3c24fd19b6 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -731,6 +731,8 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 ERR_FAIL_COND_V(!p_control, Vector2()); Rect2 parent_rect = p_control->get_parent_anchorable_rect(); + ERR_FAIL_COND_V(parent_rect.size.x == 0, Vector2()); + ERR_FAIL_COND_V(parent_rect.size.y == 0, Vector2()); return (p_control->get_transform().xform(position) - parent_rect.position) / parent_rect.size; } @@ -3348,9 +3350,6 @@ void CanvasItemEditor::_notification(int p_what) { presets_menu->set_visible(true); anchor_mode_button->set_visible(true); - // Set the pressed state of the node - anchor_mode_button->set_pressed(anchors_mode); - // Disable if the selected node is child of a container if (has_container_parents) { presets_menu->set_disabled(true); @@ -3521,6 +3520,7 @@ void CanvasItemEditor::_selection_changed() { } } anchors_mode = (nbValidControls == nbAnchorsMode); + anchor_mode_button->set_pressed(anchors_mode); } void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { @@ -3742,6 +3742,7 @@ void CanvasItemEditor::_set_anchors_and_margins_preset(Control::LayoutPreset p_p undo_redo->commit_action(); anchors_mode = false; + anchor_mode_button->set_pressed(anchors_mode); } void CanvasItemEditor::_set_anchors_and_margins_to_keep_ratio() { @@ -3766,6 +3767,7 @@ void CanvasItemEditor::_set_anchors_and_margins_to_keep_ratio() { undo_redo->add_undo_method(control, "set_meta", "_edit_use_anchors_", use_anchors); anchors_mode = true; + anchor_mode_button->set_pressed(anchors_mode); } } @@ -3912,7 +3914,6 @@ void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) { } anchors_mode = p_status; - viewport->update(); } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index df9ce73914..b4719b2e6d 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1249,7 +1249,7 @@ void ScriptEditor::_menu_option(int p_option) { if (p_option >= WINDOW_SELECT_BASE) { tab_container->set_current_tab(p_option - WINDOW_SELECT_BASE); - script_list->select(p_option - WINDOW_SELECT_BASE); + _update_script_names(); } } } @@ -1376,6 +1376,8 @@ void ScriptEditor::_notification(int p_what) { script_forward->set_icon(get_icon("Forward", "EditorIcons")); script_back->set_icon(get_icon("Back", "EditorIcons")); members_overview_alphabeta_sort_button->set_icon(get_icon("Sort", "EditorIcons")); + filter_scripts->set_right_icon(get_icon("Search", "EditorIcons")); + filter_methods->set_right_icon(get_icon("Search", "EditorIcons")); } break; case NOTIFICATION_READY: { @@ -1633,8 +1635,12 @@ void ScriptEditor::_update_members_overview() { } for (int i = 0; i < functions.size(); i++) { - members_overview->add_item(functions[i].get_slice(":", 0)); - members_overview->set_item_metadata(i, functions[i].get_slice(":", 1).to_int() - 1); + String filter = filter_methods->get_text(); + String name = functions[i].get_slice(":", 0); + if (filter == "" || filter.is_subsequence_ofi(name)) { + members_overview->add_item(name); + members_overview->set_item_metadata(members_overview->get_item_count() - 1, functions[i].get_slice(":", 1).to_int() - 1); + } } String path = se->get_edited_resource()->get_path(); @@ -1853,20 +1859,26 @@ void ScriptEditor::_update_script_names() { _sort_list_on_update = false; } + Vector<_ScriptEditorItemData> sedata_filtered; for (int i = 0; i < sedata.size(); i++) { + String filter = filter_scripts->get_text(); + if (filter == "" || filter.is_subsequence_ofi(sedata[i].name)) { + sedata_filtered.push_back(sedata[i]); + } + } - script_list->add_item(sedata[i].name, sedata[i].icon); + for (int i = 0; i < sedata_filtered.size(); i++) { + script_list->add_item(sedata_filtered[i].name, sedata_filtered[i].icon); int index = script_list->get_item_count() - 1; - script_list->set_item_tooltip(index, sedata[i].tooltip); - script_list->set_item_metadata(index, sedata[i].index); - if (sedata[i].used) { - + script_list->set_item_tooltip(index, sedata_filtered[i].tooltip); + script_list->set_item_metadata(index, sedata_filtered[i].index); /* Saving as metadata the script's index in the tab container and not the filtered one */ + if (sedata_filtered[i].used) { script_list->set_item_custom_bg_color(index, Color(88 / 255.0, 88 / 255.0, 60 / 255.0)); } - if (tab_container->get_current_tab() == sedata[i].index) { + if (tab_container->get_current_tab() == sedata_filtered[i].index) { script_list->select(index); - script_name_label->set_text(sedata[i].name); - script_icon->set_texture(sedata[i].icon); + script_name_label->set_text(sedata_filtered[i].name); + script_icon->set_texture(sedata_filtered[i].icon); } } @@ -2049,7 +2061,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra if (should_open) { if (tab_container->get_current_tab() != i) { _go_to_tab(i); - script_list->select(script_list->find_metadata(i)); + _update_script_names(); } if (is_visible_in_tree()) se->ensure_focus(); @@ -2427,7 +2439,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node); EditorHelp *eh = Object::cast_to<EditorHelp>(node); if (se || eh) { - int new_index = script_list->get_item_at_position(p_point); + int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); tab_container->move_child(node, new_index); tab_container->set_current_tab(new_index); _update_script_names(); @@ -2444,7 +2456,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node); EditorHelp *eh = Object::cast_to<EditorHelp>(node); if (se || eh) { - int new_index = script_list->get_item_at_position(p_point); + int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); tab_container->move_child(node, new_index); tab_container->set_current_tab(new_index); _update_script_names(); @@ -2455,7 +2467,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co Vector<String> files = d["files"]; - int new_index = script_list->get_item_at_position(p_point); + int new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point)); int num_tabs_before = tab_container->get_child_count(); for (int i = 0; i < files.size(); i++) { String file = files[i]; @@ -2467,7 +2479,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co if (tab_container->get_child_count() > num_tabs_before) { tab_container->move_child(tab_container->get_child(tab_container->get_child_count() - 1), new_index); num_tabs_before = tab_container->get_child_count(); - } else { + } else { /* Maybe script was already open */ tab_container->move_child(tab_container->get_child(tab_container->get_current_tab()), new_index); } } @@ -2962,6 +2974,14 @@ void ScriptEditor::_on_find_in_files_modified_files(PoolStringArray paths) { _update_modified_scripts_for_external_editor(); } +void ScriptEditor::_filter_scripts_text_changed(const String &p_newtext) { + _update_script_names(); +} + +void ScriptEditor::_filter_methods_text_changed(const String &p_newtext) { + _update_members_overview(); +} + void ScriptEditor::_bind_methods() { ClassDB::bind_method("_file_dialog_action", &ScriptEditor::_file_dialog_action); @@ -3013,6 +3033,8 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_toggle_members_overview_alpha_sort", &ScriptEditor::_toggle_members_overview_alpha_sort); ClassDB::bind_method("_update_members_overview", &ScriptEditor::_update_members_overview); ClassDB::bind_method("_script_changed", &ScriptEditor::_script_changed); + ClassDB::bind_method("_filter_scripts_text_changed", &ScriptEditor::_filter_scripts_text_changed); + ClassDB::bind_method("_filter_methods_text_changed", &ScriptEditor::_filter_methods_text_changed); ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts); ClassDB::bind_method("_on_find_in_files_requested", &ScriptEditor::_on_find_in_files_requested); ClassDB::bind_method("_start_find_in_files", &ScriptEditor::_start_find_in_files); @@ -3059,8 +3081,18 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { script_split->add_child(list_split); list_split->set_v_size_flags(SIZE_EXPAND_FILL); + scripts_vbox = memnew(VBoxContainer); + scripts_vbox->set_v_size_flags(SIZE_EXPAND_FILL); + list_split->add_child(scripts_vbox); + + filter_scripts = memnew(LineEdit); + filter_scripts->set_placeholder(TTR("Filter scripts")); + filter_scripts->set_clear_button_enabled(true); + filter_scripts->connect("text_changed", this, "_filter_scripts_text_changed"); + scripts_vbox->add_child(filter_scripts); + script_list = memnew(ItemList); - list_split->add_child(script_list); + scripts_vbox->add_child(script_list); script_list->set_custom_minimum_size(Size2(150, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(140); @@ -3096,6 +3128,12 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { buttons_hbox->add_child(members_overview_alphabeta_sort_button); + filter_methods = memnew(LineEdit); + filter_methods->set_placeholder(TTR("Filter methods")); + filter_methods->set_clear_button_enabled(true); + filter_methods->connect("text_changed", this, "_filter_methods_text_changed"); + overview_vbox->add_child(filter_methods); + members_overview = memnew(ItemList); overview_vbox->add_child(members_overview); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 549af1ca31..0d9168261a 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -38,6 +38,7 @@ #include "editor/editor_plugin.h" #include "editor/script_create_dialog.h" #include "scene/gui/item_list.h" +#include "scene/gui/line_edit.h" #include "scene/gui/menu_button.h" #include "scene/gui/split_container.h" #include "scene/gui/tab_container.h" @@ -213,6 +214,9 @@ class ScriptEditor : public PanelContainer { ItemList *script_list; HSplitContainer *script_split; ItemList *members_overview; + LineEdit *filter_scripts; + LineEdit *filter_methods; + VBoxContainer *scripts_vbox; VBoxContainer *overview_vbox; HBoxContainer *buttons_hbox; Label *filename; @@ -341,6 +345,8 @@ class ScriptEditor : public PanelContainer { void _update_members_overview_visibility(); void _update_members_overview(); void _toggle_members_overview_alpha_sort(bool p_alphabetic_sort); + void _filter_scripts_text_changed(const String &p_newtext); + void _filter_methods_text_changed(const String &p_newtext); void _update_script_names(); void _update_script_connections(); bool _sort_list_on_update; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 9a3991bef1..4b3d468a61 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -919,28 +919,37 @@ public: struct ProjectItem { String project; + String project_name; String path; String conf; - int config_version; + String icon; + String main_scene; uint64_t last_modified; bool favorite; bool grayed; - bool ordered_latest_modification; + ProjectListFilter::FilterOption filter_order_option; ProjectItem() {} - ProjectItem(const String &p_project, const String &p_path, const String &p_conf, int p_config_version, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) { + ProjectItem(const String &p_project, const String &p_name, const String &p_path, const String &p_conf, const String &p_icon, const String &p_main_scene, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const ProjectListFilter::FilterOption p_filter_order_option = ProjectListFilter::FILTER_NAME) { project = p_project; + project_name = p_name; path = p_path; conf = p_conf; - config_version = p_config_version; + icon = p_icon; + main_scene = p_main_scene; last_modified = p_last_modified; favorite = p_favorite; grayed = p_grayed; - ordered_latest_modification = p_ordered_latest_modification; + filter_order_option = p_filter_order_option; } _FORCE_INLINE_ bool operator<(const ProjectItem &l) const { - if (ordered_latest_modification) - return last_modified > l.last_modified; - return project < l.project; + switch (filter_order_option) { + case ProjectListFilter::FILTER_PATH: + return project < l.project; + case ProjectListFilter::FILTER_MODIFIED: + return last_modified > l.last_modified; + default: + return project_name < l.project_name; + } } _FORCE_INLINE_ bool operator==(const ProjectItem &l) const { return project == l.project; } }; @@ -1256,13 +1265,7 @@ void ProjectManager::_load_recent_projects() { Color font_color = gui_base->get_color("font_color", "Tree"); - bool set_ordered_latest_modification; ProjectListFilter::FilterOption filter_order_option = project_order_filter->get_filter_option(); - if (filter_order_option == ProjectListFilter::FILTER_NAME) { - set_ordered_latest_modification = false; - } else { - set_ordered_latest_modification = true; - } EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)filter_order_option); List<ProjectItem> projects; @@ -1280,10 +1283,30 @@ void ProjectManager::_load_recent_projects() { String project = _name.get_slice("/", 1); String conf = path.plus_file("project.godot"); - int config_version = 0; // Assume 0 until we know better bool favorite = (_name.begins_with("favorite_projects/")) ? true : false; bool grayed = false; + Ref<ConfigFile> cf = memnew(ConfigFile); + Error cf_err = cf->load(conf); + + int config_version = 0; + String project_name = TTR("Unnamed Project"); + if (cf_err == OK) { + + String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", "")); + if (cf_project_name != "") + project_name = cf_project_name.xml_unescape(); + config_version = (int)cf->get_value("", "config_version", 0); + } + + if (config_version > ProjectSettings::CONFIG_VERSION) { + // Comes from an incompatible (more recent) Godot version, grey it out + grayed = true; + } + + String icon = cf->get_value("application", "config/icon", ""); + String main_scene = cf->get_value("application", "run/main_scene", ""); + uint64_t last_modified = 0; if (FileAccess::exists(conf)) { last_modified = FileAccess::get_modified_time(conf); @@ -1298,7 +1321,7 @@ void ProjectManager::_load_recent_projects() { grayed = true; } - ProjectItem item(project, path, conf, config_version, last_modified, favorite, grayed, set_ordered_latest_modification); + ProjectItem item(project, project_name, path, conf, icon, main_scene, last_modified, favorite, grayed, filter_order_option); if (favorite) favorite_projects.push_back(item); else @@ -1326,43 +1349,23 @@ void ProjectManager::_load_recent_projects() { String path = item.path; String conf = item.conf; - Ref<ConfigFile> cf = memnew(ConfigFile); - Error cf_err = cf->load(conf); - - String project_name = TTR("Unnamed Project"); - if (cf_err == OK && cf->has_section_key("application", "config/name")) { - project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape(); - } - - if (filter_option == ProjectListFilter::FILTER_NAME && search_term != "" && project_name.findn(search_term) == -1) + if (filter_option == ProjectListFilter::FILTER_NAME && search_term != "" && item.project_name.findn(search_term) == -1) continue; Ref<Texture> icon; - String main_scene; - - if (cf_err == OK) { - item.config_version = (int)cf->get_value("", "config_version", 0); - if (item.config_version > ProjectSettings::CONFIG_VERSION) { - // Comes from an incompatible (more recent) Godot version, grey it out - item.grayed = true; - } - String appicon = cf->get_value("application", "config/icon", ""); - if (appicon != "") { - Ref<Image> img; - img.instance(); - Error err = img->load(appicon.replace_first("res://", path + "/")); - if (err == OK) { - - Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons"); - img->resize(default_icon->get_width(), default_icon->get_height()); - Ref<ImageTexture> it = memnew(ImageTexture); - it->create_from_image(img); - icon = it; - } + if (item.icon != "") { + Ref<Image> img; + img.instance(); + Error err = img->load(item.icon.replace_first("res://", path + "/")); + if (err == OK) { + + Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons"); + img->resize(default_icon->get_width(), default_icon->get_height()); + Ref<ImageTexture> it = memnew(ImageTexture); + it->create_from_image(img); + icon = it; } - - main_scene = cf->get_value("application", "run/main_scene", ""); } if (icon.is_null()) { @@ -1376,7 +1379,7 @@ void ProjectManager::_load_recent_projects() { HBoxContainer *hb = memnew(HBoxContainer); hb->set_meta("name", project); - hb->set_meta("main_scene", main_scene); + hb->set_meta("main_scene", item.main_scene); hb->set_meta("favorite", is_favorite); hb->connect("draw", this, "_panel_draw", varray(hb)); hb->connect("gui_input", this, "_panel_input", varray(hb)); @@ -1406,7 +1409,7 @@ void ProjectManager::_load_recent_projects() { ec->set_custom_minimum_size(Size2(0, 1)); ec->set_mouse_filter(MOUSE_FILTER_PASS); vb->add_child(ec); - Label *title = memnew(Label(project_name)); + Label *title = memnew(Label(item.project_name)); title->add_font_override("font", gui_base->get_font("title", "EditorFonts")); title->add_color_override("font_color", font_color); title->set_clip_text(true); @@ -2020,6 +2023,7 @@ ProjectManager::ProjectManager() { sort_filters->add_child(sort_label); Vector<String> sort_filter_titles; sort_filter_titles.push_back("Name"); + sort_filter_titles.push_back("Path"); sort_filter_titles.push_back("Last Modified"); project_order_filter = memnew(ProjectListFilter); project_order_filter->_setup_filters(sort_filter_titles); diff --git a/editor/project_manager.h b/editor/project_manager.h index a7cc6549f5..d75d7164cc 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -131,17 +131,19 @@ class ProjectListFilter : public HBoxContainer { GDCLASS(ProjectListFilter, HBoxContainer); +public: + enum FilterOption { + FILTER_NAME, + FILTER_PATH, + FILTER_MODIFIED, + }; + private: friend class ProjectManager; OptionButton *filter_option; LineEdit *search_box; bool has_search_box; - - enum FilterOption { - FILTER_NAME, - FILTER_PATH, - }; FilterOption _current_filter; void _search_text_changed(const String &p_newtext); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index e8f5139cd5..a15ae2efda 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -269,7 +269,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) bool SceneTreeDock::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { int childCount = p_desired_node->get_child_count(); - if (p_desired_node->get_filename() == p_target_scene_path) { + if (_track_inherit(p_target_scene_path, p_desired_node)) { return true; } @@ -284,6 +284,33 @@ bool SceneTreeDock::_cyclical_dependency_exists(const String &p_target_scene_pat return false; } +bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_desired_node) { + Node *p = p_desired_node; + bool result = false; + Vector<Node *> instances; + while (true) { + if (p->get_filename() == p_target_scene_path) { + result = true; + break; + } + Ref<SceneState> ss = p->get_scene_inherited_state(); + if (ss.is_valid()) { + String path = ss->get_path(); + Ref<PackedScene> data = ResourceLoader::load(path); + if (data.is_valid()) { + p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + instances.push_back(p); + } else + break; + } else + break; + } + for (int i = 0; i < instances.size(); i++) { + memdelete(instances[i]); + } + return result; +} + void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { current_option = p_tool; diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 9f9e93f2df..b645c22295 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -165,6 +165,7 @@ class SceneTreeDock : public VBoxContainer { void _script_open_request(const Ref<Script> &p_script); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); + bool _track_inherit(const String &p_target_scene_path, Node *p_desired_node); void _node_selected(); void _node_renamed(); diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 3b086c6316..3167abb745 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -1121,10 +1121,13 @@ void ScriptEditorDebugger::_notification(int p_what) { last_warning_count = warning_count; } - if (connection.is_null()) { - - if (server->is_connection_available()) { - + if (server->is_connection_available()) { + if (connection.is_valid()) { + // We already have a valid connection. Disconnecting any new connecting client to prevent it from hanging. + // (If we don't keep a reference to the connection it will be destroyed and disconnect_from_host will be called internally) + server->take_connection(); + } else { + // We just got the first connection. connection = server->take_connection(); if (connection.is_null()) break; @@ -1158,12 +1161,11 @@ void ScriptEditorDebugger::_notification(int p_what) { if (profiler->is_profiling()) { _profiler_activate(true); } - - } else { - - break; } - }; + } + + if (connection.is_null()) + break; if (!connection->is_connected_to_host()) { stop(); |