Compare commits

..

2 Commits

Author SHA1 Message Date
monxa 5607244db6
Merge 14cfb14ab9 into 760af804c0 2024-10-06 04:28:12 +00:00
Alexander Montag 14cfb14ab9
Implement Tree Search Functionality with Highlighting and Filtering
This commit introduces a comprehensive Tree Search feature, including:
- Tree highlighting: Highlights items that match the search query.
- Tree filtering: Filters items so only matches and descendants are
  shown.
- Counting descendants: Shows the number of matching items within collapsed branches.
- Jump to next match: on enter.
- (Limbo-)Shortcut: Default CTRL-F.
- Menu entry: Misc->Search Tree.
- Remember separate SearchInfo for each tab.

Key implementation details:
- Optimized performance for large trees
- Implemented recursive filtering for efficiency
- Added UI elements including next/previous match buttons

Development History:
- Initial implementation of highlighting and filtering
- Multiple rounds of performance optimization
- Bug fixes and refactoring for correctness
- UI enhancements and polish
- Code cleanup and style improvements
2024-10-06 06:28:03 +02:00
1 changed files with 7 additions and 4 deletions

View File

@ -238,14 +238,18 @@ void TreeSearch::_update_ordered_tree_items(TreeItem *p_tree_item) {
void TreeSearch::_update_number_matches() { void TreeSearch::_update_number_matches() {
ERR_FAIL_COND(!tree_reference); ERR_FAIL_COND(!tree_reference);
number_matches.clear(); number_matches.clear();
number_matches.reserve(ordered_tree_items.size()); number_matches.reserve(ordered_tree_items.size());
TreeItem * tree_root = tree_reference->get_root();
if (!tree_root){
return;
}
_update_number_matches(tree_reference->get_root()); _update_number_matches(tree_reference->get_root());
} }
void TreeSearch::_update_number_matches(TreeItem *item) { void TreeSearch::_update_number_matches(TreeItem *item) {
ERR_FAIL_COND(!item);
for (int i = 0; i < item->get_child_count(); i++) { for (int i = 0; i < item->get_child_count(); i++) {
TreeItem *child = item->get_child(i); TreeItem *child = item->get_child(i);
_update_number_matches(child); _update_number_matches(child);
@ -264,7 +268,7 @@ void TreeSearch::_update_number_matches(TreeItem *item) {
} }
String TreeSearch::_get_search_mask() const { String TreeSearch::_get_search_mask() const {
ERR_FAIL_COND_V(!search_panel, ""); ERR_FAIL_COND(!search_panel);
return search_panel->get_text(); return search_panel->get_text();
} }
@ -524,7 +528,6 @@ void TreeSearchPanel::_initialize_controls() {
find_next_button->set_theme_type_variation(LW_NAME(FlatButton)); find_next_button->set_theme_type_variation(LW_NAME(FlatButton));
find_prev_button->set_theme_type_variation(LW_NAME(FlatButton)); find_prev_button->set_theme_type_variation(LW_NAME(FlatButton));
close_button->set_tooltip_text("Hide");
find_next_button->set_tooltip_text("Next Match"); find_next_button->set_tooltip_text("Next Match");
find_prev_button->set_tooltip_text("Previous Match"); find_prev_button->set_tooltip_text("Previous Match");
@ -559,7 +562,7 @@ void TreeSearchPanel::_notification(int p_what) {
// Close callbacks // Close callbacks
close_button->connect(LW_NAME(pressed), Callable(this, LW_NAME(set_visible)).bind(false)); close_button->connect(LW_NAME(pressed), Callable(this, LW_NAME(set_visible)).bind(false));
close_button->connect(LW_NAME(pressed), Callable(this, LW_NAME(emit_signal)).bind(LW_NAME(Close))); close_button->connect(LW_NAME(pressed), Callable(this, LW_NAME(emit_signal)).bind(LW_NAME(Close)));
close_button->set_shortcut(LW_GET_SHORTCUT("limbo_ai/hide_tree_search")); // TODO: use internal shortcut. close_button->set_shortcut(LW_GET_SHORTCUT("limbo_ai/hide_tree_search")); // TODO: use internal shortcut. also sets tooltip...
// Search callbacks // Search callbacks
Callable c_update_requested = Callable(this, LW_NAME(emit_signal)).bind("update_requested"); Callable c_update_requested = Callable(this, LW_NAME(emit_signal)).bind("update_requested");
Callable c_text_submitted = Callable(this, LW_NAME(emit_signal)).bind(LW_NAME(text_submitted)); Callable c_text_submitted = Callable(this, LW_NAME(emit_signal)).bind(LW_NAME(text_submitted));