Procházet zdrojové kódy

Improve UX of drive letters

Namely, move the drive dropdown to just the left of the path text box and don't include the former
in the latter.

This improves the UX on Windows.

In the UNIX case, since its concept of drives is (ab)used to provide shortcuts to useful paths, its
dropdown is kept at the original location.
Pedro J. Estébanez před 5 roky
rodič
revize
aee586553a

+ 3 - 3
core/bind/core_bind.cpp

@@ -2344,10 +2344,10 @@ Error _Directory::change_dir(String p_dir) {
 	ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
 	ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
 	return d->change_dir(p_dir);
 	return d->change_dir(p_dir);
 }
 }
-String _Directory::get_current_dir() {
+String _Directory::get_current_dir(bool p_include_drive) {
 
 
 	ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
 	ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
-	return d->get_current_dir();
+	return d->get_current_dir(p_include_drive);
 }
 }
 Error _Directory::make_dir(String p_dir) {
 Error _Directory::make_dir(String p_dir) {
 
 
@@ -2444,7 +2444,7 @@ void _Directory::_bind_methods() {
 	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);
 	ClassDB::bind_method(D_METHOD("change_dir", "todir"), &_Directory::change_dir);
 	ClassDB::bind_method(D_METHOD("change_dir", "todir"), &_Directory::change_dir);
-	ClassDB::bind_method(D_METHOD("get_current_dir"), &_Directory::get_current_dir);
+	ClassDB::bind_method(D_METHOD("get_current_dir", "include_drive"), &_Directory::get_current_dir, DEFVAL(true));
 	ClassDB::bind_method(D_METHOD("make_dir", "path"), &_Directory::make_dir);
 	ClassDB::bind_method(D_METHOD("make_dir", "path"), &_Directory::make_dir);
 	ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &_Directory::make_dir_recursive);
 	ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &_Directory::make_dir_recursive);
 	ClassDB::bind_method(D_METHOD("file_exists", "path"), &_Directory::file_exists);
 	ClassDB::bind_method(D_METHOD("file_exists", "path"), &_Directory::file_exists);

+ 1 - 1
core/bind/core_bind.h

@@ -572,7 +572,7 @@ public:
 	int get_current_drive();
 	int get_current_drive();
 
 
 	Error change_dir(String p_dir); // Can be relative or absolute, return false on success.
 	Error change_dir(String p_dir); // Can be relative or absolute, return false on success.
-	String get_current_dir(); // Return current dir location.
+	String get_current_dir(bool p_include_drive = true); // Return current dir location.
 
 
 	Error make_dir(String p_dir);
 	Error make_dir(String p_dir);
 	Error make_dir_recursive(String p_dir);
 	Error make_dir_recursive(String p_dir);

+ 1 - 1
core/io/file_access_pack.cpp

@@ -454,7 +454,7 @@ Error DirAccessPack::change_dir(String p_dir) {
 	return OK;
 	return OK;
 }
 }
 
 
