diff options
-rw-r--r-- | editor/filesystem_dock.cpp | 23 | ||||
-rw-r--r-- | editor/filesystem_dock.h | 4 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj | 1 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs | 86 |
4 files changed, 66 insertions, 48 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index fb591b51df..eb3ae33065 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -52,7 +52,7 @@ Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_di return file_icon; } -bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites) { +bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path) { bool parent_should_expand = false; // Create a tree item for the subdirectory. @@ -71,14 +71,18 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->select(0); } - subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0); + if (p_unfold_path && path.begins_with(lpath) && path != lpath) { + subdirectory_item->set_collapsed(false); + } else { + subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0); + } if (searched_string.length() > 0 && dname.to_lower().find(searched_string) >= 0) { parent_should_expand = true; } // Create items for all subdirectories. for (int i = 0; i < p_dir->get_subdir_count(); i++) - parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites) || parent_should_expand); + parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites, p_unfold_path) || parent_should_expand); // Create all items for the files in the subdirectory. if (display_mode == DISPLAY_MODE_TREE_ONLY) { @@ -164,7 +168,7 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { return uncollapsed_paths; } -void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { +void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites, bool p_unfold_path) { // Recreate the tree. tree->clear(); tree_update_id++; @@ -237,7 +241,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo } // Create the remaining of the tree. - _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites); + _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites, p_unfold_path); tree->ensure_cursor_is_visible(); updating_tree = false; } @@ -459,7 +463,7 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa _set_current_path_text(path); _push_to_history(); - _update_tree(_compute_uncollapsed_paths(), false, p_select_in_favorites); + _update_tree(_compute_uncollapsed_paths(), false, p_select_in_favorites, true); if (display_mode == DISPLAY_MODE_SPLIT) { _update_file_list(false); files->get_v_scroll()->set_value(0); @@ -1780,7 +1784,7 @@ void FileSystemDock::_resource_created() const { } void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { - if (searched_string.length() == 0 && p_text.length() > 0) { + if (searched_string.length() == 0) { // Register the uncollapsed paths before they change. uncollapsed_paths_before_search = _compute_uncollapsed_paths(); } @@ -1792,13 +1796,14 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from else // File_list_search_box. tree_search_box->set_text(searched_string); + bool unfold_path = (p_text == String() && path != String()); switch (display_mode) { case DISPLAY_MODE_TREE_ONLY: { - _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>()); + _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>(), false, false, unfold_path); } break; case DISPLAY_MODE_SPLIT: { _update_file_list(false); - _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>()); + _update_tree(searched_string.length() == 0 ? uncollapsed_paths_before_search : Vector<String>(), false, false, unfold_path); } break; } } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 099f4ad273..d81a5133f2 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -177,9 +177,9 @@ private: bool import_dock_needs_update; Ref<Texture> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx); - bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites); + bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false); Vector<String> _compute_uncollapsed_paths(); - void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false); + void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false, bool p_unfold_path = false); void _navigate_to_path(const String &p_path, bool p_select_in_favorites = false); void _file_list_gui_input(Ref<InputEvent> p_event); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj index d0c78d095b..fb2cbabc8e 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -30,6 +30,7 @@ <ConsolePause>false</ConsolePause> </PropertyGroup> <ItemGroup> + <Reference Include="Mono.Posix" /> <Reference Include="System" /> <Reference Include="GodotSharp"> <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath> diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 21ee85f2a9..1a8c26acd7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using Mono.Unix.Native; namespace GodotTools.Utils { @@ -55,21 +56,23 @@ namespace GodotTools.Utils return name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); } - public static bool IsWindows => IsOS(Names.Windows); - - public static bool IsOSX => IsOS(Names.OSX); - - public static bool IsX11 => IsOS(Names.X11); - - public static bool IsServer => IsOS(Names.Server); - - public static bool IsUWP => IsOS(Names.UWP); - - public static bool IsHaiku => IsOS(Names.Haiku); - - public static bool IsAndroid => IsOS(Names.Android); - - public static bool IsHTML5 => IsOS(Names.HTML5); + private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows)); + private static readonly Lazy<bool> _isOSX = new Lazy<bool>(() => IsOS(Names.OSX)); + private static readonly Lazy<bool> _isX11 = new Lazy<bool>(() => IsOS(Names.X11)); + private static readonly Lazy<bool> _isServer = new Lazy<bool>(() => IsOS(Names.Server)); + private static readonly Lazy<bool> _isUWP = new Lazy<bool>(() => IsOS(Names.UWP)); + private static readonly Lazy<bool> _isHaiku = new Lazy<bool>(() => IsOS(Names.Haiku)); + private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android)); + private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5)); + + public static bool IsWindows => _isWindows.Value; + public static bool IsOSX => _isOSX.Value; + public static bool IsX11 => _isX11.Value; + public static bool IsServer => _isServer.Value; + public static bool IsUWP => _isUWP.Value; + public static bool IsHaiku => _isHaiku.Value; + public static bool IsAndroid => _isAndroid.Value; + public static bool IsHTML5 => _isHTML5.Value; private static bool? _isUnixCache; private static readonly string[] UnixLikePlatforms = {Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android}; @@ -88,7 +91,12 @@ namespace GodotTools.Utils public static string PathWhich(string name) { - string[] windowsExts = IsWindows ? Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) : null; + return IsWindows ? PathWhichWindows(name) : PathWhichUnix(name); + } + + private static string PathWhichWindows(string name) + { + string[] windowsExts = Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) ?? new string[] { }; string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); var searchDirs = new List<string>(); @@ -96,30 +104,34 @@ namespace GodotTools.Utils if (pathDirs != null) searchDirs.AddRange(pathDirs); + string nameExt = Path.GetExtension(name); + bool hasPathExt = string.IsNullOrEmpty(nameExt) || windowsExts.Contains(nameExt, StringComparer.OrdinalIgnoreCase); + searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list - foreach (var dir in searchDirs) - { - string path = Path.Combine(dir, name); - - if (IsWindows && windowsExts != null) - { - foreach (var extension in windowsExts) - { - string pathWithExtension = path + extension; - - if (File.Exists(pathWithExtension)) - return pathWithExtension; - } - } - else - { - if (File.Exists(path)) - return path; - } - } + if (hasPathExt) + return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists); + + return (from dir in searchDirs + select Path.Combine(dir, name) + into path + from ext in windowsExts + select path + ext).FirstOrDefault(File.Exists); + } + + private static string PathWhichUnix(string name) + { + string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); + + var searchDirs = new List<string>(); + + if (pathDirs != null) + searchDirs.AddRange(pathDirs); + + searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list - return null; + return searchDirs.Select(dir => Path.Combine(dir, name)) + .FirstOrDefault(path => File.Exists(path) && Syscall.access(path, AccessModes.X_OK) == 0); } public static void RunProcess(string command, IEnumerable<string> arguments) |