Make EditorFileDialog inherit FileDialog

This commit is contained in:
kobewi 2025-12-02 12:30:51 +01:00
parent f5918a9d35
commit c1cc178a82
23 changed files with 253 additions and 3285 deletions

View file

@ -1,36 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorFileDialog" inherits="ConfirmationDialog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <class name="EditorFileDialog" inherits="FileDialog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description> <brief_description>
A modified version of [FileDialog] used by the editor. A modified version of [FileDialog] used by the editor.
</brief_description> </brief_description>
<description> <description>
[EditorFileDialog] is an enhanced version of [FileDialog] available only to editor plugins. Additional features include list of favorited/recent files and the ability to see files as thumbnails grid instead of list. [EditorFileDialog] is a [FileDialog] tweaked to work in the editor. It automatically handles favorite and recent directory lists, and synchronizes some properties with their corresponding editor settings.
Unlike [FileDialog], [EditorFileDialog] does not have a property for using native dialogs. Instead, native dialogs can be enabled globally via the [member EditorSettings.interface/editor/use_native_file_dialogs] editor setting. They are also enabled automatically when running in sandbox (e.g. on macOS). [EditorFileDialog] will automatically show a native dialog based on the [member EditorSettings.interface/editor/use_native_file_dialogs] editor setting and ignores [member FileDialog.use_native_dialog].
[b]Note:[/b] [EditorFileDialog] is invisible by default. To make it visible, call one of the [code]popup_*[/code] methods from [Window] on the node, such as [method Window.popup_centered_clamped]. [b]Note:[/b] [EditorFileDialog] is invisible by default. To make it visible, call one of the [code]popup_*[/code] methods from [Window] on the node, such as [method Window.popup_centered_clamped].
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<methods> <methods>
<method name="add_filter">
<return type="void" />
<param index="0" name="filter" type="String" />
<param index="1" name="description" type="String" default="&quot;&quot;" />
<description>
Adds a comma-separated file name [param filter] option to the [EditorFileDialog] with an optional [param description], which restricts what files can be picked.
A [param filter] should be of the form [code]"filename.extension"[/code], where filename and extension can be [code]*[/code] to match any string. Filters starting with [code].[/code] (i.e. empty filenames) are not allowed.
For example, a [param filter] of [code]"*.tscn, *.scn"[/code] and a [param description] of [code]"Scenes"[/code] results in filter text "Scenes (*.tscn, *.scn)".
</description>
</method>
<method name="add_option">
<return type="void" />
<param index="0" name="name" type="String" />
<param index="1" name="values" type="PackedStringArray" />
<param index="2" name="default_value_index" type="int" />
<description>
Adds an additional [OptionButton] to the file dialog. If [param values] is empty, a [CheckBox] is added instead.
[param default_value_index] should be an index of the value in the [param values]. If [param values] is empty it should be either [code]1[/code] (checked), or [code]0[/code] (unchecked).
</description>
</method>
<method name="add_side_menu" deprecated="This feature is no longer supported."> <method name="add_side_menu" deprecated="This feature is no longer supported.">
<return type="void" /> <return type="void" />
<param index="0" name="menu" type="Control" /> <param index="0" name="menu" type="Control" />
@ -39,199 +19,10 @@
This method is kept for compatibility and does nothing. As an alternative, you can display another dialog after showing the file dialog. This method is kept for compatibility and does nothing. As an alternative, you can display another dialog after showing the file dialog.
</description> </description>
</method> </method>
<method name="clear_filename_filter">
<return type="void" />
<description>
Clear the filter for file names.
</description>
</method>
<method name="clear_filters">
<return type="void" />
<description>
Removes all filters except for "All Files (*.*)".
</description>
</method>
<method name="get_filename_filter" qualifiers="const">
<return type="String" />
<description>
Returns the value of the filter for file names.
</description>
</method>
<method name="get_line_edit">
<return type="LineEdit" />
<description>
Returns the LineEdit for the selected file.
[b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member CanvasItem.visible] property.
</description>
</method>
<method name="get_option_default" qualifiers="const">
<return type="int" />
<param index="0" name="option" type="int" />
<description>
Returns the default value index of the [OptionButton] or [CheckBox] with index [param option].
</description>
</method>
<method name="get_option_name" qualifiers="const">
<return type="String" />
<param index="0" name="option" type="int" />
<description>
Returns the name of the [OptionButton] or [CheckBox] with index [param option].
</description>
</method>
<method name="get_option_values" qualifiers="const">
<return type="PackedStringArray" />
<param index="0" name="option" type="int" />
<description>
Returns an array of values of the [OptionButton] with index [param option].
</description>
</method>
<method name="get_selected_options" qualifiers="const">
<return type="Dictionary" />
<description>
Returns a [Dictionary] with the selected values of the additional [OptionButton]s and/or [CheckBox]es. [Dictionary] keys are names and values are selected value indices.
</description>
</method>
<method name="get_vbox">
<return type="VBoxContainer" />
<description>
Returns the [VBoxContainer] used to display the file system.
[b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member CanvasItem.visible] property.
</description>
</method>
<method name="invalidate">
<return type="void" />
<description>
Notify the [EditorFileDialog] that its view of the data is no longer accurate. Updates the view contents on next view update.
</description>
</method>
<method name="popup_file_dialog">
<return type="void" />
<description>
Shows the [EditorFileDialog] at the default size and position for file dialogs in the editor, and selects the file name if there is a current file.
</description>
</method>
<method name="set_filename_filter">
<return type="void" />
<param index="0" name="filter" type="String" />
<description>
Sets the value of the filter for file names.
</description>
</method>
<method name="set_option_default">
<return type="void" />
<param index="0" name="option" type="int" />
<param index="1" name="default_value_index" type="int" />
<description>
Sets the default value index of the [OptionButton] or [CheckBox] with index [param option].
</description>
</method>
<method name="set_option_name">
<return type="void" />
<param index="0" name="option" type="int" />
<param index="1" name="name" type="String" />
<description>
Sets the name of the [OptionButton] or [CheckBox] with index [param option].
</description>
</method>
<method name="set_option_values">
<return type="void" />
<param index="0" name="option" type="int" />
<param index="1" name="values" type="PackedStringArray" />
<description>
Sets the option values of the [OptionButton] with index [param option].
</description>
</method>
</methods> </methods>
<members> <members>
<member name="access" type="int" setter="set_access" getter="get_access" enum="EditorFileDialog.Access" default="0"> <member name="disable_overwrite_warning" type="bool" setter="set_disable_overwrite_warning" getter="is_overwrite_warning_disabled" default="false" deprecated="Use [member FileDialog.overwrite_warning_enabled] instead.">
The location from which the user may select a file, including [code]res://[/code], [code]user://[/code], and the local file system.
</member>
<member name="current_dir" type="String" setter="set_current_dir" getter="get_current_dir">
The currently occupied directory.
</member>
<member name="current_file" type="String" setter="set_current_file" getter="get_current_file">
The currently selected file.
</member>
<member name="current_path" type="String" setter="set_current_path" getter="get_current_path">
The file system path in the address bar.
</member>
<member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
<member name="disable_overwrite_warning" type="bool" setter="set_disable_overwrite_warning" getter="is_overwrite_warning_disabled" default="false">
If [code]true[/code], the [EditorFileDialog] will not warn the user before overwriting files. If [code]true[/code], the [EditorFileDialog] will not warn the user before overwriting files.
</member> </member>
<member name="display_mode" type="int" setter="set_display_mode" getter="get_display_mode" enum="EditorFileDialog.DisplayMode" default="0">
The view format in which the [EditorFileDialog] displays resources to the user.
</member>
<member name="file_mode" type="int" setter="set_file_mode" getter="get_file_mode" enum="EditorFileDialog.FileMode" default="4">
The dialog's open or save mode, which affects the selection behavior.
</member>
<member name="filters" type="PackedStringArray" setter="set_filters" getter="get_filters" default="PackedStringArray()">
The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. Multiple file types can also be specified in a single filter. [code]"*.png, *.jpg, *.jpeg ; Supported Images"[/code] will show both PNG and JPEG files when selected.
</member>
<member name="option_count" type="int" setter="set_option_count" getter="get_option_count" default="0">
The number of additional [OptionButton]s and [CheckBox]es in the dialog.
</member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files" default="false">
If [code]true[/code], hidden files and directories will be visible in the [EditorFileDialog]. This property is synchronized with [member EditorSettings.filesystem/file_dialog/show_hidden_files].
</member>
<member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Save a File&quot;" />
</members> </members>
<signals>
<signal name="dir_selected">
<param index="0" name="dir" type="String" />
<description>
Emitted when a directory is selected.
</description>
</signal>
<signal name="file_selected">
<param index="0" name="path" type="String" />
<description>
Emitted when a file is selected.
</description>
</signal>
<signal name="filename_filter_changed">
<param index="0" name="filter" type="String" />
<description>
Emitted when the filter for file names changes.
</description>
</signal>
<signal name="files_selected">
<param index="0" name="paths" type="PackedStringArray" />
<description>
Emitted when multiple files are selected.
</description>
</signal>
</signals>
<constants>
<constant name="FILE_MODE_OPEN_FILE" value="0" enum="FileMode">
The [EditorFileDialog] can select only one file. Accepting the window will open the file.
</constant>
<constant name="FILE_MODE_OPEN_FILES" value="1" enum="FileMode">
The [EditorFileDialog] can select multiple files. Accepting the window will open all files.
</constant>
<constant name="FILE_MODE_OPEN_DIR" value="2" enum="FileMode">
The [EditorFileDialog] can select only one directory. Accepting the window will open the directory.
</constant>
<constant name="FILE_MODE_OPEN_ANY" value="3" enum="FileMode">
The [EditorFileDialog] can select a file or directory. Accepting the window will open it.
</constant>
<constant name="FILE_MODE_SAVE_FILE" value="4" enum="FileMode">
The [EditorFileDialog] can select only one file. Accepting the window will save the file.
</constant>
<constant name="ACCESS_RESOURCES" value="0" enum="Access">
The [EditorFileDialog] can only view [code]res://[/code] directory contents.
</constant>
<constant name="ACCESS_USERDATA" value="1" enum="Access">
The [EditorFileDialog] can only view [code]user://[/code] directory contents.
</constant>
<constant name="ACCESS_FILESYSTEM" value="2" enum="Access">
The [EditorFileDialog] can view the entire local file system.
</constant>
<constant name="DISPLAY_THUMBNAILS" value="0" enum="DisplayMode">
The [EditorFileDialog] displays resources as thumbnails.
</constant>
<constant name="DISPLAY_LIST" value="1" enum="DisplayMode">
The [EditorFileDialog] displays resources as a list of filenames.
</constant>
</constants>
</class> </class>

