3737#include " editor/editor_settings.h"
3838#include " editor/editor_string_names.h"
3939#include " editor/filesystem_dock.h"
40+ #include " editor/gui/editor_file_dialog.h"
4041#include " editor/gui/editor_quick_open_dialog.h"
4142#include " editor/plugins/editor_resource_conversion_plugin.h"
4243#include " editor/plugins/script_editor_plugin.h"
@@ -181,15 +182,6 @@ void EditorResourcePicker::_resource_saved(Object *p_resource) {
181182 }
182183}
183184
184- void EditorResourcePicker::_load_button_pressed () {
185- Vector<StringName> base_types;
186- for (const String &type : base_type.split (" ," )) {
187- base_types.push_back (type);
188- }
189-
190- EditorNode::get_singleton ()->get_quick_open_dialog ()->popup_dialog (base_types, callable_mp (this , &EditorResourcePicker::_file_selected));
191- }
192-
193185void EditorResourcePicker::_update_menu () {
194186 _update_menu_items ();
195187
@@ -205,23 +197,20 @@ void EditorResourcePicker::_update_menu_items() {
205197 _ensure_resource_menu ();
206198 edit_menu->clear ();
207199
208- bool added_create_options = false ;
209-
210200 // Add options for creating specific subtypes of the base resource type.
211201 if (is_editable ()) {
212- int previous_item_count = edit_menu->get_item_count ();
213-
214202 set_create_options (edit_menu);
215203
216- added_create_options = previous_item_count != edit_menu->get_item_count ();
204+ // Add an option to load a resource from a file using the QuickOpen dialog.
205+ edit_menu->add_icon_item (get_editor_theme_icon (SNAME (" Load" )), TTR (" Quick Load..." ), OBJ_MENU_QUICKLOAD);
206+ edit_menu->set_item_tooltip (-1 , TTR (" Opens a quick menu to select from a list of allowed Resource files." ));
207+
208+ // Add an option to load a resource from a file using the regular file dialog.
209+ edit_menu->add_icon_item (get_editor_theme_icon (SNAME (" Load" )), TTR (" Load..." ), OBJ_MENU_LOAD);
217210 }
218211
219212 // Add options for changing existing value of the resource.
220213 if (edited_resource.is_valid ()) {
221- if (added_create_options) {
222- edit_menu->add_separator ();
223- }
224-
225214 // Determine if the edited resource is part of another scene (foreign) which was imported
226215 bool is_edited_resource_foreign_import = EditorNode::get_singleton ()->is_resource_read_only (edited_resource, true );
227216
@@ -321,6 +310,47 @@ void EditorResourcePicker::_update_menu_items() {
321310
322311void EditorResourcePicker::_edit_menu_cbk (int p_which) {
323312 switch (p_which) {
313+ case OBJ_MENU_LOAD: {
314+ List<String> extensions;
315+ for (int i = 0 ; i < base_type.get_slice_count (" ," ); i++) {
316+ String base = base_type.get_slice (" ," , i);
317+ ResourceLoader::get_recognized_extensions_for_type (base, &extensions);
318+ if (ScriptServer::is_global_class (base)) {
319+ ResourceLoader::get_recognized_extensions_for_type (ScriptServer::get_global_class_native_base (base), &extensions);
320+ }
321+ }
322+
323+ HashSet<String> valid_extensions;
324+ for (const String &E : extensions) {
325+ valid_extensions.insert (E);
326+ }
327+
328+ if (!file_dialog) {
329+ file_dialog = memnew (EditorFileDialog);
330+ file_dialog->set_file_mode (EditorFileDialog::FILE_MODE_OPEN_FILE);
331+ add_child (file_dialog);
332+ file_dialog->connect (" file_selected" , callable_mp (this , &EditorResourcePicker::_file_selected));
333+ }
334+
335+ file_dialog->clear_filters ();
336+ for (const String &E : valid_extensions) {
337+ file_dialog->add_filter (" *." + E, E.to_upper ());
338+ }
339+
340+ file_dialog->popup_file_dialog ();
341+ } break ;
342+
343+ case OBJ_MENU_QUICKLOAD: {
344+ const Vector<String> &base_types_string = base_type.split (" ," );
345+
346+ Vector<StringName> base_types;
347+ for (const String &type : base_types_string) {
348+ base_types.push_back (type);
349+ }
350+
351+ EditorNode::get_singleton ()->get_quick_open_dialog ()->popup_dialog (base_types, callable_mp (this , &EditorResourcePicker::_file_selected));
352+ } break ;
353+
324354 case OBJ_MENU_INSPECT: {
325355 if (edited_resource.is_valid ()) {
326356 emit_signal (SNAME (" resource_selected" ), edited_resource, true );
@@ -472,25 +502,29 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) {
472502 HashSet<StringName> allowed_types = allowed_types_without_convert;
473503
474504 for (const StringName &E : allowed_types) {
475- const String &type = E;
505+ const String &t = E;
476506
477- if (!ClassDB::can_instantiate (type )) {
507+ if (!ClassDB::can_instantiate (t )) {
478508 continue ;
479509 }
480510
481- inheritors_array.push_back (type );
511+ inheritors_array.push_back (t );
482512
483- Ref<Texture2D> icon = EditorNode::get_singleton ()->get_class_icon (type , " Object" );
513+ Ref<Texture2D> icon = EditorNode::get_singleton ()->get_class_icon (t , " Object" );
484514 int id = TYPE_BASE_ID + idx;
485- edit_menu->add_icon_item (icon, vformat (TTR (" New %s" ), type ), id);
515+ edit_menu->add_icon_item (icon, vformat (TTR (" New %s" ), t ), id);
486516
487- HashMap<String, DocData::ClassDoc>::Iterator class_doc = EditorHelp::get_doc_data ()->class_list .find (type );
517+ HashMap<String, DocData::ClassDoc>::Iterator class_doc = EditorHelp::get_doc_data ()->class_list .find (t );
488518 if (class_doc) {
489519 edit_menu->set_item_tooltip (-1 , DTR (class_doc->value .brief_description ));
490520 }
491521
492522 idx++;
493523 }
524+
525+ if (edit_menu->get_item_count ()) {
526+ edit_menu->add_separator ();
527+ }
494528 }
495529}
496530
@@ -807,7 +841,6 @@ void EditorResourcePicker::_notification(int p_what) {
807841 edit_menu->add_theme_constant_override (" icon_max_width" , icon_width);
808842 }
809843
810- load_button->set_button_icon (get_editor_theme_icon (SNAME (" Load" )));
811844 edit_button->set_button_icon (get_theme_icon (SNAME (" select_arrow" ), SNAME (" Tree" )));
812845 } break ;
813846
@@ -949,7 +982,6 @@ void EditorResourcePicker::set_resource_owner(Object *p_object) {
949982void EditorResourcePicker::set_editable (bool p_editable) {
950983 editable = p_editable;
951984 assign_button->set_disabled (!editable && edited_resource.is_null ());
952- load_button->set_visible (editable);
953985 edit_button->set_visible (editable);
954986}
955987
@@ -1075,17 +1107,12 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
10751107 assign_button->add_child (preview_rect);
10761108 }
10771109
1078- load_button = memnew (Button);
1079- load_button->set_flat (false );
1080- add_child (load_button);
1081- load_button->connect (SceneStringName (pressed), callable_mp (this , &EditorResourcePicker::_load_button_pressed));
1082-
10831110 edit_button = memnew (Button);
10841111 edit_button->set_flat (false );
10851112 edit_button->set_toggle_mode (true );
10861113 edit_button->set_action_mode (BaseButton::ACTION_MODE_BUTTON_PRESS);
1087- add_child (edit_button);
10881114 edit_button->connect (SceneStringName (pressed), callable_mp (this , &EditorResourcePicker::_update_menu));
1115+ add_child (edit_button);
10891116 edit_button->connect (SceneStringName (gui_input), callable_mp (this , &EditorResourcePicker::_button_input));
10901117
10911118 add_theme_constant_override (" separation" , 0 );
@@ -1109,6 +1136,7 @@ void EditorScriptPicker::set_create_options(Object *p_menu_node) {
11091136 menu_node->add_icon_item (get_editor_theme_icon (SNAME (" ScriptExtend" )), TTR (" Extend Script..." ), OBJ_MENU_EXTEND_SCRIPT);
11101137 }
11111138 }
1139+ menu_node->add_separator ();
11121140}
11131141
11141142bool EditorScriptPicker::handle_menu_selected (int p_which) {
@@ -1158,6 +1186,7 @@ void EditorShaderPicker::set_create_options(Object *p_menu_node) {
11581186 }
11591187
11601188 menu_node->add_icon_item (get_editor_theme_icon (SNAME (" Shader" )), TTR (" New Shader..." ), OBJ_MENU_NEW_SHADER);
1189+ menu_node->add_separator ();
11611190}
11621191
11631192bool EditorShaderPicker::handle_menu_selected (int p_which) {
0 commit comments