diff options
Diffstat (limited to 'editor/editor_resource_picker.cpp')
-rw-r--r-- | editor/editor_resource_picker.cpp | 194 |
1 files changed, 134 insertions, 60 deletions
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index d1a0bfeded..a4ab749db4 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -36,6 +36,12 @@ #include "editor_settings.h" #include "filesystem_dock.h" +HashMap<StringName, List<StringName>> EditorResourcePicker::allowed_types_cache; + +void EditorResourcePicker::clear_caches() { + allowed_types_cache.clear(); +} + void EditorResourcePicker::_update_resource() { preview_rect->set_texture(Ref<Texture2D>()); assign_button->set_custom_minimum_size(Size2(1, 1)); @@ -76,7 +82,7 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const } if (p_preview.is_valid()) { - preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox("normal")->get_default_margin(SIDE_LEFT) + get_theme_constant("hseparation", "Button")); + 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") { preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); @@ -100,7 +106,7 @@ void EditorResourcePicker::_resource_selected() { return; } - emit_signal("resource_selected", edited_resource); + emit_signal(SNAME("resource_selected"), edited_resource); } void EditorResourcePicker::_file_selected(const String &p_path) { @@ -125,7 +131,7 @@ void EditorResourcePicker::_file_selected(const String &p_path) { } edited_resource = loaded_resource; - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } @@ -141,20 +147,21 @@ void EditorResourcePicker::_update_menu() { } void EditorResourcePicker::_update_menu_items() { + _ensure_resource_menu(); edit_menu->clear(); // Add options for creating specific subtypes of the base resource type. set_create_options(edit_menu); // Add an option to load a resource from a file. - edit_menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD); + edit_menu->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Load"), OBJ_MENU_LOAD); // Add options for changing existing value of the resource. if (edited_resource.is_valid()) { - edit_menu->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT); - edit_menu->add_icon_item(get_theme_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR); - edit_menu->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); - edit_menu->add_icon_item(get_theme_icon("Save", "EditorIcons"), TTR("Save"), OBJ_MENU_SAVE); + edit_menu->add_icon_item(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), TTR("Edit"), OBJ_MENU_EDIT); + edit_menu->add_icon_item(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")), TTR("Clear"), OBJ_MENU_CLEAR); + edit_menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); + edit_menu->add_icon_item(get_theme_icon(SNAME("Save"), SNAME("EditorIcons")), TTR("Save"), OBJ_MENU_SAVE); if (edited_resource->get_path().is_resource_file()) { edit_menu->add_separator(); @@ -199,13 +206,13 @@ void EditorResourcePicker::_update_menu_items() { for (int i = 0; i < conversions.size(); i++) { String what = conversions[i]->converts_to(); Ref<Texture2D> icon; - if (has_theme_icon(what, "EditorIcons")) { - icon = get_theme_icon(what, "EditorIcons"); + if (has_theme_icon(what, SNAME("EditorIcons"))) { + icon = get_theme_icon(what, SNAME("EditorIcons")); } else { - icon = get_theme_icon(what, "Resource"); + icon = get_theme_icon(what, SNAME("Resource")); } - edit_menu->add_icon_item(icon, vformat(TTR("Convert To %s"), what), CONVERT_BASE_ID + i); + edit_menu->add_icon_item(icon, vformat(TTR("Convert to %s"), what), CONVERT_BASE_ID + i); } } } @@ -220,8 +227,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } Set<String> valid_extensions; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - valid_extensions.insert(E->get()); + for (const String &E : extensions) { + valid_extensions.insert(E); } if (!file_dialog) { @@ -241,13 +248,13 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { case OBJ_MENU_EDIT: { if (edited_resource.is_valid()) { - emit_signal("resource_selected", edited_resource); + emit_signal(SNAME("resource_selected"), edited_resource); } } break; case OBJ_MENU_CLEAR: { edited_resource = RES(); - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; @@ -259,9 +266,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { List<PropertyInfo> property_list; edited_resource->get_property_list(&property_list); List<Pair<String, Variant>> propvalues; - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { + for (const PropertyInfo &pi : property_list) { Pair<String, Variant> p; - PropertyInfo &pi = E->get(); if (pi.usage & PROPERTY_USAGE_STORAGE) { p.first = pi.name; p.second = edited_resource->get(pi.name); @@ -271,17 +277,16 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } String orig_type = edited_resource->get_class(); - Object *inst = ClassDB::instance(orig_type); + Object *inst = ClassDB::instantiate(orig_type); Ref<Resource> unique_resource = Ref<Resource>(Object::cast_to<Resource>(inst)); ERR_FAIL_COND(unique_resource.is_null()); - for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { - Pair<String, Variant> &p = E->get(); + for (const Pair<String, Variant> &p : propvalues) { unique_resource->set(p.first, p.second); } edited_resource = unique_resource; - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; @@ -298,7 +303,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { case OBJ_MENU_PASTE: { edited_resource = EditorSettings::get_singleton()->get_resource_clipboard(); - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; @@ -323,7 +328,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { ERR_FAIL_INDEX(to_type, conversions.size()); edited_resource = conversions[to_type]->convert(edited_resource); - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); break; } @@ -334,7 +339,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Variant obj; if (ScriptServer::is_global_class(intype)) { - obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype)); + obj = ClassDB::instantiate(ScriptServer::get_global_class_native_base(intype)); if (obj) { Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); if (script.is_valid()) { @@ -342,7 +347,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { } } } else { - obj = ClassDB::instance(intype); + obj = ClassDB::instantiate(intype); } if (!obj) { @@ -353,16 +358,17 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { ERR_BREAK(!resp); edited_resource = RES(resp); - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } break; } } 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 (get_script_instance() && get_script_instance()->has_method("_set_create_options")) { + get_script_instance()->call("_set_create_options", p_menu_node); return; } @@ -395,14 +401,14 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) { } } - if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) { + if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instantiate(t))) { continue; } inheritors_array.push_back(t); if (!icon.is_valid()) { - icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); + icon = get_theme_icon(has_theme_icon(t, SNAME("EditorIcons")) ? t : String("Object"), SNAME("EditorIcons")); } int id = TYPE_BASE_ID + idx; @@ -418,8 +424,8 @@ 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); + if (get_script_instance() && get_script_instance()->has_method("_handle_menu_selected")) { + return get_script_instance()->call("_handle_menu_selected", p_which); } return false; @@ -427,7 +433,7 @@ bool EditorResourcePicker::handle_menu_selected(int p_which) { void EditorResourcePicker::_button_draw() { if (dropping) { - Color color = get_theme_color("accent_color", "Editor"); + Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); assign_button->draw_rect(Rect2(Point2(), assign_button->get_size()), color, false); } } @@ -462,17 +468,31 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> * String base = allowed_types[i].strip_edges(); p_vector->insert(base); - List<StringName> inheriters; + // If we hit a familiar base type, take all the data from cache. + if (allowed_types_cache.has(base)) { + List<StringName> allowed_subtypes = allowed_types_cache[base]; + for (const StringName &subtype_name : allowed_subtypes) { + p_vector->insert(subtype_name); + } + } else { + List<StringName> allowed_subtypes; - ClassDB::get_inheriters_from_class(base, &inheriters); - for (List<StringName>::Element *E = inheriters.front(); E; E = E->next()) { - p_vector->insert(E->get()); - } + List<StringName> inheriters; + ClassDB::get_inheriters_from_class(base, &inheriters); + for (const StringName &subtype_name : inheriters) { + p_vector->insert(subtype_name); + allowed_subtypes.push_back(subtype_name); + } - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base)) { - p_vector->insert(E->get()); + for (const StringName &subtype_name : global_classes) { + if (EditorNode::get_editor_data().script_class_is_parent(subtype_name, base)) { + p_vector->insert(subtype_name); + allowed_subtypes.push_back(subtype_name); + } } + + // Store the subtypes of the base type in the cache for future use. + allowed_types_cache[base] = allowed_subtypes; } if (p_with_convert) { @@ -505,7 +525,9 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { Ref<Resource> res; if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); - res = se->get_edited_resource(); + if (se) { + res = se->get_edited_resource(); + } } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { res = drag_data["resource"]; } @@ -571,7 +593,9 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ Ref<Resource> dropped_resource; if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); - dropped_resource = se->get_edited_resource(); + if (se) { + dropped_resource = se->get_edited_resource(); + } } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { dropped_resource = drag_data["resource"]; } @@ -618,16 +642,16 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ } edited_resource = dropped_resource; - emit_signal("resource_changed", edited_resource); + emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); } } void EditorResourcePicker::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_resource_preview"), &EditorResourcePicker::_update_resource_preview); - ClassDB::bind_method(D_METHOD("get_drag_data_fw", "position", "from"), &EditorResourcePicker::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw", "position", "data", "from"), &EditorResourcePicker::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw", "position", "data", "from"), &EditorResourcePicker::drop_data_fw); + ClassDB::bind_method(D_METHOD("_get_drag_data_fw", "position", "from"), &EditorResourcePicker::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("_can_drop_data_fw", "position", "data", "from"), &EditorResourcePicker::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("_drop_data_fw", "position", "data", "from"), &EditorResourcePicker::drop_data_fw); ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &EditorResourcePicker::set_base_type); ClassDB::bind_method(D_METHOD("get_base_type"), &EditorResourcePicker::get_base_type); @@ -640,11 +664,11 @@ 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"))); + 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"))); 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", 0), "set_edited_resource", "get_edited_resource"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource", PROPERTY_USAGE_NONE), "set_edited_resource", "get_edited_resource"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); @@ -659,11 +683,11 @@ void EditorResourcePicker::_notification(int p_what) { [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - edit_button->set_icon(get_theme_icon("select_arrow", "Tree")); + edit_button->set_icon(get_theme_icon(SNAME("select_arrow"), SNAME("Tree"))); } break; case NOTIFICATION_DRAW: { - draw_style_box(get_theme_stylebox("bg", "Tree"), Rect2(Point2(), get_size())); + draw_style_box(get_theme_stylebox(SNAME("bg"), SNAME("Tree")), Rect2(Point2(), get_size())); } break; case NOTIFICATION_DRAG_BEGIN: { @@ -702,6 +726,10 @@ void EditorResourcePicker::set_base_type(const String &p_base_type) { String class_str = (custom_class == StringName() ? edited_resource->get_class() : vformat("%s (%s)", custom_class, edited_resource->get_class())); WARN_PRINT(vformat("Value mismatch between the new base type of this EditorResourcePicker, '%s', and the type of the value it already has, '%s'.", base_type, class_str)); } + } else { + // Call the method to build the cache immediately. + Set<String> allowed_types; + _get_allowed_types(false, &allowed_types); } } @@ -783,6 +811,15 @@ bool EditorResourcePicker::is_editable() const { return editable; } +void EditorResourcePicker::_ensure_resource_menu() { + if (edit_menu) { + return; + } + edit_menu = memnew(PopupMenu); + add_child(edit_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); @@ -808,20 +845,18 @@ EditorResourcePicker::EditorResourcePicker() { edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu)); add_child(edit_button); edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); - edit_menu = memnew(PopupMenu); - add_child(edit_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)); } +// EditorScriptPicker + void EditorScriptPicker::set_create_options(Object *p_menu_node) { PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node); if (!menu_node) { return; } - menu_node->add_icon_item(get_theme_icon("ScriptCreate", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); - menu_node->add_icon_item(get_theme_icon("ScriptExtend", "EditorIcons"), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); + 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); menu_node->add_separator(); } @@ -857,8 +892,47 @@ void EditorScriptPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_script_owner", "owner_node"), &EditorScriptPicker::set_script_owner); ClassDB::bind_method(D_METHOD("get_script_owner"), &EditorScriptPicker::get_script_owner); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "script_owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_script_owner", "get_script_owner"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "script_owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_script_owner", "get_script_owner"); } EditorScriptPicker::EditorScriptPicker() { } + +// EditorShaderPicker + +void EditorShaderPicker::set_create_options(Object *p_menu_node) { + PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node); + if (!menu_node) { + return; + } + + menu_node->add_icon_item(get_theme_icon("Shader", "EditorIcons"), TTR("New Shader"), OBJ_MENU_NEW_SHADER); + menu_node->add_separator(); +} + +bool EditorShaderPicker::handle_menu_selected(int p_which) { + Ref<ShaderMaterial> material = Ref<ShaderMaterial>(get_edited_material()); + + switch (p_which) { + case OBJ_MENU_NEW_SHADER: { + if (material.is_valid()) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_shader_dialog(material); + return true; + } + } break; + default: + break; + } + return false; +} + +void EditorShaderPicker::set_edited_material(ShaderMaterial *p_material) { + edited_material = p_material; +} + +ShaderMaterial *EditorShaderPicker::get_edited_material() const { + return edited_material; +} + +EditorShaderPicker::EditorShaderPicker() { +} |