View file

@ -118,6 +118,12 @@
Returns [code]true[/code] if the provided [param flag] is enabled. Returns [code]true[/code] if the provided [param flag] is enabled.
</description> </description>
</method> </method>
<method name="popup_file_dialog">
<return type="void" />
<description>
Shows the [FileDialog] using the default size and position for file dialogs, and selects the file name if there is a current file.
</description>
</method>
<method name="set_customization_flag_enabled"> <method name="set_customization_flag_enabled">
<return type="void" /> <return type="void" />
<param index="0" name="flag" type="int" enum="FileDialog.Customization" /> <param index="0" name="flag" type="int" enum="FileDialog.Customization" />
@ -274,6 +280,7 @@
[b]Note:[/b] On Linux and macOS, sandboxed apps always use native dialogs to access the host file system. [b]Note:[/b] On Linux and macOS, sandboxed apps always use native dialogs to access the host file system.
[b]Note:[/b] On macOS, sandboxed apps will save security-scoped bookmarks to retain access to the opened folders across multiple sessions. Use [method OS.get_granted_permissions] to get a list of saved bookmarks. [b]Note:[/b] On macOS, sandboxed apps will save security-scoped bookmarks to retain access to the opened folders across multiple sessions. Use [method OS.get_granted_permissions] to get a list of saved bookmarks.
[b]Note:[/b] Native dialogs are isolated from the base process, file dialog properties can't be modified once the dialog is shown. [b]Note:[/b] Native dialogs are isolated from the base process, file dialog properties can't be modified once the dialog is shown.
[b]Note:[/b] This property is ignored in [EditorFileDialog].
</member> </member>
</members> </members>
<signals> <signals>

View file

@ -30,6 +30,7 @@
#include "asset_library_editor_plugin.h" #include "asset_library_editor_plugin.h"
#include "core/io/dir_access.h"
#include "core/io/json.h" #include "core/io/json.h"
#include "core/io/stream_peer_tls.h" #include "core/io/stream_peer_tls.h"
#include "core/os/keyboard.h" #include "core/os/keyboard.h"

View file

@ -2695,7 +2695,7 @@ int FileSystemDock::_get_menu_option_from_key(const Ref<InputEventKey> &p_key) {
return FILE_MENU_OPEN_EXTERNAL; return FILE_MENU_OPEN_EXTERNAL;
} else if (ED_IS_SHORTCUT("filesystem_dock/open_in_terminal", p_key)) { } else if (ED_IS_SHORTCUT("filesystem_dock/open_in_terminal", p_key)) {
return FILE_MENU_OPEN_IN_TERMINAL; return FILE_MENU_OPEN_IN_TERMINAL;
} else if (ED_IS_SHORTCUT("file_dialog/focus_path", p_key)) { } else if (ED_IS_SHORTCUT("filesystem_dock/focus_path", p_key)) {
return EXTRA_FOCUS_PATH; return EXTRA_FOCUS_PATH;
} else if (ED_IS_SHORTCUT("editor/open_search", p_key)) { } else if (ED_IS_SHORTCUT("editor/open_search", p_key)) {
return EXTRA_FOCUS_FILTER; return EXTRA_FOCUS_FILTER;
@ -4234,6 +4234,11 @@ FileSystemDock::FileSystemDock() {
ED_SHORTCUT("filesystem_dock/open_in_terminal", TTRC("Open in Terminal"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::T); ED_SHORTCUT("filesystem_dock/open_in_terminal", TTRC("Open in Terminal"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::T);
#endif #endif
ED_SHORTCUT("filesystem_dock/focus_path", TTRC("Focus Path"), KeyModifierMask::CMD_OR_CTRL | Key::L);
// Allow both Cmd + L and Cmd + Shift + G to match Safari's and Finder's shortcuts respectively.
ED_SHORTCUT_OVERRIDE_ARRAY("filesystem_dock/focus_path", "macos",
{ int32_t(KeyModifierMask::META | Key::L), int32_t(KeyModifierMask::META | KeyModifierMask::SHIFT | Key::G) });
// Properly translating color names would require a separate HashMap, so for simplicity they are provided as comments. // Properly translating color names would require a separate HashMap, so for simplicity they are provided as comments.
folder_colors["red"] = Color(1.0, 0.271, 0.271); // TTR("Red") folder_colors["red"] = Color(1.0, 0.271, 0.271); // TTR("Red")
folder_colors["orange"] = Color(1.0, 0.561, 0.271); // TTR("Orange") folder_colors["orange"] = Color(1.0, 0.561, 0.271); // TTR("Orange")

View file

@ -1029,8 +1029,6 @@ void EditorNode::_notification(int p_what) {
if (EditorSettings::get_singleton()->check_changed_settings_in_group("filesystem/file_dialog")) { if (EditorSettings::get_singleton()->check_changed_settings_in_group("filesystem/file_dialog")) {
FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files"));
FileDialog::set_default_display_mode(EDITOR_GET("filesystem/file_dialog/display_mode")); FileDialog::set_default_display_mode(EDITOR_GET("filesystem/file_dialog/display_mode"));
EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int());
} }
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/tablet_driver")) { if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/tablet_driver")) {
@ -1251,10 +1249,6 @@ void EditorNode::_fs_changed() {
E->invalidate(); E->invalidate();
} }
for (EditorFileDialog *E : editor_file_dialogs) {
E->invalidate();
}
_mark_unsaved_scenes(); _mark_unsaved_scenes();
// FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed. // FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed.
@ -5967,14 +5961,6 @@ void EditorNode::_file_dialog_unregister(FileDialog *p_dialog) {
singleton->file_dialogs.erase(p_dialog); singleton->file_dialogs.erase(p_dialog);
} }
void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) {
singleton->editor_file_dialogs.insert(p_dialog);
}
void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
singleton->editor_file_dialogs.erase(p_dialog);
}
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
void EditorNode::_begin_first_scan() { void EditorNode::_begin_first_scan() {
@ -8038,8 +8024,6 @@ EditorNode::EditorNode() {
FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files"));
FileDialog::set_default_display_mode(EDITOR_GET("filesystem/file_dialog/display_mode")); FileDialog::set_default_display_mode(EDITOR_GET("filesystem/file_dialog/display_mode"));
EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int());
int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons");
if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer. if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer.
@ -8182,10 +8166,6 @@ EditorNode::EditorNode() {
FileDialog::register_func = _file_dialog_register; FileDialog::register_func = _file_dialog_register;
FileDialog::unregister_func = _file_dialog_unregister; FileDialog::unregister_func = _file_dialog_unregister;
EditorFileDialog::get_icon_func = _file_dialog_get_icon;
EditorFileDialog::register_func = _editor_file_dialog_register;
EditorFileDialog::unregister_func = _editor_file_dialog_unregister;
editor_export = memnew(EditorExport); editor_export = memnew(EditorExport);
add_child(editor_export); add_child(editor_export);
@ -9263,12 +9243,7 @@ EditorNode::~EditorNode() {
FileDialog::register_func = nullptr; FileDialog::register_func = nullptr;
FileDialog::unregister_func = nullptr; FileDialog::unregister_func = nullptr;
EditorFileDialog::get_icon_func = nullptr;
EditorFileDialog::register_func = nullptr;
EditorFileDialog::unregister_func = nullptr;
file_dialogs.clear(); file_dialogs.clear();
editor_file_dialogs.clear();
singleton = nullptr; singleton = nullptr;
} }

View file

@ -481,7 +481,6 @@ private:
HashSet<String> textfile_extensions; HashSet<String> textfile_extensions;
HashSet<String> other_file_extensions; HashSet<String> other_file_extensions;
HashSet<FileDialog *> file_dialogs; HashSet<FileDialog *> file_dialogs;
HashSet<EditorFileDialog *> editor_file_dialogs;
Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins; Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins;
PrintHandlerList print_handler; PrintHandlerList print_handler;
@ -521,8 +520,6 @@ private:
static void _file_dialog_register(FileDialog *p_dialog); static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog); static void _file_dialog_unregister(FileDialog *p_dialog);
static void _editor_file_dialog_register(EditorFileDialog *p_dialog);
static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog);
static void _file_access_close_error_notify(const String &p_str); static void _file_access_close_error_notify(const String &p_str);
static void _file_access_close_error_notify_impl(const String &p_str); static void _file_access_close_error_notify_impl(const String &p_str);

