Fix tree filtering with new approach
This commit is contained in:
parent
e6e1addbcb
commit
74cf9855a7
|
@ -56,29 +56,41 @@ void TreeSearch::_clean_callable_cache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeSearch::_filter_tree(const String &p_search_mask) {
|
void TreeSearch::_filter_tree(const String &p_search_mask) {
|
||||||
if (matching_entries.size() == 0) {
|
if (matching_entries.is_empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<bool> item_visibilities;
|
||||||
|
item_visibilities.resize(ordered_tree_items.size());
|
||||||
|
|
||||||
|
// Make all entries visible that have any matching descendents. O(n)
|
||||||
for (int i = 0; i < ordered_tree_items.size(); i++) {
|
for (int i = 0; i < ordered_tree_items.size(); i++) {
|
||||||
TreeItem *cur_item = ordered_tree_items[i];
|
TreeItem *entry = ordered_tree_items[i];
|
||||||
|
if (number_matches.has(entry) && number_matches[entry] > 0) {
|
||||||
if (number_matches.has(cur_item)) {
|
item_visibilities.set(i, true);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *first_counting_ancestor = cur_item;
|
// Make all descendents of matching entries visible. O(n) * log(|matching_entries|)
|
||||||
bool parents_visible = true;
|
for (int i = 0; i < ordered_tree_items.size(); i++) {
|
||||||
while (first_counting_ancestor && !number_matches.has(first_counting_ancestor)) {
|
TreeItem *entry = ordered_tree_items[i];
|
||||||
// Performance: we only need to check the first visible ancestor. This is already optimal because of the ordering in ordered_tree_items.
|
TreeItem *next_entry = entry->get_next();
|
||||||
if (!first_counting_ancestor->is_visible()){
|
if (!next_entry && i < ordered_tree_items.size() - 1) {
|
||||||
parents_visible = false;
|
next_entry = ordered_tree_items[i + 1];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
first_counting_ancestor = first_counting_ancestor->get_parent();
|
if (_vector_has_bsearch(matching_entries, entry)) {
|
||||||
|
int j = i;
|
||||||
|
for (; j < ordered_tree_items.size() && ordered_tree_items[j] != next_entry; j++) {
|
||||||
|
item_visibilities.set(j, true);
|
||||||
}
|
}
|
||||||
if (!parents_visible || !first_counting_ancestor || !_vector_has_bsearch(matching_entries, first_counting_ancestor)) {
|
i = j - 1; // every entry is only processed once.
|
||||||
cur_item->set_visible(false);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply visibility. O(n)
|
||||||
|
for (int i = 0; i < ordered_tree_items.size(); i++) {
|
||||||
|
if (!item_visibilities[i]) {
|
||||||
|
ordered_tree_items[i]->set_visible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue