From 472cdb6da2e901d3f144f182434d24cb1c2c29af Mon Sep 17 00:00:00 2001 From: Robert Yevdokimov <105675984+ryevdokimov@users.noreply.github.com> Date: Thu, 9 Jan 2025 20:55:20 -0500 Subject: [PATCH 001/159] Add movement threshold before activating viewport rotation gizmo dragging --- editor/plugins/node_3d_editor_plugin.cpp | 5 ++++- editor/plugins/node_3d_editor_plugin.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 082d9c346e..80104cd5cc 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -424,7 +424,9 @@ void ViewportRotationControl::_process_click(int p_index, Vector2 p_position, bo } void ViewportRotationControl::_process_drag(Ref p_event, int p_index, Vector2 p_position, Vector2 p_relative_position) { - if (orbiting_index == p_index && gizmo_activated) { + Point2 mouse_pos = get_local_mouse_position(); + const bool movement_threshold_passed = original_mouse_pos.distance_to(mouse_pos) > 4 * EDSCALE; + if (orbiting_index == p_index && gizmo_activated && movement_threshold_passed) { if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_VISIBLE) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); orbiting_mouse_start = p_position; @@ -459,6 +461,7 @@ void ViewportRotationControl::gui_input(const Ref &p_event) { _process_click(100, mb->get_position(), mb->is_pressed()); if (mb->is_pressed()) { gizmo_activated = true; + original_mouse_pos = get_local_mouse_position(); grab_focus(); } } else if (mb->get_button_index() == MouseButton::RIGHT) { diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 27c709fb06..d445706404 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -83,6 +83,7 @@ class ViewportRotationControl : public Control { Vector axis_colors; Vector axis_menu_options; Vector2i orbiting_mouse_start; + Point2 original_mouse_pos; int orbiting_index = -1; int focused_axis = -2; bool gizmo_activated = false; From 2550cdc0c47612aa42c892083044c5c738aed8e3 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Wed, 12 Feb 2025 19:29:30 +0100 Subject: [PATCH 002/159] [.NET] Skip serializing delegates with a disposed target When reloading assemblies, we serialize the managed delegates so we can recreate the callables later. If the delegate's target is a GodotObject that has already been disposed, we can't serialize the delegate. Before this change, trying to serialize one of these delegates throws an exception and prevents releasing its strong GCHandle, so the assembly can't be unloaded. With this change, we don't serialize the delegates and release them anyway. This means some delegates may get lost on reloading assemblies, but if their target was already freed it's probably fine. --- modules/mono/csharp_script.cpp | 10 ++++++++-- .../glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 76c3ca3cb3..963974a0ed 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -690,8 +690,14 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { if (success) { ManagedCallable::instances_pending_reload.insert(managed_callable, serialized_data); - } else if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print("Failed to serialize delegate\n"); + } else { + if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Failed to serialize delegate.\n"); + } + + // We failed to serialize the delegate but we still have to release it; + // otherwise, we won't be able to unload the assembly. + managed_callable->release_delegate_handle(); } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index 7a88fea5f1..227bceacd7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -166,6 +166,12 @@ namespace Godot } case GodotObject godotObject: { + if (!GodotObject.IsInstanceValid(godotObject)) + { + // If the delegate's target has been freed we can't serialize it. + return false; + } + using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { From 8922a2f5a34946e5bb7c586a3417b6da004248d3 Mon Sep 17 00:00:00 2001 From: Micky Date: Wed, 5 Mar 2025 13:23:46 +0100 Subject: [PATCH 003/159] Reorder properties in NoiseTexture2D/3D --- modules/noise/noise_texture_2d.cpp | 44 +++++++++++++++--------------- modules/noise/noise_texture_3d.cpp | 36 ++++++++++++------------ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/modules/noise/noise_texture_2d.cpp b/modules/noise/noise_texture_2d.cpp index b55b1141e1..657b30a35a 100644 --- a/modules/noise/noise_texture_2d.cpp +++ b/modules/noise/noise_texture_2d.cpp @@ -52,48 +52,48 @@ void NoiseTexture2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture2D::set_width); ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture2D::set_height); + ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "invert"), &NoiseTexture2D::set_generate_mipmaps); + ClassDB::bind_method(D_METHOD("is_generating_mipmaps"), &NoiseTexture2D::is_generating_mipmaps); + + ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture2D::set_noise); + ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture2D::get_noise); + + ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture2D::set_color_ramp); + ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture2D::get_color_ramp); + + ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture2D::set_seamless); + ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture2D::get_seamless); + ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture2D::set_invert); ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture2D::get_invert); ClassDB::bind_method(D_METHOD("set_in_3d_space", "enable"), &NoiseTexture2D::set_in_3d_space); ClassDB::bind_method(D_METHOD("is_in_3d_space"), &NoiseTexture2D::is_in_3d_space); - ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "invert"), &NoiseTexture2D::set_generate_mipmaps); - ClassDB::bind_method(D_METHOD("is_generating_mipmaps"), &NoiseTexture2D::is_generating_mipmaps); - - ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture2D::set_seamless); - ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture2D::get_seamless); - - ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture2D::set_seamless_blend_skirt); - ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture2D::get_seamless_blend_skirt); - ClassDB::bind_method(D_METHOD("set_as_normal_map", "as_normal_map"), &NoiseTexture2D::set_as_normal_map); ClassDB::bind_method(D_METHOD("is_normal_map"), &NoiseTexture2D::is_normal_map); - ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture2D::set_bump_strength); - ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture2D::get_bump_strength); - ClassDB::bind_method(D_METHOD("set_normalize", "normalize"), &NoiseTexture2D::set_normalize); ClassDB::bind_method(D_METHOD("is_normalized"), &NoiseTexture2D::is_normalized); - ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture2D::set_color_ramp); - ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture2D::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture2D::set_seamless_blend_skirt); + ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture2D::get_seamless_blend_skirt); - ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture2D::set_noise); - ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture2D::get_noise); + ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture2D::set_bump_strength); + ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture2D::get_bump_strength); ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "is_generating_mipmaps"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert"), "set_invert", "get_invert"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "in_3d_space"), "set_in_3d_space", "is_in_3d_space"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "is_generating_mipmaps"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normal_map"), "set_as_normal_map", "is_normal_map"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize"), "set_normalize", "is_normalized"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength"); } void NoiseTexture2D::_validate_property(PropertyInfo &p_property) const { diff --git a/modules/noise/noise_texture_3d.cpp b/modules/noise/noise_texture_3d.cpp index e3cca8a09f..fb1c5130ca 100644 --- a/modules/noise/noise_texture_3d.cpp +++ b/modules/noise/noise_texture_3d.cpp @@ -53,33 +53,33 @@ void NoiseTexture3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture3D::set_height); ClassDB::bind_method(D_METHOD("set_depth", "depth"), &NoiseTexture3D::set_depth); - ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture3D::set_invert); - ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture3D::get_invert); - - ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture3D::set_seamless); - ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture3D::get_seamless); - - ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture3D::set_seamless_blend_skirt); - ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture3D::get_seamless_blend_skirt); - - ClassDB::bind_method(D_METHOD("set_normalize", "normalize"), &NoiseTexture3D::set_normalize); - ClassDB::bind_method(D_METHOD("is_normalized"), &NoiseTexture3D::is_normalized); + ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture3D::set_noise); + ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture3D::get_noise); ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture3D::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture3D::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture3D::set_noise); - ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture3D::get_noise); + ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture3D::set_seamless); + ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture3D::get_seamless); + + ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture3D::set_invert); + ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture3D::get_invert); + + ClassDB::bind_method(D_METHOD("set_normalize", "normalize"), &NoiseTexture3D::set_normalize); + ClassDB::bind_method(D_METHOD("is_normalized"), &NoiseTexture3D::is_normalized); + + ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture3D::set_seamless_blend_skirt); + ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture3D::get_seamless_blend_skirt); ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_depth", "get_depth"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert"), "set_invert", "get_invert"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0.05,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize"), "set_normalize", "is_normalized"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert"), "set_invert", "get_invert"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize"), "set_normalize", "is_normalized"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0.05,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt"); } void NoiseTexture3D::_validate_property(PropertyInfo &p_property) const { From f180e8a79ddf7d8971c71d6a3c55a7d092a9bbf9 Mon Sep 17 00:00:00 2001 From: yesfish Date: Wed, 12 Mar 2025 13:18:36 +0000 Subject: [PATCH 004/159] Add named placeholder to blender import options --- .../gltf/editor/editor_scene_importer_blend.cpp | 17 ++++++++++++----- .../gltf/editor/editor_scene_importer_blend.h | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index c9540220bf..f75e35b128 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -175,10 +175,17 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ } if (p_options.has(SNAME("blender/materials/export_materials"))) { int32_t exports = p_options["blender/materials/export_materials"]; - if (exports == BLEND_MATERIAL_EXPORT_PLACEHOLDER) { - parameters_map["export_materials"] = "PLACEHOLDER"; - } else if (exports == BLEND_MATERIAL_EXPORT_EXPORT) { - parameters_map["export_materials"] = "EXPORT"; + switch (exports) { + case BLEND_MATERIAL_EXPORT_PLACEHOLDER: { + parameters_map["export_materials"] = "PLACEHOLDER"; + } break; + case BLEND_MATERIAL_EXPORT_EXPORT: { + parameters_map["export_materials"] = "EXPORT"; + } break; + case BLEND_MATERIAL_EXPORT_NAMED_PLACEHOLDER: { + parameters_map["export_materials"] = "EXPORT"; + parameters_map["export_image_format"] = "NONE"; + } break; } } else { parameters_map["export_materials"] = "PLACEHOLDER"; @@ -367,7 +374,7 @@ void EditorSceneFormatImporterBlend::get_import_options(const String &p_path, Li ADD_OPTION_ENUM("blender/meshes/skins", "None,4 Influences (Compatible),All Influences", BLEND_BONE_INFLUENCES_ALL); ADD_OPTION_BOOL("blender/meshes/export_bones_deforming_mesh_only", false); ADD_OPTION_BOOL("blender/materials/unpack_enabled", true); - ADD_OPTION_ENUM("blender/materials/export_materials", "Placeholder,Export", BLEND_MATERIAL_EXPORT_EXPORT); + ADD_OPTION_ENUM("blender/materials/export_materials", "Placeholder,Export,Named Placeholder", BLEND_MATERIAL_EXPORT_EXPORT); ADD_OPTION_BOOL("blender/animation/limit_playback", true); ADD_OPTION_BOOL("blender/animation/always_sample", true); ADD_OPTION_BOOL("blender/animation/group_tracks", true); diff --git a/modules/gltf/editor/editor_scene_importer_blend.h b/modules/gltf/editor/editor_scene_importer_blend.h index 4a26d8d55f..956fc64d46 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.h +++ b/modules/gltf/editor/editor_scene_importer_blend.h @@ -59,7 +59,8 @@ public: }; enum { BLEND_MATERIAL_EXPORT_PLACEHOLDER, - BLEND_MATERIAL_EXPORT_EXPORT + BLEND_MATERIAL_EXPORT_EXPORT, + BLEND_MATERIAL_EXPORT_NAMED_PLACEHOLDER, }; enum { BLEND_MODIFIERS_NONE, From 49d4168f3039b12df95e6a55ca45dfb19c615ace Mon Sep 17 00:00:00 2001 From: kobewi Date: Tue, 18 Feb 2025 21:47:51 +0100 Subject: [PATCH 005/159] Better explain texture repeat --- doc/classes/CanvasItem.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 3e80ef2895..9072fd8c0e 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -638,7 +638,8 @@ The filtering mode used to render this [CanvasItem]'s texture(s). - The repeating mode used to render this [CanvasItem]'s texture(s). + The repeating mode used to render this [CanvasItem]'s texture(s). It affects what happens when the texture is sampled outside its extents, for example by setting a [member Sprite2D.region_rect] that is larger than the texture or assigning [Polygon2D] UV points outside the texture. + [b]Note:[/b] [TextureRect] is not affected by [member texture_repeat], as it uses its own texture repeating implementation. If [code]true[/code], this [CanvasItem] will [i]not[/i] inherit its transform from parent [CanvasItem]s. Its draw order will also be changed to make it draw on top of other [CanvasItem]s that do not have [member top_level] set to [code]true[/code]. The [CanvasItem] will effectively act as if it was placed as a child of a bare [Node]. @@ -748,7 +749,7 @@ The [CanvasItem] will inherit the filter from its parent. - The texture does not repeat. + The texture does not repeat. Sampling the texture outside its extents will result in "stretching" of the edge pixels. You can avoid this by ensuring a 1-pixel fully transparent border on each side of the texture. The texture repeats when exceeding the texture's size. From d10e578a5da67bb61f9c1684cd017f8043e37632 Mon Sep 17 00:00:00 2001 From: RedMser Date: Sun, 23 Mar 2025 22:20:19 +0100 Subject: [PATCH 006/159] Clarify that custom_action is only triggered if action is non-empty --- doc/classes/AcceptDialog.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml index 198429831e..179bd7ac05 100644 --- a/doc/classes/AcceptDialog.xml +++ b/doc/classes/AcceptDialog.xml @@ -15,7 +15,8 @@ - Adds a button with label [param text] and a custom [param action] to the dialog and returns the created button. [param action] will be passed to the [signal custom_action] signal when pressed. + Adds a button with label [param text] and a custom [param action] to the dialog and returns the created button. + If [param action] is not empty, pressing the button will emit the [signal custom_action] signal with the specified action string. If [code]true[/code], [param right] will place the button to the right of any sibling buttons. You can use [method remove_button] method to remove a button created with this method from the dialog. @@ -95,7 +96,7 @@ - Emitted when a custom button is pressed. See [method add_button]. + Emitted when a custom button with an action is pressed. See [method add_button]. From e9edff8d25c5240b369102f033aefb571743df91 Mon Sep 17 00:00:00 2001 From: Kasper Arnklit Frandsen Date: Thu, 24 Apr 2025 17:16:27 +0100 Subject: [PATCH 007/159] Fix scale from cursor in Animation Player --- editor/animation_track_editor.cpp | 14 ++++++++------ editor/animation_track_editor.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 1fe82aa2d0..fe39819a7f 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -6538,7 +6538,6 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeli } void AnimationTrackEditor::_edit_menu_pressed(int p_option) { - last_menu_track_opt = p_option; switch (p_option) { case EDIT_COPY_TRACKS: { track_copy_select->clear(); @@ -6698,11 +6697,15 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { undo_redo->commit_action(); } break; - - case EDIT_SCALE_SELECTION: + case EDIT_SCALE_SELECTION: { + scale_dialog->popup_centered(Size2(200, 100) * EDSCALE); + scale->get_line_edit()->grab_focus(); + scale_from_cursor = false; + } break; case EDIT_SCALE_FROM_CURSOR: { scale_dialog->popup_centered(Size2(200, 100) * EDSCALE); scale->get_line_edit()->grab_focus(); + scale_from_cursor = true; } break; case EDIT_SCALE_CONFIRM: { if (selection.is_empty()) { @@ -6725,9 +6728,8 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } len = to_t - from_t; - if (last_menu_track_opt == EDIT_SCALE_FROM_CURSOR) { + if (scale_from_cursor) { pivot = timeline->get_play_position(); - } else { pivot = from_t; } @@ -6769,7 +6771,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { to_restore.push_back(amr); } -#define NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * Math::abs(s) + from_t +#define NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * Math::abs(s) + pivot // 3 - Move the keys (re insert them). for (RBMap::Element *E = selection.back(); E; E = E->prev()) { float newpos = NEW_POS(E->get().pos); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index fa6a143f5a..86d42d8742 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -789,7 +789,7 @@ class AnimationTrackEditor : public VBoxContainer { void _edit_menu_about_to_popup(); void _edit_menu_pressed(int p_option); - int last_menu_track_opt = 0; + bool scale_from_cursor = false; void _cleanup_animation(Ref p_animation); From 0a07ae7bf162584a3de570f69d714c3ae93f16f4 Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Fri, 2 May 2025 19:22:05 +0300 Subject: [PATCH 008/159] Editor: Fix documentation for built-in scripts --- editor/connections_dialog.cpp | 2 +- editor/editor_file_system.cpp | 25 +++++++++++++++++- editor/editor_help.cpp | 29 +++++++++++++++++---- editor/plugins/script_editor_plugin.cpp | 34 ++++++++++++------------- scene/resources/packed_scene.cpp | 12 +++++++++ scene/resources/packed_scene.h | 1 + 6 files changed, 79 insertions(+), 24 deletions(-) diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 8b2cc6f94a..01d957cc9f 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -924,7 +924,7 @@ ConnectDialog::~ConnectDialog() { Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const { // If it's not a doc tooltip, fallback to the default one. - if (p_text.is_empty() || p_text.contains("::")) { + if (p_text.is_empty() || p_text.contains(" :: ")) { return nullptr; } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 5f48d34f6c..9af4836cf5 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1385,7 +1385,7 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir, void EditorFileSystem::_process_removed_files(const HashSet &p_processed_files) { for (const KeyValue &kv : file_cache) { if (!p_processed_files.has(kv.key)) { - if (ClassDB::is_parent_class(kv.value.type, SNAME("Script"))) { + if (ClassDB::is_parent_class(kv.value.type, SNAME("Script")) || ClassDB::is_parent_class(kv.value.type, SNAME("PackedScene"))) { // A script has been removed from disk since the last startup. The documentation needs to be updated. // There's no need to add the path in update_script_paths since that is exclusively for updating global class names, // which is handled in _first_scan_filesystem before the full scan to ensure plugins and autoloads can be created. @@ -2195,6 +2195,29 @@ void EditorFileSystem::_update_script_documentation() { continue; } + if (path.ends_with(".tscn")) { + Ref packed_scene = ResourceLoader::load(path); + if (packed_scene.is_valid()) { + Ref state = packed_scene->get_state(); + if (state.is_valid()) { + Vector> sub_resources = state->get_sub_resources(); + for (Ref sub_resource : sub_resources) { + Ref