View file

@ -1401,27 +1401,6 @@ void ProjectExportDialog::_open_export_template_manager() {
EditorNode::get_singleton()->open_export_template_manager(); EditorNode::get_singleton()->open_export_template_manager();
} }
void ProjectExportDialog::_validate_export_path(const String &p_path) {
// Disable export via OK button or Enter key if LineEdit has an empty filename
bool invalid_path = (p_path.get_file().get_basename().is_empty());
// Check if state change before needlessly messing with signals
if (invalid_path && export_project->get_ok_button()->is_disabled()) {
return;
}
if (!invalid_path && !export_project->get_ok_button()->is_disabled()) {
return;
}
if (invalid_path) {
export_project->get_ok_button()->set_disabled(true);
export_project->get_line_edit()->disconnect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
} else {
export_project->get_ok_button()->set_disabled(false);
export_project->get_line_edit()->connect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
}
}
void ProjectExportDialog::_export_project() { void ProjectExportDialog::_export_project() {
Ref<EditorExportPreset> current = get_current_preset(); Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null()); ERR_FAIL_COND(current.is_null());
@ -1446,16 +1425,6 @@ void ProjectExportDialog::_export_project() {
export_project->set_current_file(default_filename); export_project->set_current_file(default_filename);
} }
} }
// Ensure that signal is connected if previous attempt left it disconnected
// with _validate_export_path.
// FIXME: This is a hack, we should instead change EditorFileDialog to allow
// disabling validation by the "text_submitted" signal.
if (!export_project->get_line_edit()->is_connected(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted))) {
export_project->get_ok_button()->set_disabled(false);
export_project->get_line_edit()->connect(SceneStringName(text_submitted), callable_mp(export_project, &EditorFileDialog::_file_submitted));
}
export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
export_project->popup_file_dialog(); export_project->popup_file_dialog();
} }
@ -2041,7 +2010,6 @@ ProjectExportDialog::ProjectExportDialog() {
export_project->set_access(EditorFileDialog::ACCESS_FILESYSTEM); export_project->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(export_project); add_child(export_project);
export_project->connect("file_selected", callable_mp(this, &ProjectExportDialog::_export_project_to_path)); export_project->connect("file_selected", callable_mp(this, &ProjectExportDialog::_export_project_to_path));
export_project->get_line_edit()->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_validate_export_path));
export_project->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true)); export_project->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true));
export_pck_zip->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true)); export_pck_zip->add_option(TTR("Export With Debug"), Vector<String>(), EditorSettings::get_singleton()->get_project_metadata("export_options", "export_debug", true));

View file

