summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/code_editor.cpp24
-rw-r--r--editor/code_editor.h1
-rw-r--r--editor/editor_feature_profile.cpp17
-rw-r--r--editor/editor_node.cpp5
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp9
-rw-r--r--editor/plugins/script_editor_plugin.cpp72
-rw-r--r--editor/plugins/script_editor_plugin.h6
-rw-r--r--editor/project_manager.cpp104
-rw-r--r--editor/project_manager.h12
-rw-r--r--editor/scene_tree_dock.cpp29
-rw-r--r--editor/scene_tree_dock.h1
-rw-r--r--editor/script_editor_debugger.cpp20
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();