FileDialog: add Back/Forward buttons, add message for inaccessible folders.
This commit is contained in:
parent
0339200972
commit
b202a0dd2a
8 changed files with 134 additions and 0 deletions
|
@ -84,6 +84,8 @@ public:
|
||||||
|
|
||||||
virtual bool file_exists(String p_file) = 0;
|
virtual bool file_exists(String p_file) = 0;
|
||||||
virtual bool dir_exists(String p_dir) = 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);
|
static bool exists(String p_dir);
|
||||||
virtual size_t get_space_left() = 0;
|
virtual size_t get_space_left() = 0;
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,9 @@
|
||||||
</constant>
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
<theme_items>
|
<theme_items>
|
||||||
|
<theme_item name="back_folder" type="Texture2D">
|
||||||
|
Custom icon for the back arrow.
|
||||||
|
</theme_item>
|
||||||
<theme_item name="file" type="Texture2D">
|
<theme_item name="file" type="Texture2D">
|
||||||
Custom icon for files.
|
Custom icon for files.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
@ -148,6 +151,9 @@
|
||||||
<theme_item name="folder_icon_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
|
<theme_item name="folder_icon_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
|
||||||
The color modulation applied to the folder icon.
|
The color modulation applied to the folder icon.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
<theme_item name="forward_folder" type="Texture2D">
|
||||||
|
Custom icon for the forward arrow.
|
||||||
|
</theme_item>
|
||||||
<theme_item name="parent_folder" type="Texture2D">
|
<theme_item name="parent_folder" type="Texture2D">
|
||||||
Custom icon for the parent folder arrow.
|
Custom icon for the parent folder arrow.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
|
|
@ -102,6 +102,28 @@ bool DirAccessUnix::dir_exists(String p_dir) {
|
||||||
return (success && S_ISDIR(flags.st_mode));
|
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) {
|
uint64_t DirAccessUnix::get_modified_time(String p_file) {
|
||||||
if (p_file.is_rel_path()) {
|
if (p_file.is_rel_path()) {
|
||||||
p_file = current_dir.plus_file(p_file);
|
p_file = current_dir.plus_file(p_file);
|
||||||
|
|
|
@ -71,6 +71,8 @@ public:
|
||||||
|
|
||||||
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);
|
||||||
|
virtual bool is_readable(String p_dir);
|
||||||
|
virtual bool is_writable(String p_dir);
|
||||||
|
|
||||||
virtual uint64_t get_modified_time(String p_file);
|
virtual uint64_t get_modified_time(String p_file);
|
||||||
|
|
||||||
|
|
|
@ -1260,6 +1260,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
||||||
// FileDialog
|
// FileDialog
|
||||||
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
|
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
|
||||||
theme->set_icon("parent_folder", "FileDialog", theme->get_icon("ArrowUp", "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("reload", "FileDialog", theme->get_icon("Reload", "EditorIcons"));
|
||||||
theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon("GuiVisibilityVisible", "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.
|
// Use a different color for folder icons to make them easier to distinguish from files.
|
||||||
|
|
|
@ -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_hover_color", font_hover_color);
|
||||||
dir_up->add_theme_color_override("icon_pressed_color", font_pressed_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_normal_color", font_color);
|
||||||
refresh->add_theme_color_override("icon_hover_color", font_hover_color);
|
refresh->add_theme_color_override("icon_hover_color", font_hover_color);
|
||||||
refresh->add_theme_color_override("icon_pressed_color", font_pressed_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) {
|
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||||
dir_up->set_icon(vbox->get_theme_icon("parent_folder", "FileDialog"));
|
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"));
|
refresh->set_icon(vbox->get_theme_icon("reload", "FileDialog"));
|
||||||
show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog"));
|
show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog"));
|
||||||
_theme_changed();
|
_theme_changed();
|
||||||
|
@ -144,6 +159,7 @@ void FileDialog::_dir_entered(String p_dir) {
|
||||||
file->set_text("");
|
file->set_text("");
|
||||||
invalidate();
|
invalidate();
|
||||||
update_dir();
|
update_dir();
|
||||||
|
_push_history();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::_file_entered(const String &p_file) {
|
void FileDialog::_file_entered(const String &p_file) {
|
||||||
|
@ -177,6 +193,21 @@ void FileDialog::_post_popup() {
|
||||||
} else {
|
} else {
|
||||||
file_box->set_visible(true);
|
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() {
|
void FileDialog::_action_pressed() {
|
||||||
|
@ -316,6 +347,35 @@ void FileDialog::_go_up() {
|
||||||
dir_access->change_dir("..");
|
dir_access->change_dir("..");
|
||||||
update_file_list();
|
update_file_list();
|
||||||
update_dir();
|
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() {
|
void FileDialog::deselect_all() {
|
||||||
|
@ -377,6 +437,7 @@ void FileDialog::_tree_item_activated() {
|
||||||
}
|
}
|
||||||
call_deferred("_update_file_list");
|
call_deferred("_update_file_list");
|
||||||
call_deferred("_update_dir");
|
call_deferred("_update_dir");
|
||||||
|
_push_history();
|
||||||
} else {
|
} else {
|
||||||
_action_pressed();
|
_action_pressed();
|
||||||
}
|
}
|
||||||
|
@ -415,6 +476,13 @@ void FileDialog::update_file_list() {
|
||||||
bool is_hidden;
|
bool is_hidden;
|
||||||
String item;
|
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()) != "") {
|
while ((item = dir_access->get_next()) != "") {
|
||||||
if (item == "." || item == "..") {
|
if (item == "." || item == "..") {
|
||||||
continue;
|
continue;
|
||||||
|
@ -602,6 +670,7 @@ void FileDialog::set_current_dir(const String &p_dir) {
|
||||||
dir_access->change_dir(p_dir);
|
dir_access->change_dir(p_dir);
|
||||||
update_dir();
|
update_dir();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
_push_history();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::set_current_file(const String &p_file) {
|
void FileDialog::set_current_file(const String &p_file) {
|
||||||
|
@ -737,6 +806,7 @@ void FileDialog::_make_dir_confirm() {
|
||||||
invalidate();
|
invalidate();
|
||||||
update_filters();
|
update_filters();
|
||||||
update_dir();
|
update_dir();
|
||||||
|
_push_history();
|
||||||
} else {
|
} else {
|
||||||
mkdirerr->popup_centered(Size2(250, 50));
|
mkdirerr->popup_centered(Size2(250, 50));
|
||||||
}
|
}
|
||||||
|
@ -754,6 +824,7 @@ void FileDialog::_select_drive(int p_idx) {
|
||||||
file->set_text("");
|
file->set_text("");
|
||||||
invalidate();
|
invalidate();
|
||||||
update_dir();
|
update_dir();
|
||||||
|
_push_history();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::_update_drives() {
|
void FileDialog::_update_drives() {
|
||||||
|
@ -861,10 +932,20 @@ FileDialog::FileDialog() {
|
||||||
|
|
||||||
HBoxContainer *hbc = memnew(HBoxContainer);
|
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 = memnew(Button);
|
||||||
dir_up->set_flat(true);
|
dir_up->set_flat(true);
|
||||||
dir_up->set_tooltip(TTRC("Go to parent folder."));
|
dir_up->set_tooltip(TTRC("Go to parent folder."));
|
||||||
|
hbc->add_child(dir_prev);
|
||||||
|
hbc->add_child(dir_next);
|
||||||
hbc->add_child(dir_up);
|
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));
|
dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
|
||||||
|
|
||||||
hbc->add_child(memnew(Label(TTRC("Path:"))));
|
hbc->add_child(memnew(Label(TTRC("Path:"))));
|
||||||
|
@ -908,6 +989,13 @@ FileDialog::FileDialog() {
|
||||||
tree->set_hide_root(true);
|
tree->set_hide_root(true);
|
||||||
vbox->add_margin_child(TTRC("Directories & Files:"), tree, 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 = memnew(HBoxContainer);
|
||||||
file_box->add_child(memnew(Label(TTRC("File:"))));
|
file_box->add_child(memnew(Label(TTRC("File:"))));
|
||||||
file = memnew(LineEdit);
|
file = memnew(LineEdit);
|
||||||
|
|
|
@ -86,6 +86,10 @@ private:
|
||||||
DirAccess *dir_access;
|
DirAccess *dir_access;
|
||||||
ConfirmationDialog *confirm_save;
|
ConfirmationDialog *confirm_save;
|
||||||
|
|
||||||
|
Label *message;
|
||||||
|
|
||||||
|
Button *dir_prev;
|
||||||
|
Button *dir_next;
|
||||||
Button *dir_up;
|
Button *dir_up;
|
||||||
|
|
||||||
Button *refresh;
|
Button *refresh;
|
||||||
|
@ -93,6 +97,10 @@ private:
|
||||||
|
|
||||||
Vector<String> filters;
|
Vector<String> filters;
|
||||||
|
|
||||||
|
Vector<String> local_history;
|
||||||
|
int local_history_pos = 0;
|
||||||
|
void _push_history();
|
||||||
|
|
||||||
bool mode_overrides_title = true;
|
bool mode_overrides_title = true;
|
||||||
|
|
||||||
static bool default_show_hidden_files;
|
static bool default_show_hidden_files;
|
||||||
|
@ -119,6 +127,8 @@ private:
|
||||||
void _make_dir();
|
void _make_dir();
|
||||||
void _make_dir_confirm();
|
void _make_dir_confirm();
|
||||||
void _go_up();
|
void _go_up();
|
||||||
|
void _go_back();
|
||||||
|
void _go_forward();
|
||||||
|
|
||||||
void _update_drives();
|
void _update_drives();
|
||||||
|
|
||||||
|
|
|
@ -628,6 +628,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
// File Dialog
|
// File Dialog
|
||||||
|
|
||||||
theme->set_icon("parent_folder", "FileDialog", make_icon(icon_parent_folder_png));
|
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("reload", "FileDialog", make_icon(icon_reload_png));
|
||||||
theme->set_icon("toggle_hidden", "FileDialog", make_icon(icon_visibility_png));
|
theme->set_icon("toggle_hidden", "FileDialog", make_icon(icon_visibility_png));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue