From 99b889b6c3d13d76e29582682d69a049a153a041 Mon Sep 17 00:00:00 2001 From: kobewi Date: Mon, 8 Dec 2025 13:50:19 +0100 Subject: [PATCH] Allow dragging from shader editor to material --- editor/inspector/editor_resource_picker.cpp | 96 +++++++++------------ editor/inspector/editor_resource_picker.h | 1 + editor/shader/shader_editor_plugin.cpp | 6 ++ 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/editor/inspector/editor_resource_picker.cpp b/editor/inspector/editor_resource_picker.cpp index aeaa56775d..3fa5b6d8fa 100644 --- a/editor/inspector/editor_resource_picker.cpp +++ b/editor/inspector/editor_resource_picker.cpp @@ -843,45 +843,26 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { return true; } - Dictionary drag_data = p_drag_data; - - Ref res; - if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { - ScriptEditorBase *se = Object::cast_to(drag_data["script_list_element"]); - if (se) { - res = se->get_edited_resource(); - } - } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - res = drag_data["resource"]; - } else if (drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector files = drag_data["files"]; - - if (files.size() == 1) { - if (ResourceLoader::exists(files[0])) { - // TODO: Extract the typename of the dropped filepath's resource in a more performant way, without fully loading it. - res = ResourceLoader::load(files[0]); - } - } + Ref res = _get_dropped_resource(p_drag_data); + if (res.is_null()) { + return false; } _ensure_allowed_types(); HashSet allowed_types = allowed_types_with_convert; - if (res.is_valid()) { - String res_type = _get_resource_type(res); + String res_type = _get_resource_type(res); - if (_is_type_valid(res_type, allowed_types)) { - return true; - } - - if (res->get_script()) { - StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res->get_script()); - if (_is_type_valid(custom_class, allowed_types)) { - return true; - } - } + if (_is_type_valid(res_type, allowed_types)) { + return true; } + if (res->get_script()) { + StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res->get_script()); + if (_is_type_valid(custom_class, allowed_types)) { + return true; + } + } return false; } @@ -915,6 +896,36 @@ bool EditorResourcePicker::_is_custom_type_script() const { return false; } +Ref EditorResourcePicker::_get_dropped_resource(const Variant &p_data) const { + Dictionary drag_data = p_data; + const String type = drag_data.get("type", ""); + if (type.is_empty()) { + return Ref(); + } + + Ref res; + if (type == "script_list_element") { + ScriptEditorBase *se = Object::cast_to(drag_data["script_list_element"]); + if (se) { + return se->get_edited_resource(); + } + } else if (type == "shader_list_element") { + return ResourceCache::get_ref(drag_data["file_path"]); + } else if (type == "resource") { + return drag_data["resource"]; + } else if (type == "files") { + Vector files = drag_data["files"]; + + if (files.size() == 1) { + if (ResourceLoader::exists(files[0])) { + // TODO: Extract the typename of the dropped filepath's resource in a more performant way, without fully loading it. + return ResourceLoader::load(files[0]); + } + } + } + return Ref(); +} + Variant EditorResourcePicker::get_drag_data_fw(const Point2 &p_point, Control *p_from) { if (edited_resource.is_valid()) { Dictionary drag_data = EditorNode::get_singleton()->drag_resource(edited_resource, p_from); @@ -930,28 +941,7 @@ bool EditorResourcePicker::can_drop_data_fw(const Point2 &p_point, const Variant } void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - ERR_FAIL_COND(!_is_drop_valid(p_data)); - - Dictionary drag_data = p_data; - - Ref dropped_resource; - if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { - ScriptEditorBase *se = Object::cast_to(drag_data["script_list_element"]); - if (se) { - dropped_resource = se->get_edited_resource(); - } - } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - dropped_resource = drag_data["resource"]; - } - - if (dropped_resource.is_null() && drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector files = drag_data["files"]; - - if (files.size() == 1) { - dropped_resource = ResourceLoader::load(files[0]); - } - } - + Ref dropped_resource = _get_dropped_resource(p_data); if (dropped_resource.is_valid()) { _ensure_allowed_types(); HashSet allowed_types = allowed_types_without_convert; diff --git a/editor/inspector/editor_resource_picker.h b/editor/inspector/editor_resource_picker.h index 18b5a0d921..67622c1451 100644 --- a/editor/inspector/editor_resource_picker.h +++ b/editor/inspector/editor_resource_picker.h @@ -112,6 +112,7 @@ class EditorResourcePicker : public HBoxContainer { bool _is_drop_valid(const Dictionary &p_drag_data) const; bool _is_type_valid(const String &p_type_name, const HashSet &p_allowed_types) const; bool _is_custom_type_script() const; + Ref _get_dropped_resource(const Variant &p_data) const; Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; diff --git a/editor/shader/shader_editor_plugin.cpp b/editor/shader/shader_editor_plugin.cpp index 9e468b033f..b38fd2b8c9 100644 --- a/editor/shader/shader_editor_plugin.cpp +++ b/editor/shader/shader_editor_plugin.cpp @@ -668,6 +668,12 @@ Variant ShaderEditorPlugin::get_drag_data_fw(const Point2 &p_point, Control *p_f drag_data["type"] = "shader_list_element"; drag_data["shader_list_element"] = idx; + Ref shader = edited_shaders[idx].shader; + if (shader.is_null()) { + shader = edited_shaders[idx].shader_inc; + } + drag_data["file_path"] = shader->get_path(); + return drag_data; }