From 18a6bbeae61b45394164e398c48b86ed695b3c40 Mon Sep 17 00:00:00 2001 From: Alexander Montag Date: Wed, 25 Sep 2024 16:54:33 +0000 Subject: [PATCH] Implement filtering for TreeSearch --- editor/task_tree.cpp | 2 ++ editor/tree_search.cpp | 44 ++++++++++++++++++++++++++++++++++-------- editor/tree_search.h | 11 +++++++++-- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/editor/task_tree.cpp b/editor/task_tree.cpp index ca8e4fe..3a0e008 100644 --- a/editor/task_tree.cpp +++ b/editor/task_tree.cpp @@ -533,8 +533,10 @@ void TaskTree::_notification(int p_what) { tree->connect("multi_selected", callable_mp(this, &TaskTree::_on_item_selected).unbind(3), CONNECT_DEFERRED); tree->connect("item_activated", callable_mp(this, &TaskTree::_on_item_activated)); tree->connect("item_collapsed", callable_mp(this, &TaskTree::_on_item_collapsed)); + // TODO: Simplify these signals into one (candidate names: changed, updated, update_requested): tree_search->search_panel->connect("text_changed", callable_mp(this, &TaskTree::_update_tree).unbind(1)); tree_search->search_panel->connect("visibility_changed", callable_mp(this, &TaskTree::_update_tree)); + tree_search->search_panel->connect("filter_toggled", callable_mp(this, &TaskTree::_update_tree)); } break; case NOTIFICATION_THEME_CHANGED: { _do_update_theme_item_cache(); diff --git a/editor/tree_search.cpp b/editor/tree_search.cpp index faa5763..5dfcf76 100644 --- a/editor/tree_search.cpp +++ b/editor/tree_search.cpp @@ -93,6 +93,10 @@ void TreeSearchPanel::_emit_text_submitted(const String &p_text) { this->emit_signal("text_submitted"); } +void TreeSearchPanel::_emit_filter_toggled() { + this->emit_signal("filter_toggled"); +} + void TreeSearchPanel::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { @@ -100,6 +104,7 @@ void TreeSearchPanel::_notification(int p_what) { line_edit_search->connect("text_changed", callable_mp(this, &TreeSearchPanel::_emit_text_changed)); _initialize_close_callbacks(); line_edit_search->connect("text_submitted", callable_mp(this, &TreeSearchPanel::_emit_text_submitted)); + check_button_filter_highlight->connect("pressed", callable_mp(this, &TreeSearchPanel::_emit_filter_toggled)); break; } } @@ -108,6 +113,7 @@ void TreeSearchPanel::_notification(int p_what) { void TreeSearchPanel::_bind_methods() { ADD_SIGNAL(MethodInfo("text_changed")); ADD_SIGNAL(MethodInfo("text_submitted")); + ADD_SIGNAL(MethodInfo("filter_toggled")); } TreeSearchPanel::TreeSearchPanel() { @@ -140,10 +146,26 @@ void TreeSearchPanel::show_and_focus() { /* ------- TreeSearch ------- */ -void TreeSearch::_filter_tree(TreeItem *p_tree_item, const String &p_search_mask) { - for (int i = 0; i < ordered_tree_items.size(); i++) { +void TreeSearch::_filter_tree(const String &p_search_mask) { + if (matching_entries.size() == 0) { + return; + } + + for (int i = 0; i < ordered_tree_items.size(); i++) { + TreeItem *cur_item = ordered_tree_items[i]; + + if (number_matches.has(cur_item)){ + continue; + } + + TreeItem *first_counting_ancestor = cur_item; + while (first_counting_ancestor && !number_matches.has(first_counting_ancestor)) { + first_counting_ancestor = first_counting_ancestor->get_parent(); + } + if (!first_counting_ancestor || first_counting_ancestor == tree_reference->get_root() || !_vector_has_bsearch(matching_entries, first_counting_ancestor)) { + cur_item->set_visible(false); + } } - PRINT_LINE("filter tree not yet implemented!", p_search_mask); } void TreeSearch::_highlight_tree(const String &p_search_mask) { @@ -366,8 +388,7 @@ void TreeSearch::_select_first_match() { } for (int i = 0; i < ordered_tree_items.size(); i++) { TreeItem *item = ordered_tree_items[i]; - int match_idx = matching_entries.bsearch(item, true); - if (match_idx < 0 || match_idx >= matching_entries.size() || matching_entries[match_idx] != item) { + if (!_vector_has_bsearch(matching_entries, item)){ continue; } String debug_string = "["; @@ -397,8 +418,7 @@ void TreeSearch::_select_next_match() { // find the best fitting entry. for (int i = 0; i < ordered_tree_items.size(); i++) { TreeItem *item = ordered_tree_items[i]; - int match_idx = matching_entries.bsearch(item, true); - if (match_idx < 0 || match_idx >= matching_entries.size() || selected_idx >= i || matching_entries[match_idx] != item) { + if (!_vector_has_bsearch(matching_entries, item)){ continue; } @@ -408,6 +428,14 @@ void TreeSearch::_select_next_match() { _select_first_match(); // wrap around. } +template +inline bool TreeSearch::_vector_has_bsearch(Vector p_vec, T *element) { + int idx = p_vec.bsearch(element, true); + bool in_array = idx >= 0 && idx < p_vec.size(); + + return in_array && p_vec[idx] == element; +} + void TreeSearch::on_item_edited(TreeItem *item) { if (item->get_cell_mode(0) != TreeItem::CELL_MODE_CUSTOM) { return; @@ -446,7 +474,7 @@ void TreeSearch::update_search(Tree *p_tree) { } } if (search_mode == TreeSearchMode::FILTER) { - _filter_tree(tree_root, search_mask); + _filter_tree(search_mask); } } diff --git a/editor/tree_search.h b/editor/tree_search.h index 0b4300f..6c13a4b 100644 --- a/editor/tree_search.h +++ b/editor/tree_search.h @@ -56,6 +56,7 @@ private: void _on_draw_highlight(TreeItem *item, Rect2 rect); void _emit_text_changed(const String &text); void _emit_text_submitted(const String &p_text); + void _emit_filter_toggled(); void _notification(int p_what); protected: @@ -90,12 +91,14 @@ private: HashMap number_matches; HashMap callable_cache; - void _filter_tree(TreeItem *tree_item, const String &search_mask); + void _filter_tree(const String &p_search_mask); void _highlight_tree(const String &p_search_mask); void _draw_highlight_item(TreeItem *tree_item, Rect2 rect, String search_mask, Callable parent_draw_method); void _update_matching_entries(const String &search_mask); void _update_ordered_tree_items(TreeItem *tree_item); void _update_number_matches(); + + Vector _find_matching_entries(TreeItem *tree_item, const String &search_mask, Vector &buffer); StringSearchIndices _substring_bounds(const String &searchable, const String &search_mask) const; @@ -103,6 +106,8 @@ private: void _select_first_match(); void _select_next_match(); + template + bool _vector_has_bsearch(Vector p_vec, T* element); protected: static void _bind_methods() {} @@ -117,4 +122,6 @@ public: }; #endif // TREE_SEARCH_H -#endif // ! TOOLS_ENABLED \ No newline at end of file +#endif // ! TOOLS_ENABLED + +