Merge pull request #47163 from bruvzg/macos_sandbox_file_dialog

FileDialog: add Back/Forward buttons, add message for inaccessible folders.
This commit is contained in:
Rémi Verschelde 2021-03-26 00:00:25 +01:00 committed by GitHub
commit c6b9ceadf2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 134 additions and 0 deletions

View file

@ -84,6 +84,8 @@ public:
virtual bool file_exists(String p_file) = 0;
virtual bool dir_exists(String p_dir) = 0;
virtual bool is_readable(String p_dir) { return true; };
virtual bool is_writable(String p_dir) { return true; };
static bool exists(String p_dir);
virtual size_t get_space_left() = 0;

View file

@ -133,6 +133,9 @@
</constant>
</constants>
<theme_items>
<theme_item name="back_folder" type="Texture2D">
Custom icon for the back arrow.
</theme_item>
<theme_item name="file" type="Texture2D">
Custom icon for files.
</theme_item>
@ -148,6 +151,9 @@
<theme_item name="folder_icon_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
The color modulation applied to the folder icon.
</theme_item>
<theme_item name="forward_folder" type="Texture2D">
Custom icon for the forward arrow.
</theme_item>
<theme_item name="parent_folder" type="Texture2D">
Custom icon for the parent folder arrow.
</theme_item>

View file

