diff --git a/doc/classes/EditorResourcePicker.xml b/doc/classes/EditorResourcePicker.xml
new file mode 100644
index 000000000000..0803dc25811f
--- /dev/null
+++ b/doc/classes/EditorResourcePicker.xml
@@ -0,0 +1,115 @@
+
+
+
+ Godot editor's control for selecting [Resource] type properties.
+
+
+ This [Control] node is used in the editor's Inspector dock to allow editing of [Resource] type properties. It provides options for creating, loading, saving and converting resources. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
+ [b]Note:[/b] This [Control] does not include any editor for the resource, as editing is controlled by the Inspector dock itself or sub-Inspectors.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Returns a list of all allowed types and subtypes corresponding to the [member base_type]. If the [member base_type] is empty, an empty list is returned.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This virtual method can be implemented to handle context menu items not handled by default. See [method set_create_options].
+
+
+
+
+
+
+
+
+ This virtual method is called when updating the context menu of [EditorResourcePicker]. Implement this method to override the "New ..." items with your own options. [code]menu_node[/code] is a reference to the [PopupMenu] node.
+ [b]Note:[/b] Implement [method handle_menu_selected] to handle these custom items.
+
+
+
+
+
+
+
+
+ Sets the toggle mode state for the main button. Works only if [member toggle_mode] is set to [code]true[/code].
+
+
+
+
+
+ The base type of allowed resource types. Can be a comma-separated list of several options.
+
+
+ If [code]true[/code], the value can be selected and edited.
+
+
+ The edited resource value.
+
+
+ If [code]true[/code], the main button with the resource preview works in the toggle mode. Use [method set_toggle_pressed] to manually set the state.
+
+
+
+
+
+
+
+ Emitted when the value of the edited resource was changed.
+
+
+
+
+
+
+ Emitted when the resource value was set and user clicked to edit it.
+
+
+
+
+
+
diff --git a/doc/classes/EditorScriptPicker.xml b/doc/classes/EditorScriptPicker.xml
new file mode 100644
index 000000000000..761219d319e6
--- /dev/null
+++ b/doc/classes/EditorScriptPicker.xml
@@ -0,0 +1,21 @@
+
+
+
+ Godot editor's control for selecting the [code]script[/code] property of a [Node].
+
+
+ Similar to [EditorResourcePicker] this [Control] node is used in the editor's Inspector dock, but only to edit the [code]script[/code] property of a [Node]. Default options for creating new resources of all possible subtypes are replaced with dedicated buttons that open the "Attach Node Script" dialog. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
+ [b]Note:[/b] You must set the [member script_owner] for the custom context menu items to work.
+
+
+
+
+
+
+
+ The owner [Node] of the script property that holds the edited resource.
+
+
+
+
+
diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml
index 173d76132c77..50b25ce945f0 100644
--- a/doc/classes/EditorSpinSlider.xml
+++ b/doc/classes/EditorSpinSlider.xml
@@ -1,8 +1,10 @@
+ Godot editor's control for editing numeric values.
+ This [Control] node is used in the editor's Inspector dock to allow editing of numeric values. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ef04cafadf81..e8245fe687f9 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -79,6 +79,7 @@
#include "editor/editor_log.h"
#include "editor/editor_plugin.h"
#include "editor/editor_properties.h"
+#include "editor/editor_resource_picker.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_run_native.h"
#include "editor/editor_run_script.h"
@@ -3799,6 +3800,8 @@ void EditorNode::register_editor_types() {
ClassDB::register_class();
ClassDB::register_class();
ClassDB::register_class();
+ ClassDB::register_class();
+ ClassDB::register_class();
ClassDB::register_virtual_class();
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index d6c5bd5fcc11..6cbf4889f9b2 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2083,426 +2083,64 @@ EditorPropertyRID::EditorPropertyRID() {
////////////// RESOURCE //////////////////////
-void EditorPropertyResource::_file_selected(const String &p_path) {
- RES res = ResourceLoader::load(p_path);
-
- ERR_FAIL_COND_MSG(res.is_null(), "Cannot load resource from path '" + p_path + "'.");
-
- List prop_list;
- get_edited_object()->get_property_list(&prop_list);
- String property_types;
-
- for (List::Element *E = prop_list.front(); E; E = E->next()) {
- if (E->get().name == get_edited_property() && (E->get().hint & PROPERTY_HINT_RESOURCE_TYPE)) {
- property_types = E->get().hint_string;
- }
- }
- if (!property_types.empty()) {
- bool any_type_matches = false;
- const Vector split_property_types = property_types.split(",");
- for (int i = 0; i < split_property_types.size(); ++i) {
- if (res->is_class(split_property_types[i])) {
- any_type_matches = true;
- break;
- }
- }
-
- if (!any_type_matches) {
- EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), res->get_class(), property_types));
- }
+void EditorPropertyResource::_resource_selected(const RES &p_resource) {
+ if (use_sub_inspector) {
+ bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property());
+ get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold);
+ update_property();
+ } else {
+ emit_signal("resource_selected", get_edited_property(), p_resource);
}
-
- emit_changed(get_edited_property(), res);
- update_property();
}
-void EditorPropertyResource::_menu_option(int p_which) {
- // scene_tree->popup_centered_ratio();
- switch (p_which) {
- case OBJ_MENU_LOAD: {
- if (!file) {
- file = memnew(EditorFileDialog);
- file->connect("file_selected", this, "_file_selected");
- add_child(file);
- }
- file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
- String type = base_type;
-
- List extensions;
- for (int i = 0; i < type.get_slice_count(","); i++) {
- ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions);
- }
-
- Set valid_extensions;
- for (List::Element *E = extensions.front(); E; E = E->next()) {
- valid_extensions.insert(E->get());
- }
-
- file->clear_filters();
- for (Set::Element *E = valid_extensions.front(); E; E = E->next()) {
- file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
- }
-
- file->popup_centered_ratio();
- } break;
-
- case OBJ_MENU_EDIT: {
- RES res = get_edited_object()->get(get_edited_property());
+void EditorPropertyResource::_resource_changed(const RES &p_resource) {
+ // Make visual script the correct type.
+ Ref