diff options
Diffstat (limited to 'editor/gui/scene_tree_editor.cpp')
-rw-r--r-- | editor/gui/scene_tree_editor.cpp | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index d07e5dfa1a..0862af37b6 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -234,7 +234,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT); } else { //has no script (or script is a custom type) - item->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); item->set_selectable(0, false); if (!scr.is_null()) { // make sure to mark the script if a custom type @@ -251,11 +251,11 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { node_name += " " + TTR("(Connecting From)"); } item->set_text(0, node_name); - item->set_custom_color(0, accent); + _set_item_custom_color(item, accent); } } else if (part_of_subscene) { if (valid_types.size() == 0) { - item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } } else if (marked.has(p_node)) { String node_name = p_node->get_name(); @@ -264,15 +264,15 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } item->set_text(0, node_name); item->set_selectable(0, marked_selectable); - item->set_custom_color(0, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); } else if (!p_node->can_process()) { - item->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); } else if (!marked_selectable && !marked_children_selectable) { Node *node = p_node; while (node) { if (marked.has(node)) { item->set_selectable(0, false); - item->set_custom_color(0, get_theme_color(SNAME("error_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("error_color"), SNAME("Editor"))); break; } node = node->get_parent(); @@ -500,7 +500,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (!valid) { - item->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + _set_item_custom_color(item, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); item->set_selectable(0, false); } } @@ -550,6 +550,11 @@ void SceneTreeEditor::_update_visibility_color(Node *p_node, TreeItem *p_item) { } } +void SceneTreeEditor::_set_item_custom_color(TreeItem *p_item, Color p_color) { + p_item->set_custom_color(0, p_color); + p_item->set_meta(SNAME("custom_color"), p_color); +} + void SceneTreeEditor::_node_script_changed(Node *p_node) { if (tree_dirty) { return; @@ -613,7 +618,7 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { updating_tree = false; tree_dirty = false; - if (!filter.strip_edges().is_empty()) { + if (!filter.strip_edges().is_empty() || !show_all_nodes) { _update_filter(nullptr, p_scroll_to_selected); } } @@ -639,22 +644,34 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select PackedStringArray terms = filter.to_lower().split_spaces(); bool keep = _item_matches_all_terms(p_parent, terms); - p_parent->set_visible(keep_for_children || keep); + bool selectable = keep; if (keep && !valid_types.is_empty()) { - keep = false; + selectable = false; Node *n = get_node(p_parent->get_metadata(0)); for (const StringName &E : valid_types) { if (n->is_class(E) || EditorNode::get_singleton()->is_object_of_custom_type(n, E)) { - keep = true; + selectable = true; break; } } } - if (keep) { - p_parent->clear_custom_color(0); + if (show_all_nodes) { + p_parent->set_visible(keep_for_children || keep); + } else { + // Show only selectable nodes, or parents of selectable. + p_parent->set_visible(keep_for_children || selectable); + } + + if (selectable) { + Color custom_color = p_parent->get_meta(SNAME("custom_color"), Color(0, 0, 0, 0)); + if (custom_color == Color(0, 0, 0, 0)) { + p_parent->clear_custom_color(0); + } else { + p_parent->set_custom_color(0, custom_color); + } p_parent->set_selectable(0, true); } else if (keep_for_children) { p_parent->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); @@ -664,7 +681,7 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select if (editor_selection) { Node *n = get_node(p_parent->get_metadata(0)); - if (keep) { + if (selectable) { if (p_scroll_to_selected && n && editor_selection->is_selected(n)) { tree->scroll_to_item(p_parent); } @@ -676,7 +693,7 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } } - return keep || keep_for_children; + return p_parent->is_visible(); } bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, PackedStringArray p_terms) { @@ -1086,6 +1103,11 @@ String SceneTreeEditor::get_filter_term_warning() { return filter_term_warning; } +void SceneTreeEditor::set_show_all_nodes(bool p_show_all_nodes) { + show_all_nodes = p_show_all_nodes; + _update_filter(nullptr, true); +} + void SceneTreeEditor::set_as_scene_tree_dock() { is_scene_tree_dock = true; } @@ -1494,6 +1516,11 @@ void SceneTreeDialog::popup_scenetree_dialog() { popup_centered_clamped(Size2(350, 700) * EDSCALE); } +void SceneTreeDialog::_show_all_nodes_changed(bool p_button_pressed) { + EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "show_all_nodes_for_node_selection", p_button_pressed); + tree->set_show_all_nodes(p_button_pressed); +} + void SceneTreeDialog::set_valid_types(const Vector<StringName> &p_valid) { if (p_valid.is_empty()) { return; @@ -1531,6 +1558,8 @@ void SceneTreeDialog::set_valid_types(const Vector<StringName> &p_valid) { label->set_text(type); label->set_auto_translate(false); } + + show_all_nodes->show(); } void SceneTreeDialog::_update_theme() { @@ -1598,17 +1627,31 @@ SceneTreeDialog::SceneTreeDialog() { content = memnew(VBoxContainer); add_child(content); + HBoxContainer *filter_hbc = memnew(HBoxContainer); + content->add_child(filter_hbc); + filter = memnew(LineEdit); filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); 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)); - content->add_child(filter); + filter_hbc->add_child(filter); + + // Add 'Show All' button to HBoxContainer next to the filter, visible only when valid_types is defined. + show_all_nodes = memnew(CheckButton); + show_all_nodes->set_text(TTR("Show All")); + show_all_nodes->connect("toggled", callable_mp(this, &SceneTreeDialog::_show_all_nodes_changed)); + show_all_nodes->set_h_size_flags(Control::SIZE_SHRINK_BEGIN); + show_all_nodes->hide(); + filter_hbc->add_child(show_all_nodes); tree = memnew(SceneTreeEditor(false, false, true)); tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); tree->get_scene_tree()->connect("item_activated", callable_mp(this, &SceneTreeDialog::_select)); + // Initialize button state, must be done after the tree has been created to update its 'show_all_nodes' flag. + // This is also done before adding the tree to the content to avoid triggering unnecessary tree filtering. + show_all_nodes->set_pressed(EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "show_all_nodes_for_node_selection", false)); content->add_child(tree); // Disable the OK button when no node is selected. |