Improve Directory content navigation

This commit is contained in:
Tomasz Chabora 2020-07-20 19:20:40 +02:00 committed by kobewi
parent f675b6b623
commit d04c2a554f
3 changed files with 93 additions and 17 deletions

View file

@ -1470,12 +1470,8 @@ bool Directory::is_open() const {
return d && dir_open; 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."); 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(); 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."); ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use.");
String next = d->get_next(); 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(); next = d->get_next();
} }
return next; return next;
@ -1499,6 +1495,47 @@ void Directory::list_dir_end() {
d->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() { int Directory::get_drive_count() {
ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use.");
return d->get_drive_count(); return d->get_drive_count();
@ -1614,10 +1651,12 @@ Error Directory::remove(String p_name) {
void Directory::_bind_methods() { void Directory::_bind_methods() {
ClassDB::bind_method(D_METHOD("open", "path"), &Directory::open); 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("get_next"), &Directory::get_next);
ClassDB::bind_method(D_METHOD("current_is_dir"), &Directory::current_is_dir); 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("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_count"), &Directory::get_drive_count);
ClassDB::bind_method(D_METHOD("get_drive", "idx"), &Directory::get_drive); ClassDB::bind_method(D_METHOD("get_drive", "idx"), &Directory::get_drive);
ClassDB::bind_method(D_METHOD("get_current_drive"), &Directory::get_current_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("copy", "from", "to"), &Directory::copy);
ClassDB::bind_method(D_METHOD("rename", "from", "to"), &Directory::rename); ClassDB::bind_method(D_METHOD("rename", "from", "to"), &Directory::rename);
ClassDB::bind_method(D_METHOD("remove", "path"), &Directory::remove); 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() { Directory::Directory() {

View file

@ -444,7 +444,10 @@ public:
class Directory : public RefCounted { class Directory : public RefCounted {
GDCLASS(Directory, RefCounted); GDCLASS(Directory, RefCounted);
DirAccess *d; DirAccess *d;
bool dir_open = false; bool dir_open = false;
bool include_navigational = false;
bool include_hidden = false;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -454,12 +457,20 @@ public:
bool is_open() const; 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(); String get_next();
bool current_is_dir() const; bool current_is_dir() const;
void list_dir_end(); 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(); int get_drive_count();
String get_drive(int p_drive); String get_drive(int p_drive);
int get_current_drive(); int get_current_drive();
@ -481,10 +492,6 @@ public:
Directory(); Directory();
virtual ~Directory(); virtual ~Directory();
private:
bool _list_skip_navigational = false;
bool _list_skip_hidden = false;
}; };
class Marshalls : public Object { class Marshalls : public Object {

View file

@ -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 the currently opened directory's drive index. See [method get_drive] to convert returned index to the name of the drive.
</description> </description>
</method> </method>
<method name="get_directories">
<return type="PackedStringArray" />
<description>
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].
</description>
</method>
<method name="get_drive"> <method name="get_drive">
<return type="String" /> <return type="String" />
<argument index="0" name="idx" type="int" /> <argument index="0" name="idx" type="int" />
@ -121,6 +128,13 @@
On Windows, returns the number of drives (partitions) mounted on the current filesystem. On other platforms, the method returns 0. On Windows, returns the number of drives (partitions) mounted on the current filesystem. On other platforms, the method returns 0.
</description> </description>
</method> </method>
<method name="get_files">
<return type="PackedStringArray" />
<description>
Returns a [PackedStringArray] containing filenames of the directory contents, excluding directories. The array is sorted alphabetically.
Affected by [member include_hidden].
</description>
</method>
<method name="get_next"> <method name="get_next">
<return type="String" /> <return type="String" />
<description> <description>
@ -136,12 +150,10 @@
</method> </method>
<method name="list_dir_begin"> <method name="list_dir_begin">
<return type="int" enum="Error" /> <return type="int" enum="Error" />
<argument index="0" name="show_navigational" type="bool" default="false" />
<argument index="1" name="show_hidden" type="bool" default="false" />
<description> <description>
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]. 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. Affected by [member include_hidden] and [member include_navigational].
If [code]show_hidden[/code] is [code]true[/code], hidden files are included too. [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].
</description> </description>
</method> </method>
<method name="list_dir_end"> <method name="list_dir_end">
@ -192,4 +204,14 @@
</description> </description>
</method> </method>
</methods> </methods>
<members>
<member name="include_hidden" type="bool" setter="set_include_hidden" getter="get_include_hidden" default="false">
If [code]true[/code], hidden files are included when the navigating directory.
Affects [method list_dir_begin], [method get_directories] and [method get_files].
</member>
<member name="include_navigational" type="bool" setter="set_include_navigational" getter="get_include_navigational" default="false">
If [code]true[/code], [code].[/code] and [code]..[/code] are included when navigating the directory.
Affects [method list_dir_begin] and [method get_directories].
</member>
</members>
</class> </class>