@ -199,7 +199,6 @@ class ProjectExportDialog : public ConfirmationDialog {
void _export_pck_zip(); void _export_pck_zip();
void _export_pck_zip_selected(const String &p_path); void _export_pck_zip_selected(const String &p_path);
void _validate_export_path(const String &p_path);
void _export_project(); void _export_project();
void _export_project_to_path(const String &p_path); void _export_project_to_path(const String &p_path);
void _export_all_dialog(); void _export_all_dialog();

File diff suppressed because it is too large Load diff

View file

@ -30,348 +30,30 @@
#pragma once #pragma once
#include "core/io/dir_access.h" #include "scene/gui/file_dialog.h"
#include "editor/file_system/file_info.h"
#include "scene/gui/dialogs.h"
#include "scene/property_list_helper.h"
class DependencyRemoveDialog; class DependencyRemoveDialog;
class GridContainer;
class HSplitContainer;
class HFlowContainer;
class ItemList;
class MenuButton;
class OptionButton;
class PopupMenu;
class TextureRect;
class VSeparator;
class EditorFileDialog : public ConfirmationDialog { class EditorFileDialog : public FileDialog {
GDCLASS(EditorFileDialog, ConfirmationDialog); GDCLASS(EditorFileDialog, FileDialog);
public: DependencyRemoveDialog *dependency_remove_dialog = nullptr;
enum DisplayMode {
DISPLAY_THUMBNAILS,
DISPLAY_LIST
};
enum Access {
ACCESS_RESOURCES,
ACCESS_USERDATA,
ACCESS_FILESYSTEM
};
enum FileMode {
FILE_MODE_OPEN_FILE,
FILE_MODE_OPEN_FILES,
FILE_MODE_OPEN_DIR,
FILE_MODE_OPEN_ANY,
FILE_MODE_SAVE_FILE
};
typedef Ref<Texture2D> (*GetIconFunc)(const String &);
typedef void (*RegisterFunc)(EditorFileDialog *);
static inline GetIconFunc get_icon_func = nullptr;
static inline GetIconFunc get_thumbnail_func = nullptr;
static inline RegisterFunc register_func = nullptr;
static inline RegisterFunc unregister_func = nullptr;
private:
enum ItemMenu {
ITEM_MENU_COPY_PATH,
ITEM_MENU_DELETE,
ITEM_MENU_REFRESH,
ITEM_MENU_NEW_FOLDER,
ITEM_MENU_SHOW_IN_EXPLORER,
ITEM_MENU_SHOW_BUNDLE_CONTENT,
};
ConfirmationDialog *makedialog = nullptr;
LineEdit *makedirname = nullptr;
VSeparator *makedir_sep = nullptr;
Button *makedir = nullptr;
Access access = ACCESS_RESOURCES;
HFlowContainer *flow_checkbox_options = nullptr;
GridContainer *grid_select_options = nullptr;
VBoxContainer *vbox = nullptr;
FileMode mode = FILE_MODE_SAVE_FILE;
bool can_create_dir = false;
LineEdit *dir = nullptr;
Button *dir_prev = nullptr;
Button *dir_next = nullptr;
Button *dir_up = nullptr;
HBoxContainer *drives_container = nullptr;
HBoxContainer *shortcuts_container = nullptr;
OptionButton *drives = nullptr;
ItemList *item_list = nullptr;
PopupMenu *item_menu = nullptr;
TextureRect *preview = nullptr;
VBoxContainer *preview_vb = nullptr;
HSplitContainer *body_hsplit = nullptr;
HSplitContainer *list_hb = nullptr;
HBoxContainer *file_box = nullptr;
LineEdit *file = nullptr;
OptionButton *filter = nullptr;
AcceptDialog *error_dialog = nullptr;
Ref<DirAccess> dir_access;
ConfirmationDialog *confirm_save = nullptr;
DependencyRemoveDialog *dep_remove_dialog = nullptr;
ConfirmationDialog *global_remove_dialog = nullptr;
VBoxContainer *vbc = nullptr;
HBoxContainer *pathhb = nullptr;
Button *mode_thumbnails = nullptr;
Button *mode_list = nullptr;
Button *refresh = nullptr;
Button *favorite = nullptr;
Button *show_hidden = nullptr;
Button *show_search_filter_button = nullptr;
String search_string;
bool show_search_filter = false;
HBoxContainer *filter_hb = nullptr;
LineEdit *filter_box = nullptr;
FileSortOption file_sort = FileSortOption::FILE_SORT_NAME;
MenuButton *file_sort_button = nullptr;
Button *fav_up = nullptr;
Button *fav_down = nullptr;
ItemList *favorites = nullptr;
ItemList *recent = nullptr;
Vector<String> local_history;
int local_history_pos = 0;
void _push_history();
Vector<String> filters;
Vector<String> processed_filters;
bool previews_enabled = true;
bool preview_waiting = false;
int preview_wheel_index = 0;
float preview_wheel_timeout = 0.0f;
static inline bool default_show_hidden_files = false;
static inline DisplayMode default_display_mode = DISPLAY_THUMBNAILS;
bool show_hidden_files;
DisplayMode display_mode;
bool disable_overwrite_warning = false;
bool is_invalidating = false;
struct ThemeCache {
Ref<Texture2D> parent_folder;
Ref<Texture2D> forward_folder;
Ref<Texture2D> back_folder;
Ref<Texture2D> open_folder;
Ref<Texture2D> reload;
Ref<Texture2D> toggle_hidden;
Ref<Texture2D> toggle_filename_filter;
Ref<Texture2D> favorite;
Ref<Texture2D> mode_thumbnails;
Ref<Texture2D> mode_list;
Ref<Texture2D> create_folder;
Ref<Texture2D> favorites_up;
Ref<Texture2D> favorites_down;
Ref<Texture2D> filter_box;
Ref<Texture2D> file_sort_button;
Ref<Texture2D> file;
Ref<Texture2D> folder;
Color folder_icon_color;
Ref<Texture2D> action_copy;
Ref<Texture2D> action_delete;
Ref<Texture2D> filesystem;
Ref<Texture2D> folder_medium_thumbnail;
Ref<Texture2D> file_medium_thumbnail;
Ref<Texture2D> folder_big_thumbnail;
Ref<Texture2D> file_big_thumbnail;
Ref<Texture2D> progress[8]{};
} theme_cache;
struct Option {
String name;
Vector<String> values;
int default_idx = 0;
};
static inline PropertyListHelper base_property_helper;
PropertyListHelper property_helper;
Vector<Option> options;
Dictionary selected_options;
bool options_dirty = false;
String full_dir;
void update_dir();
void update_file_name();
void update_file_list();
void update_search_filter_gui();
void update_filters();
void _focus_file_text();
void _update_favorites();
void _favorite_pressed();
void _favorite_selected(int p_idx);
void _favorite_move_up();
void _favorite_move_down();
void _update_recent();
void _recent_selected(int p_idx);
void _item_selected(int p_item);
void _multi_selected(int p_item, bool p_selected);
void _items_clear_selection(const Vector2 &p_pos, MouseButton p_mouse_button_index);
void _item_dc_selected(int p_item);
void _item_list_item_rmb_clicked(int p_item, const Vector2 &p_pos, MouseButton p_mouse_button_index);
void _item_list_empty_clicked(const Vector2 &p_pos, MouseButton p_mouse_button_index);
void _item_menu_id_pressed(int p_option);
void _select_drive(int p_idx);
void _dir_submitted(const String &p_dir);
void _action_pressed();
void _save_confirm_pressed();
void _cancel_pressed();
void _filter_selected(int);
void _make_dir();
void _make_dir_confirm();
void _focus_filter_box();
void _filter_changed(const String &p_text);
void _search_filter_selected();
void _file_sort_popup(int p_id);
void _delete_items();
void _delete_files_global();
void _update_drives(bool p_select = true);
void _update_icons();
void _go_up();
void _go_back();
void _go_forward();
void _invalidate();
virtual void _post_popup() override;
void _save_to_recent();
// Callback function is callback(String p_path,Ref<Texture2D> preview,Variant udata) preview null if could not load.
void _thumbnail_result(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview);
void _thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview);
void _request_single_thumbnail(const String &p_path);
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
bool _is_open_should_be_disabled();
void _native_popup();
void _native_dialog_cb(bool p_ok, const Vector<String> &p_files, int p_filter, const Dictionary &p_selected_options);
TypedArray<Dictionary> _get_options() const;
void _update_option_controls();
void _option_changed_checkbox_toggled(bool p_pressed, const String &p_name);
void _option_changed_item_selected(int p_idx, const String &p_name);
protected: protected:
virtual void _update_theme_item_cache() override; virtual void _item_menu_id_pressed(int p_option) override;
virtual bool _should_use_native_popup() const override;
virtual bool _should_hide_file(const String &p_file) const override;
virtual Color _get_folder_color(const String &p_path) const override;
virtual void _popup_base(const Rect2i &p_rect = Rect2i()) override;
void _notification(int p_what);
bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); }
bool _get(const StringName &p_name, Variant &r_ret) const { return property_helper.property_get_value(p_name, r_ret); }
void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list); }
bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); }
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); }
static void _bind_methods(); static void _bind_methods();
void _validate_property(PropertyInfo &p_property) const;
void _notification(int p_what);
public: public:
virtual void set_visible(bool p_visible) override;
// Public for use with callable_mp.
void _file_submitted(const String &p_file);
void popup_file_dialog();
void clear_filters();
void add_filter(const String &p_filter, const String &p_description = "");
void set_filters(const Vector<String> &p_filters);
Vector<String> get_filters() const;
void clear_search_filter();
void set_search_filter(const String &p_search_filter);
String get_search_filter() const;
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
String get_current_dir() const;
String get_current_file() const;
String get_current_path() const;
void set_current_dir(const String &p_dir);
void set_current_file(const String &p_file);
void set_current_path(const String &p_path);
String get_option_name(int p_option) const;
Vector<String> get_option_values(int p_option) const;
int get_option_default(int p_option) const;
void set_option_name(int p_option, const String &p_name);
void set_option_values(int p_option, const Vector<String> &p_values);
void set_option_default(int p_option, int p_index);
void add_option(const String &p_name, const Vector<String> &p_values, int p_index);
void set_option_count(int p_count);
int get_option_count() const;
Dictionary get_selected_options() const;
void set_display_mode(DisplayMode p_mode);
DisplayMode get_display_mode() const;
void set_file_mode(FileMode p_mode);
FileMode get_file_mode() const;
VBoxContainer *get_vbox();
LineEdit *get_line_edit() { return file; }
void set_access(Access p_access);
Access get_access() const;
static void set_default_show_hidden_files(bool p_show);
static void set_default_display_mode(DisplayMode p_mode);
void set_show_hidden_files(bool p_show);
void set_show_search_filter(bool p_show);
bool is_showing_hidden_files() const;
void invalidate();
void set_disable_overwrite_warning(bool p_disable);
bool is_overwrite_warning_disabled() const;
void set_previews_enabled(bool p_enabled);
bool are_previews_enabled();
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
void add_side_menu(Control *p_menu, const String &p_title = "") { ERR_FAIL_MSG("add_side_menu() is kept for compatibility and does nothing. For similar functionality, you can show another dialog after file dialog."); } void add_side_menu(Control *p_menu, const String &p_title = "") { ERR_FAIL_MSG("add_side_menu() is kept for compatibility and does nothing. For similar functionality, you can show another dialog after file dialog."); }
void set_disable_overwrite_warning(bool p_disable) { set_customization_flag_enabled(CUSTOMIZATION_OVERWRITE_WARNING, !p_disable); }
bool is_overwrite_warning_disabled() const { return !is_customization_flag_enabled(CUSTOMIZATION_OVERWRITE_WARNING); }
#endif #endif
EditorFileDialog();
~EditorFileDialog();
}; };
VARIANT_ENUM_CAST(EditorFileDialog::FileMode);
VARIANT_ENUM_CAST(EditorFileDialog::Access);
VARIANT_ENUM_CAST(EditorFileDialog::DisplayMode);