@ -102,6 +102,28 @@ bool DirAccessUnix::dir_exists(String p_dir) {
return (success && S_ISDIR(flags.st_mode));
}
bool DirAccessUnix::is_readable(String p_dir) {
GLOBAL_LOCK_FUNCTION
if (p_dir.is_rel_path()) {
p_dir = get_current_dir().plus_file(p_dir);
}
p_dir = fix_path(p_dir);
return (access(p_dir.utf8().get_data(), R_OK) == 0);
}
bool DirAccessUnix::is_writable(String p_dir) {
GLOBAL_LOCK_FUNCTION
if (p_dir.is_rel_path()) {
p_dir = get_current_dir().plus_file(p_dir);
}
p_dir = fix_path(p_dir);
return (access(p_dir.utf8().get_data(), W_OK) == 0);
}
uint64_t DirAccessUnix::get_modified_time(String p_file) {
if (p_file.is_rel_path()) {
p_file = current_dir.plus_file(p_file);

View file

@ -71,6 +71,8 @@ public:
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
virtual bool is_readable(String p_dir);
virtual bool is_writable(String p_dir);
virtual uint64_t get_modified_time(String p_file);

View file

@ -1262,6 +1262,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// FileDialog
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
theme->set_icon("parent_folder", "FileDialog", theme->get_icon("ArrowUp", "EditorIcons"));
theme->set_icon("back_folder", "FileDialog", theme->get_icon("Back", "EditorIcons"));
theme->set_icon("forward_folder", "FileDialog", theme->get_icon("Forward", "EditorIcons"));
theme->set_icon("reload", "FileDialog", theme->get_icon("Reload", "EditorIcons"));
theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon("GuiVisibilityVisible", "EditorIcons"));
// Use a different color for folder icons to make them easier to distinguish from files.

View file

@ -57,6 +57,14 @@ void FileDialog::_theme_changed() {
dir_up->add_theme_color_override("icon_hover_color", font_hover_color);
dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color);
dir_prev->add_theme_color_override("icon_color_normal", font_color);
dir_prev->add_theme_color_override("icon_color_hover", font_hover_color);
dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color);
dir_next->add_theme_color_override("icon_color_normal", font_color);
dir_next->add_theme_color_override("icon_color_hover", font_hover_color);
dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color);
refresh->add_theme_color_override("icon_normal_color", font_color);
refresh->add_theme_color_override("icon_hover_color", font_hover_color);
refresh->add_theme_color_override("icon_pressed_color", font_pressed_color);
@ -74,6 +82,13 @@ void FileDialog::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
dir_up->set_icon(vbox->get_theme_icon("parent_folder", "FileDialog"));
if (vbox->is_layout_rtl()) {
dir_prev->set_icon(vbox->get_theme_icon("forward_folder", "FileDialog"));
dir_next->set_icon(vbox->get_theme_icon("back_folder", "FileDialog"));
} else {
dir_prev->set_icon(vbox->get_theme_icon("back_folder", "FileDialog"));
dir_next->set_icon(vbox->get_theme_icon("forward_folder", "FileDialog"));
}
refresh->set_icon(vbox->get_theme_icon("reload", "FileDialog"));
show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog"));
_theme_changed();
@ -144,6 +159,7 @@ void FileDialog::_dir_entered(String p_dir) {
file->set_text("");
invalidate();
update_dir();
_push_history();
}
void FileDialog::_file_entered(const String &p_file) {
@ -177,6 +193,21 @@ void FileDialog::_post_popup() {
} else {
file_box->set_visible(true);
}
local_history.clear();
local_history_pos = -1;
_push_history();
}
void FileDialog::_push_history() {
local_history.resize(local_history_pos + 1);
String new_path = dir_access->get_current_dir();
if (local_history.size() == 0 || new_path != local_history[local_history_pos]) {
local_history.push_back(new_path);
local_history_pos++;
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(true);
}
}
void FileDialog::_action_pressed() {
@ -316,6 +347,35 @@ void FileDialog::_go_up() {
dir_access->change_dir("..");
update_file_list();
update_dir();
_push_history();
}
void FileDialog::_go_back() {
if (local_history_pos <= 0) {
return;
}
local_history_pos--;
dir_access->change_dir(local_history[local_history_pos]);
update_file_list();
update_dir();
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(local_history_pos == local_history.size() - 1);
}
void FileDialog::_go_forward() {
if (local_history_pos == local_history.size() - 1) {
return;
}
local_history_pos++;
dir_access->change_dir(local_history[local_history_pos]);
update_file_list();
update_dir();
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(local_history_pos == local_history.size() - 1);
}
void FileDialog::deselect_all() {
@ -377,6 +437,7 @@ void FileDialog::_tree_item_activated() {
}
call_deferred("_update_file_list");
call_deferred("_update_dir");
_push_history();
} else {
_action_pressed();
}
@ -415,6 +476,13 @@ void FileDialog::update_file_list() {
bool is_hidden;
String item;
if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
message->hide();
} else {
message->set_text(TTRC("You don't have permission to access contents of this folder."));
message->show();
}
while ((item = dir_access->get_next()) != "") {
if (item == "." || item == "..") {
continue;
@ -602,6 +670,7 @@ void FileDialog::set_current_dir(const String &p_dir) {
dir_access->change_dir(p_dir);
update_dir();
invalidate();
_push_history();
}
void FileDialog::set_current_file(const String &p_file) {
@ -737,6 +806,7 @@ void FileDialog::_make_dir_confirm() {
invalidate();
update_filters();
update_dir();
_push_history();
} else {
mkdirerr->popup_centered(Size2(250, 50));
}
@ -754,6 +824,7 @@ void FileDialog::_select_drive(int p_idx) {
file->set_text("");
invalidate();
update_dir();
_push_history();
}
void FileDialog::_update_drives() {
@ -861,10 +932,20 @@ FileDialog::FileDialog() {
HBoxContainer *hbc = memnew(HBoxContainer);
dir_prev = memnew(Button);
dir_prev->set_flat(true);
dir_prev->set_tooltip(TTRC("Go to previous folder."));
dir_next = memnew(Button);
dir_next->set_flat(true);
dir_next->set_tooltip(TTRC("Go to next folder."));
dir_up = memnew(Button);
dir_up->set_flat(true);
dir_up->set_tooltip(TTRC("Go to parent folder."));
hbc->add_child(dir_prev);
hbc->add_child(dir_next);
hbc->add_child(dir_up);
dir_prev->connect("pressed", callable_mp(this, &FileDialog::_go_back));
dir_next->connect("pressed", callable_mp(this, &FileDialog::_go_forward));
dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
hbc->add_child(memnew(Label(TTRC("Path:"))));
@ -908,6 +989,13 @@ FileDialog::FileDialog() {
tree->set_hide_root(true);
vbox->add_margin_child(TTRC("Directories & Files:"), tree, true);
message = memnew(Label);
message->hide();
message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
message->set_align(Label::ALIGN_CENTER);
message->set_valign(Label::VALIGN_CENTER);
tree->add_child(message);
file_box = memnew(HBoxContainer);
file_box->add_child(memnew(Label(TTRC("File:"))));
file = memnew(LineEdit);

View file

@ -86,6 +86,10 @@ private:
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
Label *message;
Button *dir_prev;
Button *dir_next;
Button *dir_up;
Button *refresh;
@ -93,6 +97,10 @@ private:
Vector<String> filters;
Vector<String> local_history;
int local_history_pos = 0;
void _push_history();
bool mode_overrides_title = true;
static bool default_show_hidden_files;
@ -119,6 +127,8 @@ private:
void _make_dir();
void _make_dir_confirm();
void _go_up();
void _go_back();
void _go_forward();
void _update_drives();

View file

@ -632,6 +632,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// File Dialog
theme->set_icon("parent_folder", "FileDialog", make_icon(icon_parent_folder_png));
theme->set_icon("back_folder", "FileDialog", make_icon(arrow_left_png));
theme->set_icon("forward_folder", "FileDialog", make_icon(arrow_right_png));
theme->set_icon("reload", "FileDialog", make_icon(icon_reload_png));
theme->set_icon("toggle_hidden", "FileDialog", make_icon(icon_visibility_png));