Skip to content

Commit df94c00

Browse files
committed
Merge pull request #100010 from KoBeWi/directory_compass_for_navigating_sea_of_directories
Don't rebuild tree when navigating to path
2 parents ec7ffdc + 113621d commit df94c00

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

editor/filesystem_dock.cpp

+48-4
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ void FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
245245
}
246246
subdirectory_item->set_selectable(0, true);
247247
subdirectory_item->set_metadata(0, lpath);
248+
folder_map[lpath] = subdirectory_item;
249+
248250
if (!p_select_in_favorites && (current_path == lpath || ((display_mode != DISPLAY_MODE_TREE_ONLY) && current_path.get_base_dir() == lpath))) {
249251
subdirectory_item->select(0);
250252
// Keep select an item when re-created a tree
@@ -371,6 +373,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
371373
tree_update_id++;
372374
updating_tree = true;
373375
TreeItem *root = tree->create_item();
376+
folder_map.clear();
374377

375378
// Handles the favorites.
376379
favorites_item = tree->create_item(root);
@@ -702,19 +705,21 @@ void FileSystemDock::_set_current_path_line_edit_text(const String &p_path) {
702705
}
703706

704707
void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_favorites) {
708+
bool is_directory = false;
705709
if (p_path == "Favorites") {
706710
current_path = p_path;
707711
} else {
708712
String target_path = p_path;
709713
// If the path is a file, do not only go to the directory in the tree, also select the file in the file list.
710714
if (target_path.ends_with("/")) {
711-
target_path = target_path.substr(0, target_path.length() - 1);
715+
target_path = target_path.trim_suffix("/");
712716
}
713717
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
714718
if (da->file_exists(p_path)) {
715719
current_path = target_path;
716720
} else if (da->dir_exists(p_path)) {
717721
current_path = target_path + "/";
722+
is_directory = true;
718723
} else {
719724
ERR_FAIL_MSG(vformat("Cannot navigate to '%s' as it has not been found in the file system!", p_path));
720725
}
@@ -723,17 +728,56 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa
723728
_set_current_path_line_edit_text(current_path);
724729
_push_to_history();
725730

726-
_update_tree(get_uncollapsed_paths(), false, p_select_in_favorites, true);
731+
const String file_name = is_directory ? p_path.trim_suffix("/").get_file() + "/" : p_path.get_file();
732+
bool found = false;
733+
734+
TreeItem **base_dir_ptr;
735+
{
736+
const String base_dir = current_path.get_base_dir();
737+
if (base_dir == "res://") {
738+
base_dir_ptr = folder_map.getptr(base_dir);
739+
} else if (is_directory) {
740+
base_dir_ptr = folder_map.getptr(base_dir.get_base_dir() + "/");
741+
} else {
742+
base_dir_ptr = folder_map.getptr(base_dir + "/");
743+
}
744+
}
745+
746+
if (base_dir_ptr) {
747+
TreeItem *directory = *base_dir_ptr;
748+
{
749+
TreeItem *entry = directory->get_first_child();
750+
while (entry) {
751+
if (entry->get_metadata(0).operator String().ends_with(file_name)) {
752+
tree->deselect_all();
753+
entry->select(0);
754+
found = true;
755+
break;
756+
}
757+
entry = entry->get_next();
758+
}
759+
}
760+
761+
while (directory) {
762+
directory->set_collapsed(false);
763+
directory = directory->get_parent();
764+
}
765+
}
766+
767+
if (!found) {
768+
return;
769+
}
770+
771+
tree->ensure_cursor_is_visible();
727772
if (display_mode != DISPLAY_MODE_TREE_ONLY) {
728773
_update_file_list(false);
729774

730775
// Reset the scroll for a directory.
731-
if (p_path.ends_with("/")) {
776+
if (is_directory) {
732777
files->get_v_scroll_bar()->set_value(0);
733778
}
734779
}
735780

736-
String file_name = p_path.get_file();
737781
if (!file_name.is_empty()) {
738782
for (int i = 0; i < files->get_item_count(); i++) {
739783
if (files->get_item_text(i) == file_name) {

editor/filesystem_dock.h

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class FileSystemDock : public VBoxContainer {
133133
CONVERT_BASE_ID = 1000,
134134
};
135135

136+
HashMap<String, TreeItem *> folder_map;
136137
HashMap<String, Color> folder_colors;
137138
Dictionary assigned_folder_colors;
138139

0 commit comments

Comments
 (0)