View file

@ -978,7 +978,6 @@ void ProjectDialog::_notification(int p_what) {
} break; } break;
case NOTIFICATION_READY: { case NOTIFICATION_READY: {
fdialog_project = memnew(EditorFileDialog); fdialog_project = memnew(EditorFileDialog);
fdialog_project->set_previews_enabled(false); // Crucial, otherwise the engine crashes.
fdialog_project->set_access(EditorFileDialog::ACCESS_FILESYSTEM); fdialog_project->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
fdialog_project->connect("dir_selected", callable_mp(this, &ProjectDialog::_project_path_selected)); fdialog_project->connect("dir_selected", callable_mp(this, &ProjectDialog::_project_path_selected));
fdialog_project->connect("file_selected", callable_mp(this, &ProjectDialog::_project_path_selected)); fdialog_project->connect("file_selected", callable_mp(this, &ProjectDialog::_project_path_selected));
@ -1188,7 +1187,6 @@ ProjectDialog::ProjectDialog() {
spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
default_files_container->add_child(spacer); default_files_container->add_child(spacer);
fdialog_install = memnew(EditorFileDialog); fdialog_install = memnew(EditorFileDialog);
fdialog_install->set_previews_enabled(false); //Crucial, otherwise the engine crashes.
fdialog_install->set_access(EditorFileDialog::ACCESS_FILESYSTEM); fdialog_install->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(fdialog_install); add_child(fdialog_install);

View file

@ -1366,11 +1366,11 @@ ProjectManager::ProjectManager() {
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale")); EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break; break;
} }
EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon; FileDialog::set_get_icon_callback(callable_mp_static(ProjectManager::_file_dialog_get_icon));
EditorFileDialog::get_thumbnail_func = &ProjectManager::_file_dialog_get_thumbnail; FileDialog::set_get_thumbnail_callback(callable_mp_static(ProjectManager::_file_dialog_get_thumbnail));
EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int()); FileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int());
int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons");
if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer. if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer.
@ -1735,7 +1735,6 @@ ProjectManager::ProjectManager() {
quick_settings_dialog->connect("restart_required", callable_mp(this, &ProjectManager::_restart_confirmed)); quick_settings_dialog->connect("restart_required", callable_mp(this, &ProjectManager::_restart_confirmed));
scan_dir = memnew(EditorFileDialog); scan_dir = memnew(EditorFileDialog);
scan_dir->set_previews_enabled(false);
scan_dir->set_access(EditorFileDialog::ACCESS_FILESYSTEM); scan_dir->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
scan_dir->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); scan_dir->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR);
scan_dir->set_title(TTRC("Select a Folder to Scan")); // Must be after mode or it's overridden. scan_dir->set_title(TTRC("Select a Folder to Scan")); // Must be after mode or it's overridden.

View file

@ -459,7 +459,7 @@ void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) {
file_browse->set_title(TTR("Open Script")); file_browse->set_title(TTR("Open Script"));
} }
file_browse->set_disable_overwrite_warning(true); file_browse->set_customization_flag_enabled(FileDialog::CUSTOMIZATION_OVERWRITE_WARNING, false);
file_browse->clear_filters(); file_browse->clear_filters();
List<String> extensions; List<String> extensions;

View file

@ -54,6 +54,7 @@
#include "main/main.h" #include "main/main.h"
#include "modules/regex/regex.h" #include "modules/regex/regex.h"
#include "scene/gui/color_picker.h" #include "scene/gui/color_picker.h"
#include "scene/gui/file_dialog.h"
#include "scene/main/node.h" #include "scene/main/node.h"
#include "scene/main/scene_tree.h" #include "scene/main/scene_tree.h"
#include "scene/main/window.h" #include "scene/main/window.h"
@ -1591,7 +1592,17 @@ void EditorSettings::save_project_metadata() {
project_metadata_dirty = false; project_metadata_dirty = false;
} }
void EditorSettings::set_favorites(const Vector<String> &p_favorites) { void EditorSettings::set_favorites(const Vector<String> &p_favorites, bool p_update_file_dialog) {
if (p_update_file_dialog) {
FileDialog::set_favorite_list(p_favorites);
} else if (p_favorites == favorites) {
// If the list came from EditorFileDialog, it may be the same as before.
return;
}
set_favorites_bind(p_favorites);
}
void EditorSettings::set_favorites_bind(const Vector<String> &p_favorites) {
favorites = p_favorites; favorites = p_favorites;
String favorites_file; String favorites_file;
if (Engine::get_singleton()->is_project_manager_hint()) { if (Engine::get_singleton()->is_project_manager_hint()) {
@ -1627,7 +1638,17 @@ HashMap<String, PackedStringArray> EditorSettings::get_favorite_properties() con
return favorite_properties; return favorite_properties;
} }
void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs, bool p_update_file_dialog) {
if (p_update_file_dialog) {
FileDialog::set_recent_list(p_recent_dirs);
} else if (p_recent_dirs == recent_dirs) {
// If the list came from EditorFileDialog, it may be the same as before.
return;
}
set_recent_dirs_bind(p_recent_dirs);
}
void EditorSettings::set_recent_dirs_bind(const Vector<String> &p_recent_dirs) {
recent_dirs = p_recent_dirs; recent_dirs = p_recent_dirs;
String recent_dirs_file; String recent_dirs_file;
if (Engine::get_singleton()->is_project_manager_hint()) { if (Engine::get_singleton()->is_project_manager_hint()) {
@ -1671,6 +1692,7 @@ void EditorSettings::load_favorites_and_recent_dirs() {
line = f->get_line().strip_edges(); line = f->get_line().strip_edges();
} }
} }
FileDialog::set_favorite_list(favorites);
/// Inspector Favorites /// Inspector Favorites
@ -1701,6 +1723,7 @@ void EditorSettings::load_favorites_and_recent_dirs() {
line = f->get_line().strip_edges(); line = f->get_line().strip_edges();
} }
} }
FileDialog::set_recent_list(recent_dirs);
} }
HashMap<StringName, Color> EditorSettings::get_godot2_text_editor_theme() { HashMap<StringName, Color> EditorSettings::get_godot2_text_editor_theme() {
@ -2237,9 +2260,9 @@ void EditorSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata); ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata);
ClassDB::bind_method(D_METHOD("get_project_metadata", "section", "key", "default"), &EditorSettings::get_project_metadata, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("get_project_metadata", "section", "key", "default"), &EditorSettings::get_project_metadata, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("set_favorites", "dirs"), &EditorSettings::set_favorites); ClassDB::bind_method(D_METHOD("set_favorites", "dirs"), &EditorSettings::set_favorites_bind);
ClassDB::bind_method(D_METHOD("get_favorites"), &EditorSettings::get_favorites); ClassDB::bind_method(D_METHOD("get_favorites"), &EditorSettings::get_favorites);
ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs); ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs_bind);
ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs); ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs);
ClassDB::bind_method(D_METHOD("set_builtin_action_override", "name", "actions_list"), &EditorSettings::set_builtin_action_override); ClassDB::bind_method(D_METHOD("set_builtin_action_override", "name", "actions_list"), &EditorSettings::set_builtin_action_override);

View file