-String DirAccessPack::get_current_dir() {
+String DirAccessPack::get_current_dir(bool p_include_drive) {
 
 
 	PackedData::PackedDir *pd = current;
 	PackedData::PackedDir *pd = current;
 	String p = current->name;
 	String p = current->name;

+ 1 - 1
core/io/file_access_pack.h

@@ -216,7 +216,7 @@ public:
 	virtual String get_drive(int p_drive);
 	virtual String get_drive(int p_drive);
 
 
 	virtual Error change_dir(String p_dir);
 	virtual Error change_dir(String p_dir);
-	virtual String get_current_dir();
+	virtual String get_current_dir(bool p_include_drive = true);
 
 
 	virtual bool file_exists(String p_file);
 	virtual bool file_exists(String p_file);
 	virtual bool dir_exists(String p_dir);
 	virtual bool dir_exists(String p_dir);

+ 5 - 0
core/os/dir_access.cpp

@@ -66,6 +66,11 @@ int DirAccess::get_current_drive() {
 	return 0;
 	return 0;
 }
 }
 
 
+bool DirAccess::drives_are_shortcuts() {
+
+	return false;
+}
+
 static Error _erase_recursive(DirAccess *da) {
 static Error _erase_recursive(DirAccess *da) {
 
 
 	List<String> dirs;
 	List<String> dirs;

+ 2 - 1
core/os/dir_access.h

@@ -76,9 +76,10 @@ public:
 	virtual int get_drive_count() = 0;
 	virtual int get_drive_count() = 0;
 	virtual String get_drive(int p_drive) = 0;
 	virtual String get_drive(int p_drive) = 0;
 	virtual int get_current_drive();
 	virtual int get_current_drive();
+	virtual bool drives_are_shortcuts();
 
 
 	virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success
 	virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success
-	virtual String get_current_dir() = 0; ///< return current dir location
+	virtual String get_current_dir(bool p_include_drive = true) = 0; ///< return current dir location
 	virtual Error make_dir(String p_dir) = 0;
 	virtual Error make_dir(String p_dir) = 0;
 	virtual Error make_dir_recursive(String p_dir);
 	virtual Error make_dir_recursive(String p_dir);
 	virtual Error erase_contents_recursive(); //super dangerous, use with care!
 	virtual Error erase_contents_recursive(); //super dangerous, use with care!

+ 3 - 0
doc/classes/Directory.xml

@@ -77,8 +77,11 @@
 		<method name="get_current_dir">
 		<method name="get_current_dir">
 			<return type="String">
 			<return type="String">
 			</return>
 			</return>
+			<argument index="0" name="include_drive" type="bool" default="true">
+			</argument>
 			<description>
 			<description>
 				Returns the absolute path to the currently opened directory (e.g. [code]res://folder[/code] or [code]C:\tmp\folder[/code]).
 				Returns the absolute path to the currently opened directory (e.g. [code]res://folder[/code] or [code]C:\tmp\folder[/code]).
+				On Windows, if [code]include_drive[/code] is [code]false[/code], the leading drive specificator is omitted from the returned value (e.g. [code]\tmp\folder[/code]).
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="get_current_drive">
 		<method name="get_current_drive">

+ 6 - 1
drivers/unix/dir_access_unix.cpp

@@ -269,6 +269,11 @@ String DirAccessUnix::get_drive(int p_drive) {
 	return list[p_drive];
 	return list[p_drive];
 }
 }
 
 
+bool DirAccessUnix::drives_are_shortcuts() {
+
+	return true;
+}
+
 Error DirAccessUnix::make_dir(String p_dir) {
 Error DirAccessUnix::make_dir(String p_dir) {
 
 
 	GLOBAL_LOCK_FUNCTION
 	GLOBAL_LOCK_FUNCTION
@@ -337,7 +342,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
 	return OK;
 	return OK;
 }
 }
 
 
-String DirAccessUnix::get_current_dir() {
+String DirAccessUnix::get_current_dir(bool p_include_drive) {
 
 
 	String base = _get_root_path();
 	String base = _get_root_path();
 	if (base != "") {
 	if (base != "") {

+ 2 - 1
drivers/unix/dir_access_unix.h

@@ -63,9 +63,10 @@ public:
 
 
 	virtual int get_drive_count();
 	virtual int get_drive_count();
 	virtual String get_drive(int p_drive);
 	virtual String get_drive(int p_drive);
+	virtual bool drives_are_shortcuts();
 
 
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
-	virtual String get_current_dir(); ///< return current dir location
+	virtual String get_current_dir(bool p_include_drive = true); ///< return current dir location
 	virtual Error make_dir(String p_dir);
 	virtual Error make_dir(String p_dir);
 
 
 	virtual bool file_exists(String p_file);
 	virtual bool file_exists(String p_file);

+ 6 - 2
drivers/windows/dir_access_windows.cpp

@@ -189,7 +189,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
 	return ERR_CANT_CREATE;
 	return ERR_CANT_CREATE;
 }
 }
 
 
-String DirAccessWindows::get_current_dir() {
+String DirAccessWindows::get_current_dir(bool p_include_drive) {
 
 
 	String base = _get_root_path();
 	String base = _get_root_path();
 	if (base != "") {
 	if (base != "") {
@@ -203,7 +203,11 @@ String DirAccessWindows::get_current_dir() {
 	} else {
 	} else {
 	}
 	}
 
 
-	return current_dir;
+	if (p_include_drive) {
+		return current_dir;
+	} else {
+		return current_dir.right(current_dir.find(":") + 1);
+	}
 }
 }
 
 
 bool DirAccessWindows::file_exists(String p_file) {
 bool DirAccessWindows::file_exists(String p_file) {

+ 1 - 1
drivers/windows/dir_access_windows.h

@@ -69,7 +69,7 @@ public:
 	virtual String get_drive(int p_drive);
 	virtual String get_drive(int p_drive);
 
 
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
-	virtual String get_current_dir(); ///< return current dir location
+	virtual String get_current_dir(bool p_include_drive = true); ///< return current dir location
 
 
 	virtual bool file_exists(String p_file);
 	virtual bool file_exists(String p_file);
 	virtual bool dir_exists(String p_dir);
 	virtual bool dir_exists(String p_dir);

+ 18 - 4
editor/editor_file_dialog.cpp

@@ -199,7 +199,10 @@ Vector<String> EditorFileDialog::get_selected_files() const {
 
 
 void EditorFileDialog::update_dir() {
 void EditorFileDialog::update_dir() {
 
 
-	dir->set_text(dir_access->get_current_dir());
+	if (drives->is_visible()) {
+		drives->select(dir_access->get_current_drive());
+	}
+	dir->set_text(dir_access->get_current_dir(false));
 
 
 	// Disable "Open" button only when selecting file(s) mode.
 	// Disable "Open" button only when selecting file(s) mode.
 	get_ok()->set_disabled(_is_open_should_be_disabled());
 	get_ok()->set_disabled(_is_open_should_be_disabled());
@@ -946,7 +949,7 @@ void EditorFileDialog::add_filter(const String &p_filter) {
 
 
 String EditorFileDialog::get_current_dir() const {
 String EditorFileDialog::get_current_dir() const {
 
 
-	return dir->get_text();
+	return dir_access->get_current_dir();
 }
 }
 String EditorFileDialog::get_current_file() const {
 String EditorFileDialog::get_current_file() const {
 
 
@@ -954,7 +957,7 @@ String EditorFileDialog::get_current_file() const {
 }
 }
 String EditorFileDialog::get_current_path() const {
 String EditorFileDialog::get_current_path() const {
 
 
-	return dir->get_text().plus_file(file->get_text());
+	return dir_access->get_current_dir().plus_file(file->get_text());
 }
 }
 void EditorFileDialog::set_current_dir(const String &p_dir) {
 void EditorFileDialog::set_current_dir(const String &p_dir) {
 
 
@@ -1149,6 +1152,12 @@ void EditorFileDialog::_update_drives() {
 		drives->hide();
 		drives->hide();
 	} else {
 	} else {
 		drives->clear();
 		drives->clear();
+		Node *dp = drives->get_parent();
+		if (dp) {
+			dp->remove_child(drives);
+		}
+		dp = dir_access->drives_are_shortcuts() ? shortcuts_container : drives_container;
+		dp->add_child(drives);
 		drives->show();
 		drives->show();
 
 
 		for (int i = 0; i < dir_access->get_drive_count(); i++) {
 		for (int i = 0; i < dir_access->get_drive_count(); i++) {
@@ -1517,6 +1526,9 @@ EditorFileDialog::EditorFileDialog() {
 
 
 	pathhb->add_child(memnew(Label(TTR("Path:"))));
 	pathhb->add_child(memnew(Label(TTR("Path:"))));
 
 
+	drives_container = memnew(HBoxContainer);
+	pathhb->add_child(drives_container);
+
 	dir = memnew(LineEdit);
 	dir = memnew(LineEdit);
 	pathhb->add_child(dir);
 	pathhb->add_child(dir);
 	dir->set_h_size_flags(SIZE_EXPAND_FILL);
 	dir->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1560,8 +1572,10 @@ EditorFileDialog::EditorFileDialog() {
 	mode_list->set_tooltip(TTR("View items as a list."));
 	mode_list->set_tooltip(TTR("View items as a list."));
 	pathhb->add_child(mode_list);
 	pathhb->add_child(mode_list);
 
 
+	shortcuts_container = memnew(HBoxContainer);
+	pathhb->add_child(shortcuts_container);
+
 	drives = memnew(OptionButton);
 	drives = memnew(OptionButton);
-	pathhb->add_child(drives);
 	drives->connect("item_selected", callable_mp(this, &EditorFileDialog::_select_drive));
 	drives->connect("item_selected", callable_mp(this, &EditorFileDialog::_select_drive));
 
 
 	makedir = memnew(Button);
 	makedir = memnew(Button);

+ 2 - 0
editor/editor_file_dialog.h

@@ -100,6 +100,8 @@ private:
 	ToolButton *dir_next;
 	ToolButton *dir_next;
 	ToolButton *dir_up;
 	ToolButton *dir_up;
 
 
+	HBoxContainer *drives_container;
+	HBoxContainer *shortcuts_container;
 	OptionButton *drives;
 	OptionButton *drives;
 	ItemList *item_list;
 	ItemList *item_list;
 	PopupMenu *item_menu;
 	PopupMenu *item_menu;

+ 1 - 1
platform/android/dir_access_jandroid.cpp

@@ -144,7 +144,7 @@ Error DirAccessJAndroid::change_dir(String p_dir) {
 	return OK;
 	return OK;
 }
 }
 
 
-String DirAccessJAndroid::get_current_dir() {
+String DirAccessJAndroid::get_current_dir(bool p_include_drive) {
 
 
 	return "res://" + current_dir;
 	return "res://" + current_dir;
 }
 }

+ 1 - 1
platform/android/dir_access_jandroid.h

@@ -65,7 +65,7 @@ public:
 	virtual String get_drive(int p_drive);
 	virtual String get_drive(int p_drive);
 
 
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
 	virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
-	virtual String get_current_dir(); ///< return current dir location
+	virtual String get_current_dir(bool p_include_drive = true); ///< return current dir location
 
 
 	virtual bool file_exists(String p_file);
 	virtual bool file_exists(String p_file);
 	virtual bool dir_exists(String p_dir);
 	virtual bool dir_exists(String p_dir);

+ 16 - 3
scene/gui/file_dialog.cpp

@@ -135,7 +135,8 @@ Vector<String> FileDialog::get_selected_files() const {
 
 
 void FileDialog::update_dir() {
 void FileDialog::update_dir() {
 
 
-	dir->set_text(dir_access->get_current_dir());
+	dir->set_text(dir_access->get_current_dir(false));
+
 	if (drives->is_visible()) {
 	if (drives->is_visible()) {
 		drives->select(dir_access->get_current_drive());
 		drives->select(dir_access->get_current_drive());
 	}
 	}
@@ -789,6 +790,12 @@ void FileDialog::_update_drives() {
 		drives->hide();
 		drives->hide();
 	} else {
 	} else {
 		drives->clear();
 		drives->clear();
+		Node *dp = drives->get_parent();
+		if (dp) {
+			dp->remove_child(drives);
+		}
+		dp = dir_access->drives_are_shortcuts() ? shortcuts_container : drives_container;
+		dp->add_child(drives);
 		drives->show();
 		drives->show();
 
 
 		for (int i = 0; i < dir_access->get_drive_count(); i++) {
 		for (int i = 0; i < dir_access->get_drive_count(); i++) {
@@ -890,11 +897,14 @@ FileDialog::FileDialog() {
 	hbc->add_child(dir_up);
 	hbc->add_child(dir_up);
 	dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
 	dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
 
 
+	hbc->add_child(memnew(Label(RTR("Path:"))));
+
+	drives_container = memnew(HBoxContainer);
+	hbc->add_child(drives_container);
+
 	drives = memnew(OptionButton);
 	drives = memnew(OptionButton);
-	hbc->add_child(drives);
 	drives->connect("item_selected", callable_mp(this, &FileDialog::_select_drive));
 	drives->connect("item_selected", callable_mp(this, &FileDialog::_select_drive));
 
 
-	hbc->add_child(memnew(Label(RTR("Path:"))));
 	dir = memnew(LineEdit);
 	dir = memnew(LineEdit);
 	hbc->add_child(dir);
 	hbc->add_child(dir);
 	dir->set_h_size_flags(SIZE_EXPAND_FILL);
 	dir->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -911,6 +921,9 @@ FileDialog::FileDialog() {
 	show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files));
 	show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files));
 	hbc->add_child(show_hidden);
 	hbc->add_child(show_hidden);
 
 
+	shortcuts_container = memnew(HBoxContainer);
+	hbc->add_child(shortcuts_container);
+
 	makedir = memnew(Button);
 	makedir = memnew(Button);
 	makedir->set_text(RTR("Create Folder"));
 	makedir->set_text(RTR("Create Folder"));
 	makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir));
 	makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir));

+ 2 - 0
scene/gui/file_dialog.h

@@ -76,6 +76,8 @@ private:
 	VBoxContainer *vbox;
 	VBoxContainer *vbox;
 	Mode mode;
 	Mode mode;
 	LineEdit *dir;
 	LineEdit *dir;
+	HBoxContainer *drives_container;
+	HBoxContainer *shortcuts_container;
 	OptionButton *drives;
 	OptionButton *drives;
 	Tree *tree;
 	Tree *tree;
 	HBoxContainer *file_box;
 	HBoxContainer *file_box;