[3.x] Improve Scene Tree Dock's Node filter (Allow multiple terms & more)

This commit is contained in:
Micky 2022-10-12 19:43:56 +02:00
parent e184e626f7
commit 8049fbdb9f
4 changed files with 230 additions and 34 deletions

View file

@ -1249,6 +1249,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
default: {
_filter_option_selected(p_tool);
if (p_tool >= EDIT_SUBRESOURCE_BASE) {
int idx = p_tool - EDIT_SUBRESOURCE_BASE;
@ -2993,8 +2995,69 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->popup();
}
void SceneTreeDock::_update_filter_menu() {
_append_filter_options_to(filter->get_menu());
}
void SceneTreeDock::_filter_changed(const String &p_filter) {
scene_tree->set_filter(p_filter);
String warning = scene_tree->get_filter_term_warning();
if (!warning.empty()) {
filter->add_icon_override("clear", get_icon("NodeWarning", "EditorIcons"));
filter->set_tooltip(warning);
} else {
filter->remove_icon_override("clear");
filter->set_tooltip("");
}
}
void SceneTreeDock::_filter_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_null()) {
return;
}
if (mb->is_pressed() && mb->get_button_index() == BUTTON_MIDDLE) {
filter_quick_menu->clear();
_append_filter_options_to(filter_quick_menu, false);
filter_quick_menu->set_position(get_global_position() + get_local_mouse_position());
filter_quick_menu->popup();
filter_quick_menu->grab_focus();
accept_event();
}
}
void SceneTreeDock::_filter_option_selected(int p_option) {
String filter_parameter;
switch (p_option) {
case FILTER_BY_TYPE: {
filter_parameter = "type";
} break;
case FILTER_BY_GROUP: {
filter_parameter = "group";
} break;
}
if (!filter_parameter.empty()) {
set_filter((get_filter() + " " + filter_parameter + ":").strip_edges());
filter->set_cursor_position(filter->get_text().length());
filter->grab_focus();
}
}
void SceneTreeDock::_append_filter_options_to(PopupMenu *p_menu, bool p_include_separator) {
if (p_include_separator) {
p_menu->add_separator();
}
p_menu->add_item(TTR("Filter by Type"), FILTER_BY_TYPE);
p_menu->add_item(TTR("Filter by Group"), FILTER_BY_GROUP);
p_menu->set_item_icon(p_menu->get_item_index(FILTER_BY_TYPE), get_icon("Node", "EditorIcons"));
p_menu->set_item_icon(p_menu->get_item_index(FILTER_BY_GROUP), get_icon("Groups", "EditorIcons"));
p_menu->set_item_tooltip(p_menu->get_item_index(FILTER_BY_TYPE), TTR("Selects all Nodes of the given type."));
p_menu->set_item_tooltip(p_menu->get_item_index(FILTER_BY_GROUP), TTR("Selects all Nodes belonging to the given group.\nIf empty, selects any Node belonging to any group."));
}
String SceneTreeDock::get_filter() {
@ -3332,6 +3395,9 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_script_dropped"), &SceneTreeDock::_script_dropped);
ClassDB::bind_method(D_METHOD("_tree_rmb"), &SceneTreeDock::_tree_rmb);
ClassDB::bind_method(D_METHOD("_filter_changed"), &SceneTreeDock::_filter_changed);
ClassDB::bind_method(D_METHOD("_filter_gui_input"), &SceneTreeDock::_filter_gui_input);
ClassDB::bind_method(D_METHOD("_update_filter_menu"), &SceneTreeDock::_update_filter_menu);
ClassDB::bind_method(D_METHOD("_filter_option_selected"), &SceneTreeDock::_filter_option_selected);
ClassDB::bind_method(D_METHOD("_focus_node"), &SceneTreeDock::_focus_node);
ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected);
ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
@ -3405,14 +3471,22 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
button_instance->set_tooltip(TTR("Instance a scene file as a Node. Creates an inherited scene if no root node exists."));
button_instance->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene"));
filter_hbc->add_child(button_instance);
vbc->add_child(filter_hbc);
// The "Filter Nodes" text input above the Scene Tree Editor.
filter = memnew(LineEdit);
filter->set_h_size_flags(SIZE_EXPAND_FILL);
filter->set_placeholder(TTR("Filter nodes"));
filter_hbc->add_child(filter);
filter->add_constant_override("minimum_spaces", 0);
filter->connect("text_changed", this, "_filter_changed");
filter->connect("gui_input", this, "_filter_gui_input");
filter->get_menu()->connect("id_pressed", this, "_filter_option_selected");
call_deferred("_update_filter_menu");
filter_quick_menu = memnew(PopupMenu);
filter_quick_menu->connect("id_pressed", this, "_filter_option_selected");
filter->add_child(filter_quick_menu);
button_create_script = memnew(ToolButton);
button_create_script->connect("pressed", this, "_tool_selected", make_binds(TOOL_ATTACH_SCRIPT, false));