feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -33,12 +33,12 @@
#include "editor/audio_stream_preview.h"
#include "editor/editor_help.h"
#include "editor/editor_node.h"
#include "editor/editor_quick_open.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"
#include "editor/filesystem_dock.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/gui/editor_quick_open_dialog.h"
#include "editor/plugins/editor_resource_conversion_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/scene_tree_dock.h"
@ -61,11 +61,11 @@ void EditorResourcePicker::_update_resource() {
assign_button->set_custom_minimum_size(assign_button_min_size);
if (edited_resource == Ref<Resource>()) {
assign_button->set_icon(Ref<Texture2D>());
assign_button->set_button_icon(Ref<Texture2D>());
assign_button->set_text(TTR("<empty>"));
assign_button->set_tooltip_text("");
} else {
assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), SNAME("Object")));
assign_button->set_button_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), SNAME("Object")));
if (!edited_resource->get_name().is_empty()) {
assign_button->set_text(edited_resource->get_name());
@ -87,11 +87,11 @@ void EditorResourcePicker::_update_resource() {
assign_button->set_tooltip_text(resource_path + TTR("Type:") + " " + edited_resource->get_class());
}
assign_button->set_disabled(!editable && !edited_resource.is_valid());
assign_button->set_disabled(!editable && edited_resource.is_null());
}
void EditorResourcePicker::_update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj) {
if (!edited_resource.is_valid() || edited_resource->get_instance_id() != p_obj) {
if (edited_resource.is_null() || edited_resource->get_instance_id() != p_obj) {
return;
}
@ -103,7 +103,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(CoreStringName(normal))->get_content_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button")));
preview_rect->set_offset(SIDE_LEFT, assign_button->get_button_icon()->get_width() + assign_button->get_theme_stylebox(CoreStringName(normal))->get_content_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button")));
// Resource-specific stretching.
if (Ref<GradientTexture1D>(edited_resource).is_valid() || Ref<Gradient>(edited_resource).is_valid()) {
@ -132,6 +132,11 @@ void EditorResourcePicker::_resource_selected() {
emit_signal(SNAME("resource_selected"), edited_resource, false);
}
void EditorResourcePicker::_resource_changed() {
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
}
void EditorResourcePicker::_file_selected(const String &p_path) {
Ref<Resource> loaded_resource = ResourceLoader::load(p_path);
ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'.");
@ -167,12 +172,14 @@ void EditorResourcePicker::_file_selected(const String &p_path) {
}
edited_resource = loaded_resource;
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
}
void EditorResourcePicker::_file_quick_selected() {
_file_selected(quick_open->get_selected());
void EditorResourcePicker::_resource_saved(Object *p_resource) {
if (edited_resource.is_valid() && p_resource == edited_resource.ptr()) {
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
}
}
void EditorResourcePicker::_update_menu() {
@ -217,7 +224,9 @@ void EditorResourcePicker::_update_menu_items() {
}
if (is_editable()) {
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Clear")), TTR("Clear"), OBJ_MENU_CLEAR);
if (!_is_custom_type_script()) {
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Clear")), TTR("Clear"), OBJ_MENU_CLEAR);
}
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
// Check whether the resource has subresources.
@ -279,20 +288,22 @@ void EditorResourcePicker::_update_menu_items() {
// Add options to convert existing resource to another type of resource.
if (is_editable() && edited_resource.is_valid()) {
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(edited_resource);
if (conversions.size()) {
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin_for_resource(edited_resource);
if (!conversions.is_empty()) {
edit_menu->add_separator();
}
for (int i = 0; i < conversions.size(); i++) {
String what = conversions[i]->converts_to();
int relative_id = 0;
for (const Ref<EditorResourceConversionPlugin> &conversion : conversions) {
String what = conversion->converts_to();
Ref<Texture2D> icon;
if (has_theme_icon(what, EditorStringName(EditorIcons))) {
icon = get_editor_theme_icon(what);
} else {
icon = get_theme_icon(what, SNAME("Resource"));
icon = get_editor_theme_icon(SNAME("Object"));
}
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 + relative_id);
relative_id++;
}
}
}
@ -330,14 +341,14 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
} break;
case OBJ_MENU_QUICKLOAD: {
if (!quick_open) {
quick_open = memnew(EditorQuickOpen);
add_child(quick_open);
quick_open->connect("quick_open", callable_mp(this, &EditorResourcePicker::_file_quick_selected));
const Vector<String> &base_types_string = base_type.split(",");
Vector<StringName> base_types;
for (const String &type : base_types_string) {
base_types.push_back(type);
}
quick_open->popup_dialog(base_type);
quick_open->set_title(TTR("Resource"));
EditorNode::get_singleton()->get_quick_open_dialog()->popup_dialog(base_types, callable_mp(this, &EditorResourcePicker::_file_selected));
} break;
case OBJ_MENU_INSPECT: {
@ -348,8 +359,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
case OBJ_MENU_CLEAR: {
edited_resource = Ref<Resource>();
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
} break;
case OBJ_MENU_MAKE_UNIQUE: {
@ -361,8 +371,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
ERR_FAIL_COND(unique_resource.is_null()); // duplicate() may fail.
edited_resource = unique_resource;
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
} break;
case OBJ_MENU_MAKE_UNIQUE_RECURSIVE: {
@ -408,6 +417,10 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
if (edited_resource.is_null()) {
return;
}
Callable resource_saved = callable_mp(this, &EditorResourcePicker::_resource_saved);
if (!EditorNode::get_singleton()->is_connected("resource_saved", resource_saved)) {
EditorNode::get_singleton()->connect("resource_saved", resource_saved);
}
EditorNode::get_singleton()->save_resource_as(edited_resource);
} break;
@ -423,9 +436,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
_edit_menu_cbk(OBJ_MENU_MAKE_UNIQUE);
return;
}
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
} break;
case OBJ_MENU_SHOW_IN_FILE_SYSTEM: {
@ -440,12 +451,11 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
if (p_which >= CONVERT_BASE_ID) {
int to_type = p_which - CONVERT_BASE_ID;
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(edited_resource);
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin_for_resource(edited_resource);
ERR_FAIL_INDEX(to_type, conversions.size());
edited_resource = conversions[to_type]->convert(edited_resource);
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
break;
}
@ -472,8 +482,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
// Prevent freeing of the object until the end of the update of the resource (GH-88286).
Ref<Resource> old_edited_resource = edited_resource;
edited_resource = Ref<Resource>(resp);
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
} break;
}
}
@ -569,9 +578,9 @@ String EditorResourcePicker::_get_resource_type(const Ref<Resource> &p_resource)
return res_type;
}
static void _add_allowed_type(const StringName &p_type, HashSet<StringName> *p_vector) {
if (p_vector->has(p_type)) {
// Already added
static void _add_allowed_type(const StringName &p_type, List<StringName> *p_vector) {
if (p_vector->find(p_type)) {
// Already added.
return;
}
@ -579,7 +588,7 @@ static void _add_allowed_type(const StringName &p_type, HashSet<StringName> *p_v
// Engine class,
if (!ClassDB::is_virtual(p_type)) {
p_vector->insert(p_type);
p_vector->push_back(p_type);
}
List<StringName> inheriters;
@ -589,7 +598,7 @@ static void _add_allowed_type(const StringName &p_type, HashSet<StringName> *p_v
}
} else {
// Script class.
p_vector->insert(p_type);
p_vector->push_back(p_type);
}
List<StringName> inheriters;
@ -604,12 +613,22 @@ void EditorResourcePicker::_ensure_allowed_types() const {
return;
}
List<StringName> final_allowed;
Vector<String> allowed_types = base_type.split(",");
int size = allowed_types.size();
for (int i = 0; i < size; i++) {
const String base = allowed_types[i].strip_edges();
_add_allowed_type(base, &allowed_types_without_convert);
for (const String &S : allowed_types) {
const String base = S.strip_edges();
if (base.begins_with("-")) {
final_allowed.erase(base.right(-1));
continue;
}
_add_allowed_type(base, &final_allowed);
}
for (const StringName &SN : final_allowed) {
allowed_types_without_convert.insert(SN);
}
allowed_types_with_convert = HashSet<StringName>(allowed_types_without_convert);
@ -618,9 +637,9 @@ void EditorResourcePicker::_ensure_allowed_types() const {
const String base = allowed_types[i].strip_edges();
if (base == "BaseMaterial3D") {
allowed_types_with_convert.insert("Texture2D");
} else if (base == "ShaderMaterial") {
} else if (ClassDB::is_parent_class("ShaderMaterial", base)) {
allowed_types_with_convert.insert("Shader");
} else if (base == "Texture2D") {
} else if (ClassDB::is_parent_class("ImageTexture", base)) {
allowed_types_with_convert.insert("Image");
}
}
@ -687,6 +706,16 @@ bool EditorResourcePicker::_is_type_valid(const String &p_type_name, const HashS
return false;
}
bool EditorResourcePicker::_is_custom_type_script() const {
Ref<Script> resource_as_script = edited_resource;
if (resource_as_script.is_valid() && resource_owner && resource_owner->has_meta(SceneStringName(_custom_type_script))) {
return true;
}
return false;
}
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);
@ -716,7 +745,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
dropped_resource = drag_data["resource"];
}
if (!dropped_resource.is_valid() && drag_data.has("type") && String(drag_data["type"]) == "files") {
if (dropped_resource.is_null() && drag_data.has("type") && String(drag_data["type"]) == "files") {
Vector<String> files = drag_data["files"];
if (files.size() == 1) {
@ -738,7 +767,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
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()) {
if (mat.is_null()) {
mat.instantiate();
}
mat->set_texture(StandardMaterial3D::TextureParam::TEXTURE_ALBEDO, dropped_resource);
@ -748,7 +777,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
if (at == "ShaderMaterial" && Ref<Shader>(dropped_resource).is_valid()) {
Ref<ShaderMaterial> mat = edited_resource;
if (!mat.is_valid()) {
if (mat.is_null()) {
mat.instantiate();
}
mat->set_shader(dropped_resource);
@ -758,7 +787,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
if (at == "ImageTexture" && Ref<Image>(dropped_resource).is_valid()) {
Ref<ImageTexture> texture = edited_resource;
if (!texture.is_valid()) {
if (texture.is_null()) {
texture.instantiate();
}
texture->set_image(dropped_resource);
@ -769,8 +798,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
}
edited_resource = dropped_resource;
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
}
}
@ -813,7 +841,7 @@ void EditorResourcePicker::_notification(int p_what) {
edit_menu->add_theme_constant_override("icon_max_width", icon_width);
}
edit_button->set_icon(get_theme_icon(SNAME("select_arrow"), SNAME("Tree")));
edit_button->set_button_icon(get_theme_icon(SNAME("select_arrow"), SNAME("Tree")));
} break;
case NOTIFICATION_DRAW: {
@ -833,6 +861,13 @@ void EditorResourcePicker::_notification(int p_what) {
assign_button->queue_redraw();
}
} break;
case NOTIFICATION_EXIT_TREE: {
Callable resource_saved = callable_mp(this, &EditorResourcePicker::_resource_saved);
if (EditorNode::get_singleton()->is_connected("resource_saved", resource_saved)) {
EditorNode::get_singleton()->disconnect("resource_saved", resource_saved);
}
} break;
}
}
@ -886,7 +921,7 @@ Vector<String> EditorResourcePicker::get_allowed_types() const {
}
void EditorResourcePicker::set_edited_resource(Ref<Resource> p_resource) {
if (!p_resource.is_valid()) {
if (p_resource.is_null()) {
edited_resource = Ref<Resource>();
_update_resource();
return;
@ -936,9 +971,17 @@ void EditorResourcePicker::set_toggle_pressed(bool p_pressed) {
assign_button->set_pressed(p_pressed);
}
bool EditorResourcePicker::is_toggle_pressed() const {
return assign_button->is_pressed();
}
void EditorResourcePicker::set_resource_owner(Object *p_object) {
resource_owner = p_object;
}
void EditorResourcePicker::set_editable(bool p_editable) {
editable = p_editable;
assign_button->set_disabled(!editable && !edited_resource.is_valid());
assign_button->set_disabled(!editable && edited_resource.is_null());
edit_button->set_visible(editable);
}
@ -1030,8 +1073,7 @@ void EditorResourcePicker::_duplicate_selected_resources() {
if (meta.size() == 1) { // Root.
edited_resource = unique_resource;
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
_resource_changed();
} else {
Array parent_meta = item->get_parent()->get_metadata(0);
Ref<Resource> parent = parent_meta[0];
@ -1067,6 +1109,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
edit_button = memnew(Button);
edit_button->set_flat(false);
edit_button->set_toggle_mode(true);
edit_button->set_action_mode(BaseButton::ACTION_MODE_BUTTON_PRESS);
edit_button->connect(SceneStringName(pressed), callable_mp(this, &EditorResourcePicker::_update_menu));
add_child(edit_button);
edit_button->connect(SceneStringName(gui_input), callable_mp(this, &EditorResourcePicker::_button_input));
@ -1082,7 +1125,10 @@ void EditorScriptPicker::set_create_options(Object *p_menu_node) {
return;
}
menu_node->add_icon_item(get_editor_theme_icon(SNAME("ScriptCreate")), TTR("New Script..."), OBJ_MENU_NEW_SCRIPT);
if (!(script_owner && script_owner->has_meta(SceneStringName(_custom_type_script)))) {
menu_node->add_icon_item(get_editor_theme_icon(SNAME("ScriptCreate")), TTR("New Script..."), OBJ_MENU_NEW_SCRIPT);
}
if (script_owner) {
Ref<Script> scr = script_owner->get_script();
if (scr.is_valid()) {
@ -1251,7 +1297,7 @@ void EditorAudioStreamPicker::_update_resource() {
void EditorAudioStreamPicker::_preview_draw() {
Ref<AudioStream> audio_stream = get_edited_resource();
if (!audio_stream.is_valid()) {
if (audio_stream.is_null()) {
get_assign_button()->set_text(TTR("<empty>"));
return;
}
@ -1324,7 +1370,7 @@ void EditorAudioStreamPicker::_preview_draw() {
}
stream_preview_rect->draw_texture(icon, Point2i(EDSCALE * 4, rect.position.y + (rect.size.height - icon->get_height()) / 2), icon_modulate);
stream_preview_rect->draw_string(font, Point2i(EDSCALE * 4 + icon->get_width(), rect.position.y + font->get_ascent(font_size) + (rect.size.height - font->get_height(font_size)) / 2), text, HORIZONTAL_ALIGNMENT_CENTER, size.width - 4 * EDSCALE - icon->get_width(), font_size, get_theme_color(SNAME("font_color"), EditorStringName(Editor)));
stream_preview_rect->draw_string(font, Point2i(EDSCALE * 4 + icon->get_width(), rect.position.y + font->get_ascent(font_size) + (rect.size.height - font->get_height(font_size)) / 2), text, HORIZONTAL_ALIGNMENT_CENTER, size.width - 4 * EDSCALE - icon->get_width(), font_size, get_theme_color(SceneStringName(font_color), EditorStringName(Editor)));
}
EditorAudioStreamPicker::EditorAudioStreamPicker() :