diff options
Diffstat (limited to 'scene/gui/file_dialog.cpp')
-rw-r--r-- | scene/gui/file_dialog.cpp | 268 |
1 files changed, 100 insertions, 168 deletions
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index a4f0338f00..41ca6458af 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -34,21 +34,20 @@ #include "core/print_string.h" #include "scene/gui/label.h" -FileDialog::GetIconFunc FileDialog::get_icon_func = NULL; -FileDialog::GetIconFunc FileDialog::get_large_icon_func = NULL; +FileDialog::GetIconFunc FileDialog::get_icon_func = nullptr; +FileDialog::GetIconFunc FileDialog::get_large_icon_func = nullptr; -FileDialog::RegisterFunc FileDialog::register_func = NULL; -FileDialog::RegisterFunc FileDialog::unregister_func = NULL; +FileDialog::RegisterFunc FileDialog::register_func = nullptr; +FileDialog::RegisterFunc FileDialog::unregister_func = nullptr; VBoxContainer *FileDialog::get_vbox() { return vbox; } void FileDialog::_theme_changed() { - - Color font_color = vbc->get_theme_color("font_color", "ToolButton"); - Color font_color_hover = vbc->get_theme_color("font_color_hover", "ToolButton"); - Color font_color_pressed = vbc->get_theme_color("font_color_pressed", "ToolButton"); + Color font_color = vbox->get_theme_color("font_color", "Button"); + Color font_color_hover = vbox->get_theme_color("font_color_hover", "Button"); + Color font_color_pressed = vbox->get_theme_color("font_color_pressed", "Button"); dir_up->add_theme_color_override("icon_color_normal", font_color); dir_up->add_theme_color_override("icon_color_hover", font_color_hover); @@ -64,35 +63,27 @@ void FileDialog::_theme_changed() { } void FileDialog::_notification(int p_what) { - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { if (!is_visible()) { - set_process_unhandled_input(false); } } if (p_what == NOTIFICATION_ENTER_TREE) { - - dir_up->set_icon(vbc->get_theme_icon("parent_folder")); - refresh->set_icon(vbc->get_theme_icon("reload")); - show_hidden->set_icon(vbc->get_theme_icon("toggle_hidden")); + dir_up->set_icon(vbox->get_theme_icon("parent_folder", "FileDialog")); + refresh->set_icon(vbox->get_theme_icon("reload", "FileDialog")); + show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog")); _theme_changed(); } } void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { - Ref<InputEventKey> k = p_event; if (k.is_valid() && has_focus()) { - if (k->is_pressed()) { - bool handled = true; switch (k->get_keycode()) { - case KEY_H: { - if (k->get_command()) { set_show_hidden_files(!show_hidden_files); } else { @@ -101,11 +92,9 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { } break; case KEY_F5: { - invalidate(); } break; case KEY_BACKSPACE: { - _dir_entered(".."); } break; default: { @@ -113,24 +102,22 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { } } - if (handled) + if (handled) { set_input_as_handled(); + } } } } void FileDialog::set_enable_multiple_selection(bool p_enable) { - tree->set_select_mode(p_enable ? Tree::SELECT_MULTI : Tree::SELECT_SINGLE); }; Vector<String> FileDialog::get_selected_files() const { - Vector<String> list; TreeItem *item = tree->get_root(); while ((item = tree->get_next_selected(item))) { - list.push_back(dir_access->get_current_dir().plus_file(item->get_text(0))); }; @@ -138,7 +125,6 @@ Vector<String> FileDialog::get_selected_files() const { }; void FileDialog::update_dir() { - dir->set_text(dir_access->get_current_dir(false)); if (drives->is_visible()) { @@ -150,7 +136,6 @@ void FileDialog::update_dir() { } void FileDialog::_dir_entered(String p_dir) { - dir_access->change_dir(p_dir); file->set_text(""); invalidate(); @@ -158,7 +143,6 @@ void FileDialog::_dir_entered(String p_dir) { } void FileDialog::_file_entered(const String &p_file) { - _action_pressed(); } @@ -169,16 +153,16 @@ void FileDialog::_save_confirm_pressed() { } void FileDialog::_post_popup() { - ConfirmationDialog::_post_popup(); if (invalidated) { update_file_list(); invalidated = false; } - if (mode == FILE_MODE_SAVE_FILE) + if (mode == FILE_MODE_SAVE_FILE) { file->grab_focus(); - else + } else { tree->grab_focus(); + } set_process_unhandled_input(true); @@ -192,15 +176,12 @@ void FileDialog::_post_popup() { } void FileDialog::_action_pressed() { - if (mode == FILE_MODE_OPEN_FILES) { - - TreeItem *ti = tree->get_next_selected(NULL); + TreeItem *ti = tree->get_next_selected(nullptr); String fbase = dir_access->get_current_dir(); Vector<String> files; while (ti) { - files.push_back(fbase.plus_file(ti->get_text(0))); ti = tree->get_next_selected(ti); } @@ -219,7 +200,6 @@ void FileDialog::_action_pressed() { emit_signal("file_selected", f); hide(); } else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) { - String path = dir_access->get_current_dir(); path = path.replace("\\", "/"); @@ -236,7 +216,6 @@ void FileDialog::_action_pressed() { } if (mode == FILE_MODE_SAVE_FILE) { - bool valid = false; if (filter->get_selected() == filter->get_item_count() - 1) { @@ -244,29 +223,27 @@ void FileDialog::_action_pressed() { } else if (filters.size() > 1 && filter->get_selected() == 0) { // match all filters for (int i = 0; i < filters.size(); i++) { - String flt = filters[i].get_slice(";", 0); for (int j = 0; j < flt.get_slice_count(","); j++) { - String str = flt.get_slice(",", j).strip_edges(); if (f.match(str)) { valid = true; break; } } - if (valid) + if (valid) { break; + } } } else { int idx = filter->get_selected(); - if (filters.size() > 1) + if (filters.size() > 1) { idx--; + } if (idx >= 0 && idx < filters.size()) { - String flt = filters[idx].get_slice(";", 0); int filterSliceCount = flt.get_slice_count(","); for (int j = 0; j < filterSliceCount; j++) { - String str = (flt.get_slice(",", j).strip_edges()); if (f.match(str)) { valid = true; @@ -286,7 +263,6 @@ void FileDialog::_action_pressed() { } if (!valid) { - exterr->popup_centered(Size2(250, 80)); return; } @@ -295,7 +271,6 @@ void FileDialog::_action_pressed() { confirm_save->set_text(RTR("File Exists, Overwrite?")); confirm_save->popup_centered(Size2(200, 80)); } else { - emit_signal("file_selected", f); hide(); } @@ -303,27 +278,28 @@ void FileDialog::_action_pressed() { } void FileDialog::_cancel_pressed() { - file->set_text(""); invalidate(); hide(); } bool FileDialog::_is_open_should_be_disabled() { - - if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE) + if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE) { return false; + } TreeItem *ti = tree->get_next_selected(tree->get_root()); while (ti) { TreeItem *prev_ti = ti; ti = tree->get_next_selected(tree->get_root()); - if (ti == prev_ti) + if (ti == prev_ti) { break; + } } // We have something that we can't select? - if (!ti) + if (!ti) { return mode != FILE_MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder. + } Dictionary d = ti->get_metadata(0); @@ -333,14 +309,12 @@ bool FileDialog::_is_open_should_be_disabled() { } void FileDialog::_go_up() { - dir_access->change_dir(".."); update_file_list(); update_dir(); } void FileDialog::deselect_items() { - // Clear currently selected items in file manager. tree->deselect_all(); @@ -349,7 +323,6 @@ void FileDialog::deselect_items() { get_ok()->set_disabled(_is_open_should_be_disabled()); switch (mode) { - case FILE_MODE_OPEN_FILE: case FILE_MODE_OPEN_FILES: get_ok()->set_text(RTR("Open")); @@ -370,14 +343,13 @@ void FileDialog::_tree_multi_selected(Object *p_object, int p_cell, bool p_selec } void FileDialog::_tree_selected() { - TreeItem *ti = tree->get_selected(); - if (!ti) + if (!ti) { return; + } Dictionary d = ti->get_metadata(0); if (!d["dir"]) { - file->set_text(d["name"]); } else if (mode == FILE_MODE_OPEN_DIR) { get_ok()->set_text(RTR("Select This Folder")); @@ -387,22 +359,21 @@ void FileDialog::_tree_selected() { } void FileDialog::_tree_item_activated() { - TreeItem *ti = tree->get_selected(); - if (!ti) + if (!ti) { return; + } Dictionary d = ti->get_metadata(0); if (d["dir"]) { - dir_access->change_dir(d["name"]); - if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY) + if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY) { file->set_text(""); + } call_deferred("_update_file_list"); call_deferred("_update_dir"); } else { - _action_pressed(); } } @@ -410,7 +381,9 @@ void FileDialog::_tree_item_activated() { void FileDialog::update_file_name() { int idx = filter->get_selected() - 1; if ((idx == -1 && filter->get_item_count() == 2) || (filter->get_item_count() > 2 && idx >= 0 && idx < filter->get_item_count() - 2)) { - if (idx == -1) idx += 1; + if (idx == -1) { + idx += 1; + } String filter_str = filters[idx]; String file_str = file->get_text(); String base_name = file_str.get_basename(); @@ -420,7 +393,6 @@ void FileDialog::update_file_name() { } void FileDialog::update_file_list() { - tree->clear(); // Scroll back to the top after opening a directory @@ -429,8 +401,10 @@ void FileDialog::update_file_list() { dir_access->list_dir_begin(); TreeItem *root = tree->create_item(); - Ref<Texture2D> folder = vbc->get_theme_icon("folder"); - const Color folder_color = vbc->get_theme_color("folder_icon_modulate"); + Ref<Texture2D> folder = vbox->get_theme_icon("folder", "FileDialog"); + Ref<Texture2D> file_icon = vbox->get_theme_icon("file", "FileDialog"); + const Color folder_color = vbox->get_theme_color("folder_icon_modulate", "FileDialog"); + const Color file_color = vbox->get_theme_color("file_icon_modulate", "FileDialog"); List<String> files; List<String> dirs; @@ -438,17 +412,18 @@ void FileDialog::update_file_list() { String item; while ((item = dir_access->get_next()) != "") { - - if (item == "." || item == "..") + if (item == "." || item == "..") { continue; + } is_hidden = dir_access->current_is_hidden(); if (show_hidden_files || !is_hidden) { - if (!dir_access->current_is_dir()) + if (!dir_access->current_is_dir()) { files.push_back(item); - else + } else { dirs.push_back(item); + } } } @@ -474,28 +449,24 @@ void FileDialog::update_file_list() { List<String> patterns; // build filter if (filter->get_selected() == filter->get_item_count() - 1) { - // match all } else if (filters.size() > 1 && filter->get_selected() == 0) { // match all filters for (int i = 0; i < filters.size(); i++) { - String f = filters[i].get_slice(";", 0); for (int j = 0; j < f.get_slice_count(","); j++) { - patterns.push_back(f.get_slice(",", j).strip_edges()); } } } else { int idx = filter->get_selected(); - if (filters.size() > 1) + if (filters.size() > 1) { idx--; + } if (idx >= 0 && idx < filters.size()) { - String f = filters[idx].get_slice(";", 0); for (int j = 0; j < f.get_slice_count(","); j++) { - patterns.push_back(f.get_slice(",", j).strip_edges()); } } @@ -504,12 +475,10 @@ void FileDialog::update_file_list() { String base_dir = dir_access->get_current_dir(); while (!files.empty()) { - bool match = patterns.empty(); String match_str; for (List<String>::Element *E = patterns.front(); E; E = E->next()) { - if (files.front()->get().matchn(E->get())) { match_str = E->get(); match = true; @@ -522,13 +491,15 @@ void FileDialog::update_file_list() { ti->set_text(0, files.front()->get()); if (get_icon_func) { - Ref<Texture2D> icon = get_icon_func(base_dir.plus_file(files.front()->get())); ti->set_icon(0, icon); + } else { + ti->set_icon(0, file_icon); } + ti->set_icon_modulate(0, file_color); if (mode == FILE_MODE_OPEN_DIR) { - ti->set_custom_color(0, vbc->get_theme_color("files_disabled")); + ti->set_custom_color(0, vbox->get_theme_color("files_disabled", "FileDialog")); ti->set_selectable(0, false); } Dictionary d; @@ -536,25 +507,25 @@ void FileDialog::update_file_list() { d["dir"] = false; ti->set_metadata(0, d); - if (file->get_text() == files.front()->get() || match_str == files.front()->get()) + if (file->get_text() == files.front()->get() || match_str == files.front()->get()) { ti->select(0); + } } files.pop_front(); } - if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == NULL) + if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr) { tree->get_root()->get_children()->select(0); + } } void FileDialog::_filter_selected(int) { - update_file_name(); update_file_list(); } void FileDialog::update_filters() { - filter->clear(); if (filters.size() > 1) { @@ -564,37 +535,38 @@ void FileDialog::update_filters() { for (int i = 0; i < MIN(max_filters, filters.size()); i++) { String flt = filters[i].get_slice(";", 0).strip_edges(); - if (i > 0) + if (i > 0) { all_filters += ", "; + } all_filters += flt; } - if (max_filters < filters.size()) + if (max_filters < filters.size()) { all_filters += ", ..."; + } filter->add_item(RTR("All Recognized") + " (" + all_filters + ")"); } for (int i = 0; i < filters.size(); i++) { - String flt = filters[i].get_slice(";", 0).strip_edges(); String desc = filters[i].get_slice(";", 1).strip_edges(); - if (desc.length()) + if (desc.length()) { filter->add_item(String(tr(desc)) + " (" + flt + ")"); - else + } else { filter->add_item("(" + flt + ")"); + } } filter->add_item(RTR("All Files (*)")); } void FileDialog::clear_filters() { - filters.clear(); update_filters(); invalidate(); } -void FileDialog::add_filter(const String &p_filter) { +void FileDialog::add_filter(const String &p_filter) { filters.push_back(p_filter); update_filters(); invalidate(); @@ -611,45 +583,44 @@ Vector<String> FileDialog::get_filters() const { } String FileDialog::get_current_dir() const { - return dir->get_text(); } -String FileDialog::get_current_file() const { +String FileDialog::get_current_file() const { return file->get_text(); } -String FileDialog::get_current_path() const { +String FileDialog::get_current_path() const { return dir->get_text().plus_file(file->get_text()); } -void FileDialog::set_current_dir(const String &p_dir) { +void FileDialog::set_current_dir(const String &p_dir) { dir_access->change_dir(p_dir); update_dir(); invalidate(); } -void FileDialog::set_current_file(const String &p_file) { +void FileDialog::set_current_file(const String &p_file) { file->set_text(p_file); update_dir(); invalidate(); int lp = p_file.find_last("."); if (lp != -1) { file->select(0, lp); - if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) + if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) { file->grab_focus(); + } } } -void FileDialog::set_current_path(const String &p_path) { - if (!p_path.size()) +void FileDialog::set_current_path(const String &p_path) { + if (!p_path.size()) { return; + } int pos = MAX(p_path.find_last("/"), p_path.find_last("\\")); if (pos == -1) { - set_current_file(p_path); } else { - String dir = p_path.substr(0, pos); String file = p_path.substr(pos + 1, p_path.length()); set_current_dir(dir); @@ -666,40 +637,43 @@ bool FileDialog::is_mode_overriding_title() const { } void FileDialog::set_file_mode(FileMode p_mode) { - ERR_FAIL_INDEX((int)p_mode, 5); mode = p_mode; switch (mode) { - case FILE_MODE_OPEN_FILE: get_ok()->set_text(RTR("Open")); - if (mode_overrides_title) + if (mode_overrides_title) { set_title(RTR("Open a File")); + } makedir->hide(); break; case FILE_MODE_OPEN_FILES: get_ok()->set_text(RTR("Open")); - if (mode_overrides_title) + if (mode_overrides_title) { set_title(RTR("Open File(s)")); + } makedir->hide(); break; case FILE_MODE_OPEN_DIR: get_ok()->set_text(RTR("Select Current Folder")); - if (mode_overrides_title) + if (mode_overrides_title) { set_title(RTR("Open a Directory")); + } makedir->show(); break; case FILE_MODE_OPEN_ANY: get_ok()->set_text(RTR("Open")); - if (mode_overrides_title) + if (mode_overrides_title) { set_title(RTR("Open a File or Directory")); + } makedir->show(); break; case FILE_MODE_SAVE_FILE: get_ok()->set_text(RTR("Save")); - if (mode_overrides_title) + if (mode_overrides_title) { set_title(RTR("Save a File")); + } makedir->show(); break; } @@ -712,27 +686,23 @@ void FileDialog::set_file_mode(FileMode p_mode) { } FileDialog::FileMode FileDialog::get_file_mode() const { - return mode; } void FileDialog::set_access(Access p_access) { - ERR_FAIL_INDEX(p_access, 3); - if (access == p_access) + if (access == p_access) { return; + } memdelete(dir_access); switch (p_access) { case ACCESS_FILESYSTEM: { - dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); } break; case ACCESS_RESOURCES: { - dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); } break; case ACCESS_USERDATA: { - dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA); } break; } @@ -744,7 +714,6 @@ void FileDialog::set_access(Access p_access) { } void FileDialog::invalidate() { - if (is_visible()) { update_file_list(); invalidated = false; @@ -754,12 +723,10 @@ void FileDialog::invalidate() { } FileDialog::Access FileDialog::get_access() const { - return access; } void FileDialog::_make_dir_confirm() { - Error err = dir_access->make_dir(makedirname->get_text()); if (err == OK) { dir_access->change_dir(makedirname->get_text()); @@ -773,13 +740,11 @@ void FileDialog::_make_dir_confirm() { } void FileDialog::_make_dir() { - makedialog->popup_centered(Size2(250, 80)); makedirname->grab_focus(); } void FileDialog::_select_drive(int p_idx) { - String d = drives->get_item_text(p_idx); dir_access->change_dir(d); file->set_text(""); @@ -788,7 +753,6 @@ void FileDialog::_select_drive(int p_idx) { } void FileDialog::_update_drives() { - int dc = dir_access->get_drive_count(); if (dc == 0 || access != ACCESS_FILESYSTEM) { drives->hide(); @@ -813,7 +777,6 @@ void FileDialog::_update_drives() { bool FileDialog::default_show_hidden_files = false; void FileDialog::_bind_methods() { - ClassDB::bind_method(D_METHOD("_unhandled_input"), &FileDialog::_unhandled_input); ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed); @@ -883,21 +846,21 @@ void FileDialog::set_default_show_hidden_files(bool p_show) { } FileDialog::FileDialog() { - show_hidden_files = default_show_hidden_files; mode_overrides_title = true; - vbc = memnew(VBoxContainer); - add_child(vbc); - vbc->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); + vbox = memnew(VBoxContainer); + add_child(vbox); + vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); mode = FILE_MODE_SAVE_FILE; set_title(RTR("Save a File")); HBoxContainer *hbc = memnew(HBoxContainer); - dir_up = memnew(ToolButton); + dir_up = memnew(Button); + dir_up->set_flat(true); dir_up->set_tooltip(RTR("Go to parent folder.")); hbc->add_child(dir_up); dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up)); @@ -909,17 +872,20 @@ FileDialog::FileDialog() { drives = memnew(OptionButton); drives->connect("item_selected", callable_mp(this, &FileDialog::_select_drive)); + hbc->add_child(drives); dir = memnew(LineEdit); hbc->add_child(dir); dir->set_h_size_flags(Control::SIZE_EXPAND_FILL); - refresh = memnew(ToolButton); + refresh = memnew(Button); + refresh->set_flat(true); refresh->set_tooltip(RTR("Refresh files.")); refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list)); hbc->add_child(refresh); - show_hidden = memnew(ToolButton); + show_hidden = memnew(Button); + show_hidden->set_flat(true); show_hidden->set_toggle_mode(true); show_hidden->set_pressed(is_showing_hidden_files()); show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files.")); @@ -933,11 +899,11 @@ FileDialog::FileDialog() { makedir->set_text(RTR("Create Folder")); makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir)); hbc->add_child(makedir); - vbc->add_child(hbc); + vbox->add_child(hbc); tree = memnew(Tree); tree->set_hide_root(true); - vbc->add_margin_child(RTR("Directories & Files:"), tree, true); + vbox->add_margin_child(RTR("Directories & Files:"), tree, true); file_box = memnew(HBoxContainer); file_box->add_child(memnew(Label(RTR("File:")))); @@ -950,7 +916,7 @@ FileDialog::FileDialog() { filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); filter->set_clip_text(true); // too many extensions overflows it file_box->add_child(filter); - vbc->add_child(file_box); + vbox->add_child(file_box); dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); access = ACCESS_RESOURCES; @@ -993,50 +959,16 @@ FileDialog::FileDialog() { update_dir(); set_hide_on_ok(false); - vbox = vbc; invalidated = true; - if (register_func) + if (register_func) { register_func(this); + } } FileDialog::~FileDialog() { - - if (unregister_func) + if (unregister_func) { unregister_func(this); + } memdelete(dir_access); } - -void LineEditFileChooser::_bind_methods() { - - ClassDB::bind_method(D_METHOD("get_button"), &LineEditFileChooser::get_button); - ClassDB::bind_method(D_METHOD("get_line_edit"), &LineEditFileChooser::get_line_edit); - ClassDB::bind_method(D_METHOD("get_file_dialog"), &LineEditFileChooser::get_file_dialog); -} - -void LineEditFileChooser::_chosen(const String &p_text) { - - line_edit->set_text(p_text); - line_edit->emit_signal("text_entered", p_text); -} - -void LineEditFileChooser::_browse() { - - dialog->popup_centered_ratio(); -} - -LineEditFileChooser::LineEditFileChooser() { - - line_edit = memnew(LineEdit); - add_child(line_edit); - line_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); - button = memnew(Button); - button->set_text(" .. "); - add_child(button); - button->connect("pressed", callable_mp(this, &LineEditFileChooser::_browse)); - dialog = memnew(FileDialog); - add_child(dialog); - dialog->connect("file_selected", callable_mp(this, &LineEditFileChooser::_chosen)); - dialog->connect("dir_selected", callable_mp(this, &LineEditFileChooser::_chosen)); - dialog->connect("files_selected", callable_mp(this, &LineEditFileChooser::_chosen)); -} |