diff --git a/core/core_constants.cpp b/core/core_constants.cpp index e353e8a22fd..112a76ffa75 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -680,6 +680,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ONESHOT); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GROUP_ENABLE); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INPUT_NAME); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FILE_PATH); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE); diff --git a/core/object/object.h b/core/object/object.h index 4d3d340ca1a..5e826be7c02 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -95,6 +95,7 @@ enum PropertyHint { PROPERTY_HINT_NO_NODEPATH, /// < this property will not contain a NodePath, regardless of type (Array, Dictionary, List, etc.). Needed for SceneTreeDock. PROPERTY_HINT_GROUP_ENABLE, ///< used to make the property's group checkable. Only use for boolean types. Optional "feature" hint string force hides anything inside when unchecked. PROPERTY_HINT_INPUT_NAME, + PROPERTY_HINT_FILE_PATH, PROPERTY_HINT_MAX, }; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 22b59e56a03..1991d877587 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2815,7 +2815,7 @@ Hints that an integer property is a bitmask using the optionally named avoidance layers. - Hints that a [String] property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. + Hints that a [String] property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. By default the file will be stored as UID whenever available. You can use [ResourceUID] methods to convert it back to path. For storing a raw path, use [constant PROPERTY_HINT_FILE_PATH]. Hints that a [String] property is a path to a directory. Editing it will show a file dialog for picking the path. @@ -2964,7 +2964,10 @@ - If it contains [code]"show_builtin"[/code], built-in input actions are included in the selection. - If it contains [code]"loose_mode"[/code], loose mode is enabled. This allows inserting any action name even if it's not present in the input map. - + + Like [constant PROPERTY_HINT_FILE], but the property is stored as a raw path, not UID. That means the reference will be broken if you move the file. Consider using [constant PROPERTY_HINT_FILE] when possible. + + Represents the size of the [enum PropertyHint] enum. diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 3c17cf00ba3..1960101cbaa 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -568,7 +568,7 @@ void EditorPropertyPath::_set_read_only(bool p_read_only) { void EditorPropertyPath::_path_selected(const String &p_path) { String full_path = p_path; - if (!global) { + if (enable_uid) { const ResourceUID::ID id = ResourceLoader::get_resource_uid(full_path); if (id != ResourceUID::INVALID_ID) { full_path = ResourceUID::get_singleton()->id_to_text(id); @@ -629,10 +629,11 @@ void EditorPropertyPath::update_property() { path->set_tooltip_text(full_path); } -void EditorPropertyPath::setup(const Vector &p_extensions, bool p_folder, bool p_global) { +void EditorPropertyPath::setup(const Vector &p_extensions, bool p_folder, bool p_global, bool p_enable_uid) { extensions = p_extensions; folder = p_folder; global = p_global; + enable_uid = p_enable_uid; } void EditorPropertyPath::set_save_mode() { @@ -3801,13 +3802,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyLocale *editor = memnew(EditorPropertyLocale); editor->setup(p_hint_text); return editor; - } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) { + } else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE || p_hint == PROPERTY_HINT_FILE_PATH) { Vector extensions = p_hint_text.split(","); bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE; bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR; bool save = p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_SAVE_FILE; + bool enable_uid = p_hint == PROPERTY_HINT_FILE; EditorPropertyPath *editor = memnew(EditorPropertyPath); - editor->setup(extensions, folder, global); + editor->setup(extensions, folder, global, enable_uid); if (save) { editor->set_save_mode(); } diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 08adb99e3b5..20e38dbc506 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -161,6 +161,7 @@ class EditorPropertyPath : public EditorProperty { bool folder = false; bool global = false; bool save_mode = false; + bool enable_uid = false; EditorFileDialog *dialog = nullptr; LineEdit *path = nullptr; Button *path_edit = nullptr; @@ -178,7 +179,7 @@ protected: void _notification(int p_what); public: - void setup(const Vector &p_extensions, bool p_folder, bool p_global); + void setup(const Vector &p_extensions, bool p_folder, bool p_global, bool p_enable_uid); void set_save_mode(); virtual void update_property() override; EditorPropertyPath(); diff --git a/editor/export/editor_export_platform_apple_embedded.cpp b/editor/export/editor_export_platform_apple_embedded.cpp index eab922e00db..3cef0355be4 100644 --- a/editor/export/editor_export_platform_apple_embedded.cpp +++ b/editor/export/editor_export_platform_apple_embedded.cpp @@ -351,9 +351,9 @@ void EditorExportPlatformAppleEmbedded::get_export_options(List *r } } - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_dark", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_tinted", PROPERTY_HINT_FILE, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_dark", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/icon_1024x1024_tinted", PROPERTY_HINT_FILE_PATH, "*.svg,*.png,*.webp,*.jpg,*.jpeg"), "")); HashSet used_names; @@ -361,9 +361,9 @@ void EditorExportPlatformAppleEmbedded::get_export_options(List *r for (int i = 0; i < icon_infos.size(); ++i) { if (!used_names.has(icon_infos[i].preset_key)) { used_names.insert(icon_infos[i].preset_key); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key), PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_dark", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_tinted", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key), PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_dark", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, String(icon_infos[i].preset_key) + "_tinted", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), "")); } } } diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 98240dc862d..57cd2939bc3 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -280,7 +280,7 @@ void ProjectExportDialog::_edit_preset(int p_index) { extension_vector.push_back("*." + extension); } - export_path->setup(extension_vector, false, true); + export_path->setup(extension_vector, false, true, false); export_path->update_property(); advanced_options->set_disabled(false); advanced_options->set_pressed(current->are_advanced_options_enabled()); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index de7fff1e4bc..2df20f1a8ea 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1635,7 +1635,7 @@ void FileSystemDock::_update_project_settings_after_move(const HashMap prop_info = ProjectSettings::get_singleton()->get_custom_property_info(); for (const KeyValue &E : prop_info) { - if (E.value.hint == PROPERTY_HINT_FILE) { + if (E.value.hint == PROPERTY_HINT_FILE_PATH) { String old_path = GLOBAL_GET(E.key); if (p_renames.has(old_path)) { ProjectSettings::get_singleton()->set_setting(E.key, p_renames[old_path]); diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp index 177f5cb8dd9..223c48a4373 100644 --- a/editor/gui/editor_file_dialog.cpp +++ b/editor/gui/editor_file_dialog.cpp @@ -2191,7 +2191,7 @@ void EditorFileDialog::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"), "set_display_mode", "get_display_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "file_mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"), "set_file_mode", "get_file_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE_PATH, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_path", "get_current_path"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters"); ADD_ARRAY_COUNT("Options", "option_count", "set_option_count", "get_option_count", "option_"); diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 54812d687a8..73cb4ebd167 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -435,6 +435,14 @@ @export_file("*.txt") var notes_path: String @export_file var level_paths: Array[String] [/codeblock] + [b]Note:[/b] The file will be stored and referenced as UID, if available. This ensures that the reference is valid even when the file is moved. You can use [ResourceUID] methods to convert it to path. + + + + + + + Same as [annotation @export_file], except the file will be stored as a raw path. This means that it may become invalid when the file is moved. If you are exporting a [Resource] path, consider using [annotation @export_file] instead. diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 1bdd1da42f2..6cc79abea0c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -102,6 +102,7 @@ GDScriptParser::GDScriptParser() { register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations); register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(), true); register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true); + register_annotation(MethodInfo("@export_file_path", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true); register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations); register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray(""), true); register_annotation(MethodInfo("@export_global_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations); diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index 01c8c296f9a..2ba36c56f56 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -47,8 +47,8 @@ void EditorExportPlatformIOS::get_export_options(List *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), get_minimum_deployment_target())); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale to Fit,Scale to Fill,Scale"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE_PATH, "*.png,*.jpg,*.jpeg"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_custom_bg_color"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "storyboard/custom_bg_color"), Color())); } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index c4b73733472..48c03d418d7 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1945,7 +1945,7 @@ void FileDialog::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "layout_toggle_enabled"), "set_customization_flag_enabled", "is_customization_flag_enabled", CUSTOMIZATION_LAYOUT); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE_PATH, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_path", "get_current_path"); ADD_SIGNAL(MethodInfo("file_selected", PropertyInfo(Variant::STRING, "path"))); diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index ea8034efbaa..4c93fe0383b 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -635,7 +635,7 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPRequest::set_http_proxy); ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPRequest::set_https_proxy); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE_PATH), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216,suffix:B"), "set_download_chunk_size", "get_download_chunk_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accept_gzip"), "set_accept_gzip", "is_accepting_gzip");