@ -177,11 +177,13 @@ public:
Variant get_project_metadata(const String &p_section, const String &p_key, const Variant &p_default) const; Variant get_project_metadata(const String &p_section, const String &p_key, const Variant &p_default) const;
void save_project_metadata(); void save_project_metadata();
void set_favorites(const Vector<String> &p_favorites); void set_favorites(const Vector<String> &p_favorites, bool p_update_file_dialog = true);
void set_favorites_bind(const Vector<String> &p_favorites);
Vector<String> get_favorites() const; Vector<String> get_favorites() const;
void set_favorite_properties(const HashMap<String, PackedStringArray> &p_favorite_properties); void set_favorite_properties(const HashMap<String, PackedStringArray> &p_favorite_properties);
HashMap<String, PackedStringArray> get_favorite_properties() const; HashMap<String, PackedStringArray> get_favorite_properties() const;
void set_recent_dirs(const Vector<String> &p_recent_dirs); void set_recent_dirs(const Vector<String> &p_recent_dirs, bool p_update_file_dialog = true);
void set_recent_dirs_bind(const Vector<String> &p_recent_dirs);
Vector<String> get_recent_dirs() const; Vector<String> get_recent_dirs() const;
void load_favorites_and_recent_dirs(); void load_favorites_and_recent_dirs();

View file

@ -306,7 +306,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
handled = true; handled = true;
} }
if (ED_IS_SHORTCUT("file_dialog/focus_path", p_event)) { if (ED_IS_SHORTCUT("filesystem_dock/focus_path", p_event)) {
_focus_current_path_box(); _focus_current_path_box();
handled = true; handled = true;
} }

View file

