diff options
Diffstat (limited to 'editor/editor_resource_picker.cpp')
-rw-r--r-- | editor/editor_resource_picker.cpp | 123 |
1 files changed, 83 insertions, 40 deletions
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index f05c401f1d..53f1a689d6 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,11 +30,15 @@ #include "editor_resource_picker.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_node.h" #include "editor/editor_resource_preview.h" -#include "editor_node.h" -#include "editor_scale.h" -#include "editor_settings.h" -#include "filesystem_dock.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "editor/filesystem_dock.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/quick_open.h" +#include "editor/scene_tree_dock.h" HashMap<StringName, List<StringName>> EditorResourcePicker::allowed_types_cache; @@ -49,21 +53,23 @@ void EditorResourcePicker::_update_resource() { if (edited_resource == RES()) { assign_button->set_icon(Ref<Texture2D>()); assign_button->set_text(TTR("[empty]")); + assign_button->set_tooltip(""); } else { assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); - if (edited_resource->get_name() != String()) { + if (!edited_resource->get_name().is_empty()) { assign_button->set_text(edited_resource->get_name()); } else if (edited_resource->get_path().is_resource_file()) { assign_button->set_text(edited_resource->get_path().get_file()); - assign_button->set_tooltip(edited_resource->get_path()); } else { assign_button->set_text(edited_resource->get_class()); } + String resource_path; if (edited_resource->get_path().is_resource_file()) { - assign_button->set_tooltip(edited_resource->get_path()); + resource_path = edited_resource->get_path() + "\n"; } + assign_button->set_tooltip(resource_path + TTR("Type:") + " " + edited_resource->get_class()); // Preview will override the above, so called at the end. EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); @@ -75,16 +81,16 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const return; } - String type = edited_resource->get_class_name(); - if (ClassDB::is_parent_class(type, "Script")) { - assign_button->set_text(edited_resource->get_path().get_file()); + Ref<Script> script = edited_resource; + if (script.is_valid()) { + assign_button->set_text(script->get_path().get_file()); return; } if (p_preview.is_valid()) { preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox(SNAME("normal"))->get_default_margin(SIDE_LEFT) + get_theme_constant(SNAME("hseparation"), SNAME("Button"))); - if (type == "GradientTexture") { + if (Ref<GradientTexture1D>(edited_resource).is_valid()) { preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); assign_button->set_custom_minimum_size(Size2(1, 1)); } else { @@ -113,7 +119,7 @@ void EditorResourcePicker::_file_selected(const String &p_path) { RES loaded_resource = ResourceLoader::load(p_path); ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'."); - if (base_type != "") { + if (!base_type.is_empty()) { bool any_type_matches = false; for (int i = 0; i < base_type.get_slice_count(","); i++) { @@ -143,7 +149,7 @@ void EditorResourcePicker::_update_menu() { _update_menu_items(); Rect2 gt = edit_button->get_screen_rect(); - edit_menu->set_as_minsize(); + edit_menu->reset_size(); int ms = edit_menu->get_contents_minimum_size().width; Vector2 popup_pos = gt.get_end() - Vector2(ms, 0); edit_menu->set_position(popup_pos); @@ -180,7 +186,7 @@ void EditorResourcePicker::_update_menu_items() { RES cb = EditorSettings::get_singleton()->get_resource_clipboard(); bool paste_valid = false; if (cb.is_valid()) { - if (base_type == "") { + if (base_type.is_empty()) { paste_valid = true; } else { for (int i = 0; i < base_type.get_slice_count(","); i++) { @@ -321,17 +327,24 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { case OBJ_MENU_PASTE: { edited_resource = EditorSettings::get_singleton()->get_resource_clipboard(); + if (edited_resource->is_built_in() && EditorNode::get_singleton()->get_edited_scene() && + edited_resource->get_path().get_slice("::", 0) != EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path()) { + // Automatically make resource unique if it belongs to another scene. + _edit_menu_cbk(OBJ_MENU_MAKE_UNIQUE); + return; + } + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(edited_resource->get_path()); // Ensure that the FileSystem dock is visible. TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(file_system_dock->get_index()); + tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); } break; default: { @@ -375,6 +388,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Resource *resp = Object::cast_to<Resource>(obj); ERR_BREAK(!resp); + EditorNode::get_editor_data().instantiate_object_properties(obj); + edited_resource = RES(resp); emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); @@ -385,13 +400,12 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { void EditorResourcePicker::set_create_options(Object *p_menu_node) { _ensure_resource_menu(); // If a subclass implements this method, use it to replace all create items. - if (get_script_instance() && get_script_instance()->has_method("_set_create_options")) { - get_script_instance()->call("_set_create_options", p_menu_node); + if (GDVIRTUAL_CALL(_set_create_options, p_menu_node)) { return; } // By default provide generic "New ..." options. - if (base_type != "") { + if (!base_type.is_empty()) { int idx = 0; Set<String> allowed_types; @@ -442,8 +456,9 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) { } bool EditorResourcePicker::handle_menu_selected(int p_which) { - if (get_script_instance() && get_script_instance()->has_method("_handle_menu_selected")) { - return get_script_instance()->call("_handle_menu_selected", p_which); + bool success; + if (GDVIRTUAL_CALL(_handle_menu_selected, p_which, success)) { + return success; } return false; @@ -464,11 +479,11 @@ void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { + if (mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { _update_menu_items(); Vector2 pos = get_screen_position() + mb->get_position(); - edit_menu->set_as_minsize(); + edit_menu->reset_size(); edit_menu->set_position(pos); edit_menu->popup(); } @@ -514,12 +529,14 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> * } if (p_with_convert) { - if (base == "StandardMaterial3D") { + if (base == "BaseMaterial3D") { p_vector->insert("Texture2D"); } else if (base == "ShaderMaterial") { p_vector->insert("Shader"); } else if (base == "Font") { p_vector->insert("FontData"); + } else if (base == "Texture2D") { + p_vector->insert("Image"); } } } @@ -571,7 +588,7 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { String file = files[0]; String file_type = EditorFileSystem::get_singleton()->get_file_type(file); - if (file_type != "" && _is_type_valid(file_type, allowed_types)) { + if (!file_type.is_empty() && _is_type_valid(file_type, allowed_types)) { return true; } } @@ -636,26 +653,46 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { String at = E->get().strip_edges(); - if (at == "StandardMaterial3D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture2D")) { - Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); + if (at == "BaseMaterial3D" && Ref<Texture2D>(dropped_resource).is_valid()) { + // Use existing resource if possible and only replace its data. + Ref<StandardMaterial3D> mat = edited_resource; + if (!mat.is_valid()) { + mat.instantiate(); + } mat->set_texture(StandardMaterial3D::TextureParam::TEXTURE_ALBEDO, dropped_resource); dropped_resource = mat; break; } - if (at == "ShaderMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Shader")) { - Ref<ShaderMaterial> mat = memnew(ShaderMaterial); + if (at == "ShaderMaterial" && Ref<Shader>(dropped_resource).is_valid()) { + Ref<ShaderMaterial> mat = edited_resource; + if (!mat.is_valid()) { + mat.instantiate(); + } mat->set_shader(dropped_resource); dropped_resource = mat; break; } - if (at == "Font" && ClassDB::is_parent_class(dropped_resource->get_class(), "FontData")) { - Ref<Font> font = memnew(Font); + if (at == "Font" && Ref<FontData>(dropped_resource).is_valid()) { + Ref<Font> font = edited_resource; + if (!font.is_valid()) { + font.instantiate(); + } font->add_data(dropped_resource); dropped_resource = font; break; } + + if (at == "Texture2D" && Ref<Image>(dropped_resource).is_valid()) { + Ref<ImageTexture> texture = edited_resource; + if (!texture.is_valid()) { + texture.instantiate(); + } + texture->create_from_image(dropped_resource); + dropped_resource = texture; + break; + } } } @@ -682,8 +719,8 @@ void EditorResourcePicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editable", "enable"), &EditorResourcePicker::set_editable); ClassDB::bind_method(D_METHOD("is_editable"), &EditorResourcePicker::is_editable); - ClassDB::add_virtual_method(get_class_static(), MethodInfo("_set_create_options", PropertyInfo(Variant::OBJECT, "menu_node"))); - ClassDB::add_virtual_method(get_class_static(), MethodInfo("_handle_menu_selected", PropertyInfo(Variant::INT, "id"))); + GDVIRTUAL_BIND(_set_create_options, "menu_node"); + GDVIRTUAL_BIND(_handle_menu_selected, "id"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource", PROPERTY_USAGE_NONE), "set_edited_resource", "get_edited_resource"); @@ -838,6 +875,7 @@ void EditorResourcePicker::_ensure_resource_menu() { edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); } + EditorResourcePicker::EditorResourcePicker() { assign_button = memnew(Button); assign_button->set_flat(true); @@ -850,7 +888,7 @@ EditorResourcePicker::EditorResourcePicker() { assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); preview_rect = memnew(TextureRect); - preview_rect->set_expand(true); + preview_rect->set_ignore_texture_size(true); preview_rect->set_anchors_and_offsets_preset(PRESET_WIDE); preview_rect->set_offset(SIDE_TOP, 1); preview_rect->set_offset(SIDE_BOTTOM, -1); @@ -874,7 +912,12 @@ void EditorScriptPicker::set_create_options(Object *p_menu_node) { } menu_node->add_icon_item(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); - menu_node->add_icon_item(get_theme_icon(SNAME("ScriptExtend"), SNAME("EditorIcons")), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); + if (script_owner) { + Ref<Script> script = script_owner->get_script(); + if (script.is_valid()) { + menu_node->add_icon_item(get_theme_icon(SNAME("ScriptExtend"), SNAME("EditorIcons")), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); + } + } menu_node->add_separator(); } @@ -882,14 +925,14 @@ bool EditorScriptPicker::handle_menu_selected(int p_which) { switch (p_which) { case OBJ_MENU_NEW_SCRIPT: { if (script_owner) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, false); + SceneTreeDock::get_singleton()->open_script_dialog(script_owner, false); } return true; } case OBJ_MENU_EXTEND_SCRIPT: { if (script_owner) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, true); + SceneTreeDock::get_singleton()->open_script_dialog(script_owner, true); } return true; } @@ -934,7 +977,7 @@ bool EditorShaderPicker::handle_menu_selected(int p_which) { switch (p_which) { case OBJ_MENU_NEW_SHADER: { if (material.is_valid()) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_shader_dialog(material, preferred_mode); + SceneTreeDock::get_singleton()->open_shader_dialog(material, preferred_mode); return true; } } break; |