diff options
Diffstat (limited to 'scene/gui/file_dialog.cpp')
-rw-r--r-- | scene/gui/file_dialog.cpp | 208 |
1 files changed, 99 insertions, 109 deletions
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 1163c0e390..c3a586a1ee 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -59,6 +59,17 @@ void FileDialog::_focus_file_text() { } } +void FileDialog::_native_popup() { + // Show native dialog directly. + String root; + if (access == ACCESS_RESOURCES) { + root = ProjectSettings::get_singleton()->get_resource_path(); + } else if (access == ACCESS_USERDATA) { + root = OS::get_singleton()->get_user_data_dir(); + } + DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb)); +} + void FileDialog::popup(const Rect2i &p_rect) { _update_option_controls(); @@ -69,20 +80,16 @@ void FileDialog::popup(const Rect2i &p_rect) { #endif if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { - String root; - if (access == ACCESS_RESOURCES) { - root = ProjectSettings::get_singleton()->get_resource_path(); - } else if (access == ACCESS_USERDATA) { - root = OS::get_singleton()->get_user_data_dir(); - } - DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb)); + _native_popup(); } else { ConfirmationDialog::popup(p_rect); } } void FileDialog::set_visible(bool p_visible) { - _update_option_controls(); + if (p_visible) { + _update_option_controls(); + } #ifdef TOOLS_ENABLED if (is_part_of_edited_scene()) { @@ -92,67 +99,62 @@ void FileDialog::set_visible(bool p_visible) { #endif if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { - if (p_visible) { - String root; - if (access == ACCESS_RESOURCES) { - root = ProjectSettings::get_singleton()->get_resource_path(); - } else if (access == ACCESS_USERDATA) { - root = OS::get_singleton()->get_user_data_dir(); - } - DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb)); - } + _native_popup(); } else { ConfirmationDialog::set_visible(p_visible); } } void FileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_files, int p_filter, const Dictionary &p_selected_options) { - if (p_ok) { - if (p_files.size() > 0) { - Vector<String> files = p_files; - if (access != ACCESS_FILESYSTEM) { - for (String &file_name : files) { - file_name = ProjectSettings::get_singleton()->localize_path(file_name); - } - } - String f = files[0]; - if (mode == FILE_MODE_OPEN_FILES) { - emit_signal(SNAME("files_selected"), files); - } else { - if (mode == FILE_MODE_SAVE_FILE) { - if (p_filter >= 0 && p_filter < filters.size()) { - bool valid = false; - String flt = filters[p_filter].get_slice(";", 0); - int filter_slice_count = flt.get_slice_count(","); - for (int j = 0; j < filter_slice_count; j++) { - String str = (flt.get_slice(",", j).strip_edges()); - if (f.match(str)) { - valid = true; - break; - } - } - - if (!valid && filter_slice_count > 0) { - String str = (flt.get_slice(",", 0).strip_edges()); - f += str.substr(1, str.length() - 1); - } + if (!p_ok) { + file->set_text(""); + emit_signal(SNAME("canceled")); + return; + } + + if (p_files.is_empty()) { + return; + } + + Vector<String> files = p_files; + if (access != ACCESS_FILESYSTEM) { + for (String &file_name : files) { + file_name = ProjectSettings::get_singleton()->localize_path(file_name); + } + } + String f = files[0]; + if (mode == FILE_MODE_OPEN_FILES) { + emit_signal(SNAME("files_selected"), files); + } else { + if (mode == FILE_MODE_SAVE_FILE) { + if (p_filter >= 0 && p_filter < filters.size()) { + bool valid = false; + String flt = filters[p_filter].get_slice(";", 0); + int filter_slice_count = flt.get_slice_count(","); + for (int j = 0; j < filter_slice_count; j++) { + String str = (flt.get_slice(",", j).strip_edges()); + if (f.match(str)) { + valid = true; + break; } - emit_signal(SNAME("file_selected"), f); - } else if ((mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_FILE) && dir_access->file_exists(f)) { - emit_signal(SNAME("file_selected"), f); - } else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) { - emit_signal(SNAME("dir_selected"), f); + } + + if (!valid && filter_slice_count > 0) { + String str = (flt.get_slice(",", 0).strip_edges()); + f += str.substr(1, str.length() - 1); } } - file->set_text(f); - dir->set_text(f.get_base_dir()); - selected_options = p_selected_options; - filter->select(p_filter); + emit_signal(SNAME("file_selected"), f); + } else if ((mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_FILE) && dir_access->file_exists(f)) { + emit_signal(SNAME("file_selected"), f); + } else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) { + emit_signal(SNAME("dir_selected"), f); } - } else { - file->set_text(""); - emit_signal(SNAME("canceled")); } + file->set_text(f); + dir->set_text(f.get_base_dir()); + selected_options = p_selected_options; + filter->select(p_filter); } VBoxContainer *FileDialog::get_vbox() { @@ -168,6 +170,20 @@ void FileDialog::_validate_property(PropertyInfo &p_property) const { void FileDialog::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: { +#ifdef TOOLS_ENABLED + if (is_part_of_edited_scene()) { + return; + } +#endif + + // Replace the built-in dialog with the native one if it started visible. + if (is_visible() && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { + ConfirmationDialog::set_visible(false); + _native_popup(); + } + } break; + case NOTIFICATION_VISIBILITY_CHANGED: { if (!is_visible()) { set_process_shortcut_input(false); @@ -1110,7 +1126,7 @@ void FileDialog::_update_option_controls() { } options_dirty = false; - while (grid_options->get_child_count(false) > 0) { + while (grid_options->get_child_count() > 0) { Node *child = grid_options->get_child(0); grid_options->remove_child(child); child->queue_free(); @@ -1222,9 +1238,8 @@ void FileDialog::add_option(const String &p_name, const Vector<String> &p_values void FileDialog::set_option_count(int p_count) { ERR_FAIL_COND(p_count < 0); - int prev_size = options.size(); - if (prev_size == p_count) { + if (options.size() == p_count) { return; } options.resize(p_count); @@ -1240,52 +1255,6 @@ int FileDialog::get_option_count() const { return options.size(); } -bool FileDialog::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("option_") && components[0].trim_prefix("option_").is_valid_int()) { - int item_index = components[0].trim_prefix("option_").to_int(); - String property = components[1]; - if (property == "name") { - set_option_name(item_index, p_value); - return true; - } else if (property == "values") { - set_option_values(item_index, p_value); - return true; - } else if (property == "default") { - set_option_default(item_index, p_value); - return true; - } - } - return false; -} - -bool FileDialog::_get(const StringName &p_name, Variant &r_ret) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("option_") && components[0].trim_prefix("option_").is_valid_int()) { - int item_index = components[0].trim_prefix("option_").to_int(); - String property = components[1]; - if (property == "name") { - r_ret = get_option_name(item_index); - return true; - } else if (property == "values") { - r_ret = get_option_values(item_index); - return true; - } else if (property == "default") { - r_ret = get_option_default(item_index); - return true; - } - } - return false; -} - -void FileDialog::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < options.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("option_%d/name", i))); - p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, vformat("option_%d/values", i))); - p_list->push_back(PropertyInfo(Variant::INT, vformat("option_%d/default", i))); - } -} - void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed); @@ -1298,10 +1267,10 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("get_option_default", "option"), &FileDialog::get_option_default); ClassDB::bind_method(D_METHOD("set_option_name", "option", "name"), &FileDialog::set_option_name); ClassDB::bind_method(D_METHOD("set_option_values", "option", "values"), &FileDialog::set_option_values); - ClassDB::bind_method(D_METHOD("set_option_default", "option", "index"), &FileDialog::set_option_default); + ClassDB::bind_method(D_METHOD("set_option_default", "option", "default_value_index"), &FileDialog::set_option_default); ClassDB::bind_method(D_METHOD("set_option_count", "count"), &FileDialog::set_option_count); ClassDB::bind_method(D_METHOD("get_option_count"), &FileDialog::get_option_count); - ClassDB::bind_method(D_METHOD("add_option", "name", "values", "index"), &FileDialog::add_option); + ClassDB::bind_method(D_METHOD("add_option", "name", "values", "default_value_index"), &FileDialog::add_option); ClassDB::bind_method(D_METHOD("get_selected_options"), &FileDialog::get_selected_options); ClassDB::bind_method(D_METHOD("get_current_dir"), &FileDialog::get_current_dir); ClassDB::bind_method(D_METHOD("get_current_file"), &FileDialog::get_current_file); @@ -1371,6 +1340,13 @@ void FileDialog::_bind_methods() { BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_hover_color, "font_hover_color", "Button"); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_focus_color, "font_focus_color", "Button"); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_pressed_color, "font_pressed_color", "Button"); + + Option defaults; + + base_property_helper.set_prefix("option_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults.name, &FileDialog::set_option_name, &FileDialog::get_option_name); + base_property_helper.register_property(PropertyInfo(Variant::PACKED_STRING_ARRAY, "values"), defaults.values, &FileDialog::set_option_values, &FileDialog::get_option_values); + base_property_helper.register_property(PropertyInfo(Variant::INT, "default"), defaults.default_idx, &FileDialog::set_option_default, &FileDialog::get_option_default); } void FileDialog::set_show_hidden_files(bool p_show) { @@ -1391,6 +1367,18 @@ void FileDialog::set_default_show_hidden_files(bool p_show) { void FileDialog::set_use_native_dialog(bool p_native) { use_native_dialog = p_native; + +#ifdef TOOLS_ENABLED + if (is_part_of_edited_scene()) { + return; + } +#endif + + // Replace the built-in dialog with the native one if it's currently visible. + if (is_visible() && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { + ConfirmationDialog::set_visible(false); + _native_popup(); + } } bool FileDialog::get_use_native_dialog() const { @@ -1536,6 +1524,8 @@ FileDialog::FileDialog() { if (register_func) { register_func(this); } + + property_helper.setup_for_instance(base_property_helper, this); } FileDialog::~FileDialog() { |