@ -31,6 +31,7 @@
#include "shader_create_dialog.h" #include "shader_create_dialog.h"
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_file_dialog.h"
#include "editor/gui/editor_validation_panel.h" #include "editor/gui/editor_validation_panel.h"
@ -261,7 +262,7 @@ void ShaderCreateDialog::_browse_path() {
file_browse->set_title(TTR("Open Shader / Choose Location")); file_browse->set_title(TTR("Open Shader / Choose Location"));
file_browse->set_ok_button_text(TTR("Open")); file_browse->set_ok_button_text(TTR("Open"));
file_browse->set_disable_overwrite_warning(true); file_browse->set_customization_flag_enabled(FileDialog::CUSTOMIZATION_OVERWRITE_WARNING, false);
file_browse->clear_filters(); file_browse->clear_filters();
List<String> extensions = type_data.get(type_menu->get_selected()).extensions; List<String> extensions = type_data.get(type_menu->get_selected()).extensions;

View file

@ -1050,6 +1050,8 @@ void ThemeClassic::populate_standard_styles(const Ref<EditorTheme> &p_theme, Edi
p_theme->set_color("folder_icon_color", "FileDialog", (p_config.dark_icon_and_font ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(p_config.accent_color, 0.7)); p_theme->set_color("folder_icon_color", "FileDialog", (p_config.dark_icon_and_font ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(p_config.accent_color, 0.7));
p_theme->set_color("file_disabled_color", "FileDialog", p_config.font_disabled_color); p_theme->set_color("file_disabled_color", "FileDialog", p_config.font_disabled_color);
p_theme->set_constant("thumbnail_size", "EditorFileDialog", p_config.thumb_size);
// PopupDialog. // PopupDialog.
p_theme->set_stylebox(SceneStringName(panel), "PopupDialog", p_config.popup_style); p_theme->set_stylebox(SceneStringName(panel), "PopupDialog", p_config.popup_style);

View file

@ -1003,6 +1003,8 @@ void ThemeModern::populate_standard_styles(const Ref<EditorTheme> &p_theme, Edit
p_theme->set_color("folder_icon_color", "FileDialog", (p_config.dark_icon_and_font ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(p_config.accent_color, 0.7)); p_theme->set_color("folder_icon_color", "FileDialog", (p_config.dark_icon_and_font ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(p_config.accent_color, 0.7));
p_theme->set_color("file_disabled_color", "FileDialog", p_config.font_disabled_color); p_theme->set_color("file_disabled_color", "FileDialog", p_config.font_disabled_color);
p_theme->set_constant("thumbnail_size", "EditorFileDialog", p_config.thumb_size);
// PopupDialog. // PopupDialog.
p_theme->set_stylebox(SceneStringName(panel), "PopupDialog", p_config.dialog_style); p_theme->set_stylebox(SceneStringName(panel), "PopupDialog", p_config.dialog_style);

View file

@ -174,3 +174,54 @@ Validate extension JSON: Error: Field 'classes/GLTFState/methods/get_unique_name
Validate extension JSON: Error: Field 'classes/GLTFState/methods/get_use_named_skin_binds': is_const changed value in new API, from false to true. Validate extension JSON: Error: Field 'classes/GLTFState/methods/get_use_named_skin_binds': is_const changed value in new API, from false to true.
GLTFState getters made const. Compatibility methods registered. GLTFState getters made const. Compatibility methods registered.
GH-111212
---------
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/add_filter
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/add_option
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/add_side_menu
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/clear_filename_filter
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/clear_filters
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_access
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_current_dir
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_current_file
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_current_path
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_display_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_file_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_filename_filter
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_filters
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_line_edit
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_option_count
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_option_default
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_option_name
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_option_values
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_selected_options
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/get_vbox
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/invalidate
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/is_showing_hidden_files
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/popup_file_dialog
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_access
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_current_dir
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_current_file
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_current_path
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_display_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_file_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_filename_filter
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_filters
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_option_count
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_option_default
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_option_name
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_option_values
Validate extension JSON: API was removed: classes/EditorFileDialog/methods/set_show_hidden_files
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/access
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/current_dir
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/current_file
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/current_path
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/display_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/file_mode
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/filters
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/option_count
Validate extension JSON: API was removed: classes/EditorFileDialog/properties/show_hidden_files
The errors are false-positives. The removed methods are now part of the new parent class.

View file

@ -31,6 +31,7 @@
#include "openxr_action_map_editor.h" #include "openxr_action_map_editor.h"
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_bottom_panel.h"
#include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_file_dialog.h"

View file

@ -49,7 +49,7 @@
#include "scene/theme/theme_db.h" #include "scene/theme/theme_db.h"
void FileDialog::popup_file_dialog() { void FileDialog::popup_file_dialog() {
popup_centered_clamped(Size2i(700, 500), 0.8f); popup_centered_clamped(Vector2(1050, 700) * get_theme_default_base_scale(), 0.8f);
_focus_file_text(); _focus_file_text();
} }
@ -88,30 +88,13 @@ void FileDialog::_native_popup() {
} }
} }
bool FileDialog::_can_use_native_popup() { bool FileDialog::_can_use_native_popup() const {
if (access == ACCESS_RESOURCES || access == ACCESS_USERDATA || options.size() > 0) { if (access == ACCESS_RESOURCES || access == ACCESS_USERDATA || options.size() > 0) {
return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_EXTRA); return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_EXTRA);
} }
return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE); return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE);
} }
void FileDialog::_popup_base(const Rect2i &p_rect) {
_update_option_controls();
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
ConfirmationDialog::_popup_base(p_rect);
return;
}
#endif
if (_can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
_native_popup();
} else {
ConfirmationDialog::_popup_base(p_rect);
}
}
void FileDialog::set_visible(bool p_visible) { void FileDialog::set_visible(bool p_visible) {
if (p_visible) { if (p_visible) {
_update_option_controls(); _update_option_controls();
@ -124,7 +107,7 @@ void FileDialog::set_visible(bool p_visible) {
} }
#endif #endif
if (_can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { if (_should_use_native_popup()) {
if (p_visible) { if (p_visible) {
_native_popup(); _native_popup();
} }
@ -228,6 +211,10 @@ void FileDialog::_native_dialog_cb_with_options(bool p_ok, const Vector<String>
} }
} }
bool FileDialog::_should_use_native_popup() const {
return _can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed());
}
void FileDialog::_validate_property(PropertyInfo &p_property) const { void FileDialog::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "dialog_text") { if (p_property.name == "dialog_text") {
// File dialogs have a custom layout, and dialog nodes can't have both a text and a layout. // File dialogs have a custom layout, and dialog nodes can't have both a text and a layout.
@ -245,7 +232,7 @@ void FileDialog::_notification(int p_what) {
#endif #endif
// Replace the built-in dialog with the native one if it started visible. // Replace the built-in dialog with the native one if it started visible.
if (is_visible() && _can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { if (is_visible() && _should_use_native_popup()) {
ConfirmationDialog::set_visible(false); ConfirmationDialog::set_visible(false);
_native_popup(); _native_popup();
} }
@ -259,6 +246,21 @@ void FileDialog::_notification(int p_what) {
} }
} break; } break;
case NOTIFICATION_TRANSLATION_CHANGED: {
update_filters();
[[fallthrough]];
}
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
if (main_vbox->is_layout_rtl()) {
_setup_button(dir_prev, theme_cache.forward_folder);
_setup_button(dir_next, theme_cache.back_folder);
} else {
_setup_button(dir_prev, theme_cache.back_folder);
_setup_button(dir_next, theme_cache.forward_folder);
}
} break;
case NOTIFICATION_THEME_CHANGED: { case NOTIFICATION_THEME_CHANGED: {
favorite_list->set_custom_minimum_size(Vector2(128 * get_theme_default_base_scale(), 0)); favorite_list->set_custom_minimum_size(Vector2(128 * get_theme_default_base_scale(), 0));
recent_list->set_custom_minimum_size(Vector2(128 * get_theme_default_base_scale(), 0)); recent_list->set_custom_minimum_size(Vector2(128 * get_theme_default_base_scale(), 0));
@ -284,8 +286,22 @@ void FileDialog::_notification(int p_what) {
invalidate(); invalidate();
} break; } break;
case NOTIFICATION_TRANSLATION_CHANGED: { case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
update_filters(); if (!is_visible()) {
return;
}
// Check if the current directory was removed externally (much less likely to happen while the window is focused).
const String previous_dir = get_current_dir();
while (!dir_access->dir_exists(get_current_dir())) {
_go_up();
// In case we can't go further up, use some fallback and break.
if (get_current_dir() == previous_dir) {
_dir_submitted(OS::get_singleton()->get_user_data_dir());
break;
}
}
} break; } break;
} }
} }
@ -304,10 +320,6 @@ void FileDialog::shortcut_input(const Ref<InputEvent> &p_event) {
} }
} }
void FileDialog::set_enable_multiple_selection(bool p_enable) {
file_list->set_select_mode(p_enable ? ItemList::SELECT_MULTI : ItemList::SELECT_SINGLE);
}
Vector<String> FileDialog::get_selected_files() const { Vector<String> FileDialog::get_selected_files() const {
const String current_dir = dir_access->get_current_dir(); const String current_dir = dir_access->get_current_dir();
Vector<String> list; Vector<String> list;
@ -356,10 +368,6 @@ void FileDialog::_dir_submitted(String p_dir) {
_push_history(); _push_history();
} }
void FileDialog::_file_submitted(const String &p_file) {
_action_pressed();
}
void FileDialog::_save_confirm_pressed() { void FileDialog::_save_confirm_pressed() {
_save_to_recent(); _save_to_recent();
@ -525,24 +533,6 @@ bool FileDialog::_is_open_should_be_disabled() {
return false; return false;
} }
void FileDialog::_thumbnail_callback(const Ref<Texture2D> &p_texture, const String &p_path) {
if (display_mode == DISPLAY_LIST || p_texture.is_null()) {
return;
}
if (!p_path.begins_with(full_dir)) {
return;
}
const String file_name = p_path.get_file();
for (int i = 0; i < file_list->get_item_count(); i++) {
if (file_list->get_item_text(i) == file_name) {
file_list->set_item_icon(i, p_texture);
break;
}
}
}
void FileDialog::_go_up() { void FileDialog::_go_up() {
_change_dir(".."); _change_dir("..");
_push_history(); _push_history();
@ -819,7 +809,6 @@ void FileDialog::update_file_list() {
LocalVector<String> files; LocalVector<String> files;
LocalVector<String> dirs; LocalVector<String> dirs;
bool is_hidden;
String item = dir_access->get_next(); String item = dir_access->get_next();
while (!item.is_empty()) { while (!item.is_empty()) {
@ -828,9 +817,7 @@ void FileDialog::update_file_list() {
continue; continue;
} }
is_hidden = dir_access->current_is_hidden(); if (show_hidden_files || (!dir_access->current_is_hidden() && !_should_hide_file(item))) {
if (show_hidden_files || !is_hidden) {
if (!dir_access->current_is_dir()) { if (!dir_access->current_is_dir()) {
files.push_back(item); files.push_back(item);
} else { } else {
@ -913,7 +900,7 @@ void FileDialog::update_file_list() {
} else { } else {
file_list->add_item(info.name, info.bundle ? theme_cache.file : theme_cache.folder); file_list->add_item(info.name, info.bundle ? theme_cache.file : theme_cache.folder);
} }
file_list->set_item_icon_modulate(-1, theme_cache.folder_icon_color); file_list->set_item_icon_modulate(-1, _get_folder_color(base_dir.path_join(info.name)));
Dictionary d; Dictionary d;
d["name"] = info.name; d["name"] = info.name;
@ -977,7 +964,6 @@ void FileDialog::update_file_list() {
file_list->add_item(info.name); file_list->add_item(info.name);
const String path = base_dir.path_join(info.name); const String path = base_dir.path_join(info.name);
if (display_mode == DISPLAY_LIST) {
Ref<Texture2D> icon; Ref<Texture2D> icon;
if (get_icon_callback.is_valid()) { if (get_icon_callback.is_valid()) {
const Variant &v = path; const Variant &v = path;
@ -991,12 +977,14 @@ void FileDialog::update_file_list() {
} }
icon = vicon; icon = vicon;
} }
if (display_mode == DISPLAY_LIST) {
if (icon.is_null()) { if (icon.is_null()) {
icon = theme_cache.file; icon = theme_cache.file;
} }
file_list->set_item_icon(-1, icon); file_list->set_item_icon(-1, icon);
} else { // DISPLAY_THUMBNAILS } else { // DISPLAY_THUMBNAILS
Ref<Texture2D> icon; Ref<Texture2D> thumbnail;
if (get_thumbnail_callback.is_valid()) { if (get_thumbnail_callback.is_valid()) {
const Variant &v = path; const Variant &v = path;
const Variant *argptrs[1] = { &v }; const Variant *argptrs[1] = { &v };
@ -1007,12 +995,15 @@ void FileDialog::update_file_list() {
if (unlikely(ce.error != Callable::CallError::CALL_OK)) { if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
ERR_PRINT(vformat("Error calling FileDialog's thumbnail callback: %s.", Variant::get_callable_error_text(get_thumbnail_callback, argptrs, 1, ce))); ERR_PRINT(vformat("Error calling FileDialog's thumbnail callback: %s.", Variant::get_callable_error_text(get_thumbnail_callback, argptrs, 1, ce)));
} }
icon = vicon; thumbnail = vicon;
} }
if (icon.is_null()) { if (thumbnail.is_null()) {
icon = theme_cache.file; thumbnail = theme_cache.file;
}
file_list->set_item_icon(-1, thumbnail);
if (icon.is_valid()) {
file_list->set_item_tag_icon(-1, icon);
} }
file_list->set_item_icon(-1, icon);
} }
file_list->set_item_icon_modulate(-1, theme_cache.file_icon_color); file_list->set_item_icon_modulate(-1, theme_cache.file_icon_color);
@ -1381,7 +1372,7 @@ FileDialog::FileMode FileDialog::get_file_mode() const {
} }
void FileDialog::set_display_mode(DisplayMode p_mode) { void FileDialog::set_display_mode(DisplayMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 2); ERR_FAIL_INDEX((int)p_mode, DISPLAY_MAX);
if (display_mode == p_mode) { if (display_mode == p_mode) {
return; return;
} }
@ -1731,6 +1722,7 @@ void FileDialog::_update_favorite_list() {
favorite_list->add_item(favorited_names[i], theme_cache.folder); favorite_list->add_item(favorited_names[i], theme_cache.folder);
favorite_list->set_item_tooltip(-1, favorited_paths[i]); favorite_list->set_item_tooltip(-1, favorited_paths[i]);
favorite_list->set_item_metadata(-1, favorited_paths[i]); favorite_list->set_item_metadata(-1, favorited_paths[i]);
favorite_list->set_item_icon_modulate(-1, _get_folder_color(favorited_paths[i]));
if (i == current_favorite) { if (i == current_favorite) {
favorite_button->set_pressed(true); favorite_button->set_pressed(true);
@ -1818,6 +1810,7 @@ void FileDialog::_update_recent_list() {
recent_list->add_item(recent_dir_names[i], theme_cache.folder); recent_list->add_item(recent_dir_names[i], theme_cache.folder);
recent_list->set_item_tooltip(-1, recent_dir_paths[i]); recent_list->set_item_tooltip(-1, recent_dir_paths[i]);
recent_list->set_item_metadata(-1, recent_dir_paths[i]); recent_list->set_item_metadata(-1, recent_dir_paths[i]);
recent_list->set_item_icon_modulate(-1, _get_folder_color(recent_dir_paths[i]));
} }
} }
@ -2053,6 +2046,7 @@ void FileDialog::_bind_methods() {
ClassDB::bind_static_method("FileDialog", D_METHOD("set_get_icon_callback", "callback"), &FileDialog::set_get_icon_callback); ClassDB::bind_static_method("FileDialog", D_METHOD("set_get_icon_callback", "callback"), &FileDialog::set_get_icon_callback);
ClassDB::bind_static_method("FileDialog", D_METHOD("set_get_thumbnail_callback", "callback"), &FileDialog::set_get_thumbnail_callback); ClassDB::bind_static_method("FileDialog", D_METHOD("set_get_thumbnail_callback", "callback"), &FileDialog::set_get_thumbnail_callback);
ClassDB::bind_method(D_METHOD("popup_file_dialog"), &FileDialog::popup_file_dialog);
ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate); ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title");
@ -2213,7 +2207,7 @@ void FileDialog::set_use_native_dialog(bool p_native) {
#endif #endif
// Replace the built-in dialog with the native one if it's currently visible. // Replace the built-in dialog with the native one if it's currently visible.
if (is_inside_tree() && is_visible() && _can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) { if (is_inside_tree() && _should_use_native_popup()) {
ConfirmationDialog::set_visible(false); ConfirmationDialog::set_visible(false);
_native_popup(); _native_popup();
} }
@ -2229,7 +2223,6 @@ FileDialog::FileDialog() {
set_size(Size2(640, 360)); set_size(Size2(640, 360));
set_default_ok_text(ETR("Save")); // Default mode text. set_default_ok_text(ETR("Save")); // Default mode text.
set_process_shortcut_input(true); set_process_shortcut_input(true);
thumbnail_callback = callable_mp(this, &FileDialog::_thumbnail_callback);
for (int i = 0; i < CUSTOMIZATION_MAX; i++) { for (int i = 0; i < CUSTOMIZATION_MAX; i++) {
customization_flags[i] = true; customization_flags[i] = true;
@ -2336,6 +2329,7 @@ FileDialog::FileDialog() {
{ {
Label *label = memnew(Label(ETR("Favorites:"))); Label *label = memnew(Label(ETR("Favorites:")));
label->set_h_size_flags(Control::SIZE_EXPAND_FILL); label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label->set_theme_type_variation("HeaderSmall");
fav_hbox->add_child(label); fav_hbox->add_child(label);
} }
@ -2363,6 +2357,7 @@ FileDialog::FileDialog() {
{ {
Label *label = memnew(Label(ETR("Recent:"))); Label *label = memnew(Label(ETR("Recent:")));
label->set_theme_type_variation("HeaderSmall");
recent_vbox->add_child(label); recent_vbox->add_child(label);
} }
@ -2503,7 +2498,7 @@ FileDialog::FileDialog() {
filename_edit->set_stretch_ratio(4); filename_edit->set_stretch_ratio(4);
filename_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); filename_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
file_box->add_child(filename_edit); file_box->add_child(filename_edit);
filename_edit->connect(SceneStringName(text_submitted), callable_mp(this, &FileDialog::_file_submitted)); filename_edit->connect(SceneStringName(text_submitted), callable_mp(this, &FileDialog::_action_pressed).unbind(1));
filter = memnew(OptionButton); filter = memnew(OptionButton);
filter->set_stretch_ratio(3); filter->set_stretch_ratio(3);

View file

@ -127,6 +127,7 @@ public:
enum DisplayMode { enum DisplayMode {
DISPLAY_THUMBNAILS, DISPLAY_THUMBNAILS,
DISPLAY_LIST, DISPLAY_LIST,
DISPLAY_MAX
}; };
enum ItemMenu { enum ItemMenu {
@ -184,7 +185,6 @@ private:
FileMode mode = FILE_MODE_SAVE_FILE; FileMode mode = FILE_MODE_SAVE_FILE;
DisplayMode display_mode = DISPLAY_THUMBNAILS; DisplayMode display_mode = DISPLAY_THUMBNAILS;
FileSortOption file_sort = FileSortOption::NAME; FileSortOption file_sort = FileSortOption::NAME;
Ref<DirAccess> dir_access;
Vector<String> filters; Vector<String> filters;
Vector<String> processed_filters; Vector<String> processed_filters;
@ -204,7 +204,6 @@ private:
String root_prefix; String root_prefix;
String full_dir; String full_dir;
Callable thumbnail_callback;
bool is_invalidating = false; bool is_invalidating = false;
VBoxContainer *main_vbox = nullptr; VBoxContainer *main_vbox = nullptr;
@ -299,7 +298,6 @@ private:
void update_filters(); void update_filters();
void update_customization(); void update_customization();
void _item_menu_id_pressed(int p_option);
void _empty_clicked(const Vector2 &p_pos, MouseButton p_button); void _empty_clicked(const Vector2 &p_pos, MouseButton p_button);
void _item_clicked(int p_item, const Vector2 &p_pos, MouseButton p_button); void _item_clicked(int p_item, const Vector2 &p_pos, MouseButton p_button);
void _popup_menu(const Vector2 &p_pos, int p_for_item); void _popup_menu(const Vector2 &p_pos, int p_for_item);
@ -314,7 +312,6 @@ private:
void _select_drive(int p_idx); void _select_drive(int p_idx);
void _dir_submitted(String p_dir); void _dir_submitted(String p_dir);
void _file_submitted(const String &p_file);
void _action_pressed(); void _action_pressed();
void _save_confirm_pressed(); void _save_confirm_pressed();
void _cancel_pressed(); void _cancel_pressed();
@ -352,7 +349,6 @@ private:
virtual void shortcut_input(const Ref<InputEvent> &p_event) override; virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
bool _can_use_native_popup();
void _native_popup(); void _native_popup();
void _native_dialog_cb(bool p_ok, const Vector<String> &p_files, int p_filter); void _native_dialog_cb(bool p_ok, const Vector<String> &p_files, int p_filter);
void _native_dialog_cb_with_options(bool p_ok, const Vector<String> &p_files, int p_filter, const Dictionary &p_selected_options); void _native_dialog_cb_with_options(bool p_ok, const Vector<String> &p_files, int p_filter, const Dictionary &p_selected_options);
@ -368,7 +364,15 @@ private:
virtual void _post_popup() override; virtual void _post_popup() override;
protected: protected:
virtual void _popup_base(const Rect2i &p_rect = Rect2i()) override; Ref<DirAccess> dir_access;
bool _can_use_native_popup() const;
virtual void _item_menu_id_pressed(int p_option);
virtual bool _should_use_native_popup() const;
virtual bool _should_hide_file(const String &p_file) const { return false; }
virtual Color _get_folder_color(const String &p_path) const { return theme_cache.folder_icon_color; }
void _validate_property(PropertyInfo &p_property) const; void _validate_property(PropertyInfo &p_property) const;
void _notification(int p_what); void _notification(int p_what);
bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); } bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); }
@ -376,6 +380,7 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list); } void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list); }
bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); }
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); }
static void _bind_methods(); static void _bind_methods();
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
@ -396,7 +401,6 @@ public:
void set_filename_filter(const String &p_filename_filter); void set_filename_filter(const String &p_filename_filter);
String get_filename_filter() const; String get_filename_filter() const;
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const; Vector<String> get_selected_files() const;
String get_current_dir() const; String get_current_dir() const;
@ -446,6 +450,7 @@ public:
VBoxContainer *get_vbox() { return main_vbox; } VBoxContainer *get_vbox() { return main_vbox; }
LineEdit *get_line_edit() { return filename_edit; } LineEdit *get_line_edit() { return filename_edit; }
ItemList *get_file_item_list() { return file_list; }
void set_access(Access p_access); void set_access(Access p_access);
Access get_access() const; Access get_access() const;