diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-06 16:35:23 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-06 16:35:23 +0200 |
commit | 75c4b955f60c466f383ebe39002e47d1fac314af (patch) | |
tree | 14eb27d57b1d92ae8dba21f9beb127035721a4f0 | |
parent | afb63944d00fd93d16576e2c8843bf78470a5e9e (diff) | |
parent | 33092b6f4519a1caef7158efaf3ee7a9c91732f5 (diff) |
Merge pull request #65932 from Mickeon/editor-scene-tree-filter-selection
Expose and warn about Node Filters in Scene Tree Dock
-rw-r--r-- | editor/scene_tree_dock.cpp | 87 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 10 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 9 | ||||
-rw-r--r-- | editor/scene_tree_editor.h | 2 |
4 files changed, 103 insertions, 5 deletions
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index d1dc188be9..967334f183 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1187,6 +1187,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; @@ -2883,11 +2885,83 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { void SceneTreeDock::_update_tree_menu() { PopupMenu *tree_menu = button_tree_menu->get_popup(); - tree_menu->set_item_checked(tree_menu->get_item_idx_from_text(TTR("Auto Expand to Selected")), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); + tree_menu->clear(); + + _append_filter_options_to(tree_menu); + + tree_menu->add_separator(); + tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); + tree_menu->set_item_checked(tree_menu->get_item_index(TOOL_AUTO_EXPAND), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); +} + +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.is_empty()) { + filter->add_theme_icon_override(SNAME("clear"), get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); + filter->set_tooltip_text(warning); + } else { + filter->remove_theme_icon_override(SNAME("clear")); + filter->set_tooltip_text(""); + } +} + +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() == MouseButton::MIDDLE) { + filter_quick_menu->clear(); + + _append_filter_options_to(filter_quick_menu, false); + filter_quick_menu->set_position(get_screen_position() + get_local_mouse_position()); + filter_quick_menu->reset_size(); + 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.is_empty()) { + set_filter((get_filter() + " " + filter_parameter + ":").strip_edges()); + filter->set_caret_column(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->set_item_text(-1, TTR("Filters")); + p_menu->set_item_icon(-1, get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + p_menu->set_item_indent(-1, -2); + } + + 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_theme_icon(SNAME("Node"), SNAME("EditorIcons"))); + p_menu->set_item_icon(p_menu->get_item_index(FILTER_BY_GROUP), get_theme_icon(SNAME("Groups"), SNAME("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() { @@ -3399,14 +3473,22 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_instance->set_tooltip_text(TTR("Instantiate 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_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); + filter->connect("gui_input", callable_mp(this, &SceneTreeDock::_filter_gui_input)); + filter->get_menu()->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_update_filter_menu)); + filter->get_menu()->connect("id_pressed", callable_mp(this, &SceneTreeDock::_filter_option_selected)); + + filter_quick_menu = memnew(PopupMenu); + filter_quick_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_filter_option_selected)); + filter->add_child(filter_quick_menu); button_create_script = memnew(Button); button_create_script->set_flat(true); @@ -3430,7 +3512,6 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec filter_hbc->add_child(button_tree_menu); PopupMenu *tree_menu = button_tree_menu->get_popup(); - tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); tree_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(false)); button_hb = memnew(HBoxContainer); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index e48b518252..04bb4d93e7 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -160,7 +160,13 @@ class SceneTreeDock : public VBoxContainer { EditorQuickOpen *quick_open = nullptr; EditorFileDialog *new_scene_from_dialog = nullptr; + enum FilterMenuItems { + FILTER_BY_TYPE = 64, // Used in the same menus as the Tool enum. + FILTER_BY_GROUP, + }; + LineEdit *filter = nullptr; + PopupMenu *filter_quick_menu = nullptr; TextureRect *filter_icon = nullptr; PopupMenu *menu = nullptr; @@ -243,8 +249,12 @@ class SceneTreeDock : public VBoxContainer { void _tree_rmb(const Vector2 &p_menu_pos); void _update_tree_menu(); + void _update_filter_menu(); void _filter_changed(const String &p_filter); + void _filter_gui_input(const Ref<InputEvent> &p_event); + void _filter_option_selected(int option); + void _append_filter_options_to(PopupMenu *p_menu, bool p_include_separator = true); void _perform_instantiate_scenes(const Vector<String> &p_files, Node *parent, int p_pos); void _replace_with_branch_scene(const String &p_file, Node *base); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 689570bcf6..abebd306e6 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -612,6 +612,7 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_selected) { if (!p_parent) { p_parent = tree->get_root(); + filter_term_warning.clear(); } if (!p_parent) { @@ -704,8 +705,8 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, PackedStringArra return false; } } - } else { - WARN_PRINT(vformat(TTR("Special Node filter \"%s\" is not recognised. Available filters include \"type\" and \"group\"."), parameter)); + } else if (filter_term_warning.is_empty()) { + filter_term_warning = vformat(TTR("\"%s\" is not a known filter."), parameter); continue; } } else { @@ -1029,6 +1030,10 @@ String SceneTreeEditor::get_filter() const { return filter; } +String SceneTreeEditor::get_filter_term_warning() { + return filter_term_warning; +} + void SceneTreeEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { undo_redo = p_undo_redo; } diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 8fbc3ab6d6..dcdfead885 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -62,6 +62,7 @@ class SceneTreeEditor : public Control { ObjectID instance_node; String filter; + String filter_term_warning; AcceptDialog *error = nullptr; AcceptDialog *warning = nullptr; @@ -142,6 +143,7 @@ public: void set_filter(const String &p_filter); String get_filter() const; + String get_filter_term_warning(); void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_display_foreign_nodes(bool p_display); |