From d04c2a554f7f359c4ba75898a0a4bb39c75c10a2 Mon Sep 17 00:00:00 2001 From: Tomasz Chabora Date: Mon, 20 Jul 2020 19:20:40 +0200 Subject: [PATCH] Improve Directory content navigation --- core/core_bind.cpp | 61 ++++++++++++++++++++++++++++++++++----- core/core_bind.h | 19 ++++++++---- doc/classes/Directory.xml | 30 ++++++++++++++++--- 3 files changed, 93 insertions(+), 17 deletions(-) diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 161008fd35b..fe026ed38f5 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1470,12 +1470,8 @@ bool Directory::is_open() const { return d && dir_open; } -Error Directory::list_dir_begin(bool p_show_navigational, bool p_show_hidden) { +Error Directory::list_dir_begin() { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); - - _list_skip_navigational = !p_show_navigational; - _list_skip_hidden = !p_show_hidden; - return d->list_dir_begin(); } @@ -1483,7 +1479,7 @@ String Directory::get_next() { ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); String next = d->get_next(); - while (!next.is_empty() && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) { + while (!next.is_empty() && ((!include_navigational && (next == "." || next == "..")) || (!include_hidden && d->current_is_hidden()))) { next = d->get_next(); } return next; @@ -1499,6 +1495,47 @@ void Directory::list_dir_end() { d->list_dir_end(); } +PackedStringArray Directory::get_files() { + return _get_contents(false); +} + +PackedStringArray Directory::get_directories() { + return _get_contents(true); +} + +PackedStringArray Directory::_get_contents(bool p_directories) { + PackedStringArray ret; + ERR_FAIL_COND_V_MSG(!is_open(), ret, "Directory must be opened before use."); + + list_dir_begin(); + String s = get_next(); + while (!s.is_empty()) { + if (current_is_dir() == p_directories) { + ret.append(s); + } + s = get_next(); + } + + ret.sort(); + return ret; +} + +void Directory::set_include_navigational(bool p_enable) { + include_navigational = p_enable; +} + +bool Directory::get_include_navigational() const { + return include_navigational; +} + +void Directory::set_include_hidden(bool p_enable) { + include_hidden = p_enable; +} + +bool Directory::get_include_hidden() const { + return include_hidden; +} + int Directory::get_drive_count() { ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_drive_count(); @@ -1614,10 +1651,12 @@ Error Directory::remove(String p_name) { void Directory::_bind_methods() { ClassDB::bind_method(D_METHOD("open", "path"), &Directory::open); - ClassDB::bind_method(D_METHOD("list_dir_begin", "show_navigational", "show_hidden"), &Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("list_dir_begin"), &Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_next"), &Directory::get_next); ClassDB::bind_method(D_METHOD("current_is_dir"), &Directory::current_is_dir); ClassDB::bind_method(D_METHOD("list_dir_end"), &Directory::list_dir_end); + ClassDB::bind_method(D_METHOD("get_files"), &Directory::get_files); + ClassDB::bind_method(D_METHOD("get_directories"), &Directory::get_directories); ClassDB::bind_method(D_METHOD("get_drive_count"), &Directory::get_drive_count); ClassDB::bind_method(D_METHOD("get_drive", "idx"), &Directory::get_drive); ClassDB::bind_method(D_METHOD("get_current_drive"), &Directory::get_current_drive); @@ -1632,6 +1671,14 @@ void Directory::_bind_methods() { ClassDB::bind_method(D_METHOD("copy", "from", "to"), &Directory::copy); ClassDB::bind_method(D_METHOD("rename", "from", "to"), &Directory::rename); ClassDB::bind_method(D_METHOD("remove", "path"), &Directory::remove); + + ClassDB::bind_method(D_METHOD("set_include_navigational"), &Directory::set_include_navigational); + ClassDB::bind_method(D_METHOD("get_include_navigational"), &Directory::get_include_navigational); + ClassDB::bind_method(D_METHOD("set_include_hidden"), &Directory::set_include_hidden); + ClassDB::bind_method(D_METHOD("get_include_hidden"), &Directory::get_include_hidden); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_hidden"), "set_include_hidden", "get_include_hidden"); } Directory::Directory() { diff --git a/core/core_bind.h b/core/core_bind.h index 920f2b539ba..6da44038808 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -444,7 +444,10 @@ public: class Directory : public RefCounted { GDCLASS(Directory, RefCounted); DirAccess *d; + bool dir_open = false; + bool include_navigational = false; + bool include_hidden = false; protected: static void _bind_methods(); @@ -454,12 +457,20 @@ public: bool is_open() const; - Error list_dir_begin(bool p_show_navigational = false, bool p_show_hidden = false); // This starts dir listing. + Error list_dir_begin(); String get_next(); bool current_is_dir() const; - void list_dir_end(); + PackedStringArray get_files(); + PackedStringArray get_directories(); + PackedStringArray _get_contents(bool p_directories); + + void set_include_navigational(bool p_enable); + bool get_include_navigational() const; + void set_include_hidden(bool p_enable); + bool get_include_hidden() const; + int get_drive_count(); String get_drive(int p_drive); int get_current_drive(); @@ -481,10 +492,6 @@ public: Directory(); virtual ~Directory(); - -private: - bool _list_skip_navigational = false; - bool _list_skip_hidden = false; }; class Marshalls : public Object { diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index cd4b8fde1e1..dbf5e31da4d 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -108,6 +108,13 @@ Returns the currently opened directory's drive index. See [method get_drive] to convert returned index to the name of the drive. + + + + Returns a [PackedStringArray] containing filenames of the directory contents, excluding files. The array is sorted alphabetically. + Affected by [member include_hidden] and [member include_navigational]. + + @@ -121,6 +128,13 @@ On Windows, returns the number of drives (partitions) mounted on the current filesystem. On other platforms, the method returns 0. + + + + Returns a [PackedStringArray] containing filenames of the directory contents, excluding directories. The array is sorted alphabetically. + Affected by [member include_hidden]. + + @@ -136,12 +150,10 @@ - - Initializes the stream used to list all files and directories using the [method get_next] function, closing the currently opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end]. - If [code]show_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are included too. - If [code]show_hidden[/code] is [code]true[/code], hidden files are included too. + Affected by [member include_hidden] and [member include_navigational]. + [b]Note:[/b] The order of files and directories returned by this method is not deterministic, and can vary between operating systems. If you want a list of all files or folders sorted alphabetically, use [method get_files] or [method get_directories]. @@ -192,4 +204,14 @@ + + + If [code]true[/code], hidden files are included when the navigating directory. + Affects [method list_dir_begin], [method get_directories] and [method get_files]. + + + If [code]true[/code], [code].[/code] and [code]..[/code] are included when navigating the directory. + Affects [method list_dir_begin] and [method get_directories]. + +