diff options
Diffstat (limited to 'editor/scene_tree_editor.cpp')
-rw-r--r-- | editor/scene_tree_editor.cpp | 100 |
1 files changed, 86 insertions, 14 deletions
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index c120468ecb..137574640e 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -387,17 +387,18 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { Ref<Script> script = p_node->get_script(); if (!script.is_null()) { String additional_notes; + Color button_color = Color(1, 1, 1); // Can't set tooltip after adding button, need to do it before. if (script->is_tool()) { additional_notes += "\n" + TTR("This script is currently running in the editor."); + button_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); } - item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path() + additional_notes); if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) { - item->set_button_color(0, item->get_button_count(0) - 1, Color(1, 1, 1, 0.5)); - } - if (script->is_tool()) { - item->set_button_color(0, item->get_button_count(0) - 1, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + additional_notes += "\n" + TTR("This script is a custom type."); + button_color.a = 0.5; } + item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path() + additional_notes); + item->set_button_color(0, item->get_button_count(0) - 1, button_color); } if (p_node->is_class("CanvasItem")) { @@ -602,7 +603,7 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { updating_tree = false; tree_dirty = false; - if (!filter.is_empty()) { + if (!filter.strip_edges().is_empty()) { _update_filter(nullptr, p_scroll_to_selected); } } @@ -617,18 +618,28 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select return false; } - bool keep = false; + bool keep_for_children = false; for (TreeItem *child = p_parent->get_first_child(); child; child = child->get_next()) { - keep = _update_filter(child, p_scroll_to_selected) || keep; + // Always keep if at least one of the children are kept. + keep_for_children = _update_filter(child, p_scroll_to_selected) || keep_for_children; } - if (!keep) { - 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); + // Now find other reasons to keep this Node, too. + PackedStringArray terms = filter.to_lower().split_spaces(); + bool keep = _item_matches_all_terms(p_parent, terms); + + p_parent->set_visible(keep_for_children || keep); + if (keep_for_children) { + if (keep) { + p_parent->clear_custom_color(0); + p_parent->set_selectable(0, true); + } else { + p_parent->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + p_parent->set_selectable(0, false); + p_parent->deselect(0); + } } - p_parent->set_visible(keep); if (editor_selection) { Node *n = get_node(p_parent->get_metadata(0)); if (keep) { @@ -643,7 +654,68 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } } - return keep; + return keep || keep_for_children; +} + +bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, PackedStringArray p_terms) { + if (p_terms.is_empty()) { + return true; + } + + for (int i = 0; i < p_terms.size(); i++) { + String term = p_terms[i]; + + // Recognise special filter. + if (term.contains(":") && !term.get_slicec(':', 0).is_empty()) { + String parameter = term.get_slicec(':', 0); + String argument = term.get_slicec(':', 1); + + if (parameter == "type" || parameter == "t") { + // Filter by Type. + String node_type = get_node(p_item->get_metadata(0))->get_class().to_lower(); + + if (!node_type.contains(argument)) { + return false; + } + } else if (parameter == "group" || parameter == "g") { + // Filter by Group. + Node *node = get_node(p_item->get_metadata(0)); + + List<Node::GroupInfo> group_info_list; + node->get_groups(&group_info_list); + if (group_info_list.is_empty()) { + return false; + } + // When argument is empty, match all Nodes belonging to any group. + if (!argument.is_empty()) { + bool term_in_groups = false; + for (int j = 0; j < group_info_list.size(); j++) { + // Ignore private groups. + if (String(group_info_list[j].name).begins_with("__")) { + continue; + } + if (String(group_info_list[j].name).to_lower().contains(argument)) { + term_in_groups = true; + break; + } + } + if (!term_in_groups) { + return false; + } + } + } else { + WARN_PRINT(vformat(TTR("Special Node filter \"%s\" is not recognised. Available filters include \"type\" and \"group\"."), parameter)); + continue; + } + } else { + // Default. + if (!p_item->get_text(0).to_lower().contains(term)) { + return false; + } + } + } + + return true; } void SceneTreeEditor::_compute_hash(Node *p_node, uint64_t &hash) { |