summaryrefslogtreecommitdiff
path: root/editor/scene_tree_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/scene_tree_editor.cpp')
-rw-r--r--editor/scene_tree_editor.cpp69
1 files changed, 48 insertions, 21 deletions
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 32d43d7c59..b977b012a8 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/node_dock.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -268,7 +269,17 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
String warning = p_node->get_configuration_warnings_as_string();
if (!warning.is_empty()) {
- item->add_button(0, get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning);
+ const int num_warnings = p_node->get_configuration_warnings().size();
+ String warning_icon;
+ if (num_warnings == 1) {
+ warning_icon = SNAME("NodeWarning");
+ } else if (num_warnings <= 3) {
+ warning_icon = vformat("NodeWarnings%d", num_warnings);
+ } else {
+ warning_icon = SNAME("NodeWarnings4Plus");
+ }
+
+ item->add_button(0, get_theme_icon(warning_icon, SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning);
}
if (p_node->is_unique_name_in_owner()) {
@@ -355,10 +366,10 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_tooltip(0, tooltip);
}
- if (can_open_instance && undo_redo) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes
+ if (can_open_instance && undo_redo.is_valid()) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes
if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) {
- p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed), varray(p_node));
+ p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed).bind(p_node));
}
Ref<Script> script = p_node->get_script();
@@ -375,7 +386,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (p_node->has_meta("_edit_group_")) {
- item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable."));
+ item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
}
bool v = p_node->call("is_visible");
@@ -386,11 +397,11 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
- p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node));
+ p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node));
}
_update_visibility_color(p_node, item);
- } else if (p_node->is_class("CanvasLayer")) {
+ } else if (p_node->is_class("CanvasLayer") || p_node->is_class("Window")) {
bool v = p_node->call("is_visible");
if (v) {
item->add_button(0, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
@@ -399,7 +410,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
- p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node));
+ p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node));
}
} else if (p_node->is_class("Node3D")) {
if (p_node->has_meta("_edit_lock_")) {
@@ -407,7 +418,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (p_node->has_meta("_edit_group_")) {
- item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable."));
+ item->add_button(0, get_theme_icon(SNAME("Group"), SNAME("EditorIcons")), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make them selectable."));
}
bool v = p_node->call("is_visible");
@@ -418,7 +429,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
- p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node));
+ p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed).bind(p_node));
}
_update_visibility_color(p_node, item);
@@ -480,10 +491,7 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
bool visible = false;
- if (p_node->is_class("CanvasItem")) {
- visible = p_node->call("is_visible");
- CanvasItemEditor::get_singleton()->get_viewport_control()->update();
- } else if (p_node->is_class("CanvasLayer")) {
+ if (p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer") || p_node->is_class("Window")) {
visible = p_node->call("is_visible");
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
} else if (p_node->is_class("Node3D")) {
@@ -529,7 +537,7 @@ void SceneTreeEditor::_node_removed(Node *p_node) {
p_node->disconnect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed));
}
- if (p_node->is_class("Node3D") || p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer")) {
+ if (p_node->is_class("Node3D") || p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer") || p_node->is_class("Window")) {
if (p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
p_node->disconnect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed));
}
@@ -584,13 +592,20 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select
p_parent = tree->get_root();
}
+ if (!p_parent) {
+ // Tree is empty, nothing to do here.
+ return false;
+ }
+
bool keep = false;
for (TreeItem *child = p_parent->get_first_child(); child; child = child->get_next()) {
keep = _update_filter(child, p_scroll_to_selected) || keep;
}
if (!keep) {
- keep = filter.is_subsequence_ofn(p_parent->get_text(0));
+ StringName node_type = get_node(p_parent->get_metadata(0))->get_class();
+ bool is_kept_by_type = (filter.begins_with("type:") && filter.trim_prefix("type:").is_subsequence_ofn(node_type)) || (filter.begins_with("t:") && filter.trim_prefix("t:").is_subsequence_ofn(node_type));
+ keep = (filter.is_subsequence_ofn(p_parent->get_text(0)) || is_kept_by_type);
}
p_parent->set_visible(keep);
@@ -728,7 +743,7 @@ void SceneTreeEditor::_notification(int p_what) {
get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed));
get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
- get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed), varray(), CONNECT_DEFERRED);
+ get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed), CONNECT_DEFERRED);
tree->connect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed));
@@ -871,7 +886,7 @@ void SceneTreeEditor::_renamed() {
return;
}
- if (!undo_redo) {
+ if (!undo_redo.is_valid()) {
n->set_name(new_name);
which->set_metadata(0, n->get_path());
emit_signal(SNAME("node_renamed"));
@@ -915,6 +930,10 @@ String SceneTreeEditor::get_filter() const {
return filter;
}
+void SceneTreeEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
+ undo_redo = p_undo_redo;
+}
+
void SceneTreeEditor::set_display_foreign_nodes(bool p_display) {
display_foreign = p_display;
_update_tree();
@@ -1246,7 +1265,6 @@ void SceneTreeEditor::_bind_methods() {
}
SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_open_instance) {
- undo_redo = nullptr;
selected = nullptr;
can_rename = p_can_rename;
@@ -1296,7 +1314,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
blocked = 0;
update_timer = memnew(Timer);
- update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree), varray(false));
+ update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree).bind(false));
update_timer->set_one_shot(true);
update_timer->set_wait_time(0.5);
add_child(update_timer);
@@ -1348,11 +1366,16 @@ void SceneTreeDialog::_cancel() {
void SceneTreeDialog::_select() {
if (tree->get_selected()) {
- emit_signal(SNAME("selected"), tree->get_selected()->get_path());
+ // The signal may cause another dialog to be displayed, so be sure to hide this one first.
hide();
+ emit_signal(SNAME("selected"), tree->get_selected()->get_path());
}
}
+void SceneTreeDialog::_selected_changed() {
+ get_ok_button()->set_disabled(!tree->get_selected());
+}
+
void SceneTreeDialog::_filter_changed(const String &p_filter) {
tree->set_filter(p_filter);
}
@@ -1370,7 +1393,7 @@ SceneTreeDialog::SceneTreeDialog() {
filter = memnew(LineEdit);
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- filter->set_placeholder(TTR("Filter nodes"));
+ filter->set_placeholder(TTR("Filter Nodes"));
filter->set_clear_button_enabled(true);
filter->add_theme_constant_override("minimum_character_width", 0);
filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed));
@@ -1380,6 +1403,10 @@ SceneTreeDialog::SceneTreeDialog() {
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tree->get_scene_tree()->connect("item_activated", callable_mp(this, &SceneTreeDialog::_select));
vbc->add_child(tree);
+
+ // Disable the OK button when no node is selected.
+ get_ok_button()->set_disabled(!tree->get_selected());
+ tree->connect("node_selected", callable_mp(this, &SceneTreeDialog::_selected_changed));
}
SceneTreeDialog::~SceneTreeDialog() {