Merge pull request #117010 from bruvzg/voll_name_win

[Windows] Show drive names in file dialog.
This commit is contained in:
Thaddeus Crews committed 2026-03-30 13:35:34 -05:00
commit 656a268688
7 files changed
+100 -36

No files matched your search

+8 -2
View File
@@ -265,11 +265,16 @@ int DirAccess::_get_drive_count() {
return d->get_drive_count();
}
String DirAccess::get_drive_name(int p_idx) {
String DirAccess::_get_drive_name(int p_idx) {
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
return d->get_drive(p_idx);
}
String DirAccess::_get_drive_label(int p_idx) {
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
return d->get_drive_label(p_idx);
}
Error DirAccess::make_dir_absolute(const String &p_dir) {
Ref<DirAccess> d = DirAccess::create_for_path(p_dir);
return d->make_dir(p_dir);
@@ -646,7 +651,8 @@ void DirAccess::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_directories"), &DirAccess::get_directories);
ClassDB::bind_static_method("DirAccess", D_METHOD("get_directories_at", "path"), &DirAccess::get_directories_at);
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_count"), &DirAccess::_get_drive_count);
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_name", "idx"), &DirAccess::get_drive_name);
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_name", "idx"), &DirAccess::_get_drive_name);
ClassDB::bind_static_method("DirAccess", D_METHOD("get_drive_label", "idx"), &DirAccess::_get_drive_label);
ClassDB::bind_method(D_METHOD("get_current_drive"), &DirAccess::get_current_drive);
ClassDB::bind_method(D_METHOD("change_dir", "to_dir"), &DirAccess::change_dir);
ClassDB::bind_method(D_METHOD("get_current_dir", "include_drive"), &DirAccess::get_current_dir, DEFVAL(true));
+3 -1
View File
@@ -91,6 +91,7 @@ public:
virtual int get_drive_count() = 0;
virtual String get_drive(int p_drive) = 0;
virtual String get_drive_label(int p_drive) { return String(); }
virtual int get_current_drive();
virtual bool drives_are_shortcuts();
@@ -145,7 +146,8 @@ public:
static Ref<DirAccess> create_temp(const String &p_prefix = "", bool p_keep = false, Error *r_error = nullptr);
static int _get_drive_count();
static String get_drive_name(int p_idx);
static String _get_drive_name(int p_idx);
static String _get_drive_label(int p_idx);
static Error make_dir_absolute(const String &p_dir);
static Error make_dir_recursive_absolute(const String &p_dir);
+9 -1
View File
@@ -186,6 +186,14 @@
On other platforms, the method returns 0.
</description>
</method>
<method name="get_drive_label" qualifiers="static">
<return type="String" />
<param index="0" name="idx" type="int" />
<description>
On Windows, returns the label of the drive (partition) passed as an argument.
On other platforms, or if the requested drive does not exist, returns an empty String.
</description>
</method>
<method name="get_drive_name" qualifiers="static">
<return type="String" />
<param index="0" name="idx" type="int" />
@@ -194,7 +202,7 @@
On macOS, returns the path to the mounted volume passed as an argument.
On Linux, returns the path to the mounted volume or GTK 3 bookmark passed as an argument.
On Android (API level 30+), returns the path to the mounted volume as an argument.
On other platforms, or if the requested drive does not exist, the method returns an empty String.
On other platforms, or if the requested drive does not exist, returns an empty String.
</description>
</method>
<method name="get_files">
+28 -14
View File
@@ -135,16 +135,38 @@ void DirAccessWindows::list_dir_end() {
}
}
void DirAccessWindows::_update_drives() {
drives.clear();
DWORD mask = GetLogicalDrives();
for (int i = 0; i < MAX_DRIVES; i++) {
if (mask & (1 << i)) {
String path = String::chr('A' + i) + ":";
String label;
char16_t wlabel[4096];
if (GetVolumeInformationW((LPCWSTR)(path).utf16().get_data(), (LPWSTR)wlabel, 4096, nullptr, nullptr, nullptr, nullptr, 0)) {
label = String::utf16(wlabel);
}
drives.push_back(DriveInfo{ path, label });
}
}
}
int DirAccessWindows::get_drive_count() {
return drive_count;
return drives.size();
}
String DirAccessWindows::get_drive_label(int p_drive) {
if (p_drive < 0 || p_drive >= (int)drives.size()) {
return String();
}
return drives[p_drive].label;
}
String DirAccessWindows::get_drive(int p_drive) {
if (p_drive < 0 || p_drive >= drive_count) {
return "";
if (p_drive < 0 || p_drive >= (int)drives.size()) {
return String();
}
return String::chr(drives[p_drive]) + ":";
return drives[p_drive].path;
}
Error DirAccessWindows::change_dir(String p_dir) {
@@ -485,15 +507,7 @@ DirAccessWindows::DirAccessWindows() {
GetCurrentDirectoryW(real_current_dir_name.size(), (LPWSTR)real_current_dir_name.ptrw());
current_dir = String::utf16((const char16_t *)real_current_dir_name.get_data());
DWORD mask = GetLogicalDrives();
for (int i = 0; i < MAX_DRIVES; i++) {
if (mask & (1 << i)) { //DRIVE EXISTS
drives[drive_count] = 'A' + i;
drive_count++;
}
}
_update_drives();
change_dir(".");
}
+8 -2
View File
@@ -45,8 +45,13 @@ class DirAccessWindows : public DirAccess {
DirAccessWindowsPrivate *p = nullptr;
/* Windows stuff */
char drives[MAX_DRIVES] = { 0 }; // a-z:
int drive_count = 0;
struct DriveInfo {
String path;
String label;
};
LocalVector<DriveInfo> drives;
void _update_drives();
String current_dir;
@@ -65,6 +70,7 @@ public:
virtual int get_drive_count() override;
virtual String get_drive(int p_drive) override;
virtual String get_drive_label(int p_drive) override;
virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location
+42 -15
View File
@@ -370,14 +370,24 @@ void FileDialog::update_dir() {
if (drives->is_visible()) {
if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(ETR("Network"));
drives->set_item_disabled(-1, true);
drives->select(drives->get_item_count() - 1);
PopupMenu *pm = drives->get_popup();
pm->add_item(ETR("Network"));
Dictionary meta;
meta["index"] = -1;
meta["path"] = String();
meta["name"] = ETR("Network");
pm->set_item_metadata(-1, meta);
pm->set_item_disabled(-1, true);
drives->set_text(meta["name"]);
selected_drive = pm->get_item_count() - 1;
} else {
PopupMenu *pm = drives->get_popup();
int cur = dir_access->get_current_drive();
for (int i = 0; i < drives->get_item_count(); i++) {
if (drives->get_item_metadata(i).operator int() == cur) {
drives->select(i);
for (int i = 0; i < pm->get_item_count(); i++) {
const Dictionary &meta = pm->get_item_metadata(i);
if (meta["index"].operator int() == cur) {
drives->set_text(meta["name"]);
selected_drive = i;
break;
}
}
@@ -393,7 +403,7 @@ void FileDialog::_dir_submitted(String p_dir) {
#ifdef WINDOWS_ENABLED
if (root_prefix.is_empty() && drives->is_visible() && !new_dir.is_network_share_path() && new_dir.is_absolute_path() && new_dir.find(":/") == -1 && new_dir.find(":\\") == -1) {
// Non network path without X:/ prefix on Windows, add drive letter.
new_dir = drives->get_item_text(drives->get_selected()).path_join(new_dir);
new_dir = drives->get_popup()->get_item_metadata(selected_drive).operator Dictionary()["path"].operator String().path_join(new_dir);
}
#endif
if (!root_prefix.is_empty()) {
@@ -1615,8 +1625,11 @@ void FileDialog::_make_dir() {
}
void FileDialog::_select_drive(int p_idx) {
String d = drives->get_item_text(p_idx);
_change_dir(d);
const Dictionary &meta = drives->get_popup()->get_item_metadata(p_idx);
drives->set_text(meta["name"]);
selected_drive = p_idx;
_change_dir(meta["path"]);
filename_edit->set_text("");
_push_history();
}
@@ -1662,7 +1675,8 @@ void FileDialog::_update_drives(bool p_select) {
if (drive_map.size() == 0) {
drives->hide();
} else {
drives->clear();
PopupMenu *pm = drives->get_popup();
pm->clear();
Node *dp = drives->get_parent();
if (dp) {
dp->remove_child(drives);
@@ -1672,10 +1686,22 @@ void FileDialog::_update_drives(bool p_select) {
drives->show();
for (const KeyValue<int, String> &drv : drive_map) {
drives->add_item(drv.value);
drives->set_item_metadata(-1, drv.key);
String display_name = drv.value;
String lbl = dir_access->get_drive_label(drv.key);
if (!lbl.is_empty()) {
display_name = drv.value + " (" + lbl + ")";
}
pm->add_item(display_name);
pm->set_item_tooltip(-1, drv.value);
Dictionary meta;
meta["index"] = drv.key;
meta["path"] = drv.value;
meta["name"] = drv.value;
pm->set_item_metadata(-1, meta);
if (p_select && drv.key == cur) {
drives->select(drives->get_item_count() - 1);
drives->set_text(drv.value);
selected_drive = drv.key;
}
}
}
@@ -2367,8 +2393,9 @@ FileDialog::FileDialog() {
drives_container = memnew(HBoxContainer);
top_toolbar->add_child(drives_container);
drives = memnew(OptionButton);
drives->connect(SceneStringName(item_selected), callable_mp(this, &FileDialog::_select_drive));
drives = memnew(MenuButton);
drives->set_flat(false);
drives->get_popup()->connect("index_pressed", callable_mp(this, &FileDialog::_select_drive));
drives->set_accessibility_name(ETR("Drive"));
top_toolbar->add_child(drives);
+2 -1
View File
@@ -214,7 +214,8 @@ private:
Button *dir_up = nullptr;
HBoxContainer *drives_container = nullptr;
OptionButton *drives = nullptr;
MenuButton *drives = nullptr;
int selected_drive = 0;
LineEdit *directory_edit = nullptr;
HBoxContainer *shortcuts_container = nullptr;