summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite_2d.cpp19
-rw-r--r--scene/2d/audio_stream_player_2d.cpp5
-rw-r--r--scene/2d/camera_2d.cpp4
-rw-r--r--scene/2d/cpu_particles_2d.cpp3
-rw-r--r--scene/2d/gpu_particles_2d.cpp3
-rw-r--r--scene/2d/mesh_instance_2d.cpp4
-rw-r--r--scene/2d/multimesh_instance_2d.cpp4
-rw-r--r--scene/2d/navigation_agent_2d.cpp2
-rw-r--r--scene/2d/navigation_region_2d.cpp178
-rw-r--r--scene/2d/navigation_region_2d.h6
-rw-r--r--scene/2d/physics/area_2d.cpp75
-rw-r--r--scene/2d/physics/collision_object_2d.cpp11
-rw-r--r--scene/2d/physics/joints/joint_2d.cpp13
-rw-r--r--scene/2d/physics/rigid_body_2d.cpp32
-rw-r--r--scene/2d/sprite_2d.cpp5
-rw-r--r--scene/2d/tile_map.cpp97
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/2d/tile_map_layer.cpp137
-rw-r--r--scene/2d/tile_map_layer.h4
-rw-r--r--scene/2d/touch_screen_button.cpp15
-rw-r--r--scene/2d/visible_on_screen_notifier_2d.cpp6
-rw-r--r--scene/3d/bone_attachment_3d.cpp4
-rw-r--r--scene/3d/cpu_particles_3d.cpp5
-rw-r--r--scene/3d/gpu_particles_3d.cpp3
-rw-r--r--scene/3d/label_3d.cpp1
-rw-r--r--scene/3d/lightmap_gi.cpp17
-rw-r--r--scene/3d/lightmap_gi.h4
-rw-r--r--scene/3d/lightmapper.h2
-rw-r--r--scene/3d/navigation_agent_3d.cpp2
-rw-r--r--scene/3d/navigation_region_3d.cpp4
-rw-r--r--scene/3d/node_3d.cpp15
-rw-r--r--scene/3d/physical_bone_simulator_3d.cpp8
-rw-r--r--scene/3d/physics/area_3d.cpp79
-rw-r--r--scene/3d/physics/area_3d.h5
-rw-r--r--scene/3d/physics/collision_object_3d.cpp7
-rw-r--r--scene/3d/physics/joints/cone_twist_joint_3d.cpp2
-rw-r--r--scene/3d/physics/joints/joint_3d.cpp14
-rw-r--r--scene/3d/physics/joints/slider_joint_3d.cpp2
-rw-r--r--scene/3d/physics/rigid_body_3d.cpp32
-rw-r--r--scene/3d/skeleton_3d.cpp20
-rw-r--r--scene/3d/skeleton_modifier_3d.cpp3
-rw-r--r--scene/3d/skeleton_modifier_3d.h1
-rw-r--r--scene/3d/sprite_3d.cpp27
-rw-r--r--scene/3d/visible_on_screen_notifier_3d.cpp6
-rw-r--r--scene/3d/visual_instance_3d.cpp11
-rw-r--r--scene/3d/voxel_gi.cpp1
-rw-r--r--scene/animation/animation_blend_tree.cpp27
-rw-r--r--scene/animation/animation_mixer.cpp53
-rw-r--r--scene/animation/animation_mixer.h6
-rw-r--r--scene/animation/animation_player.cpp15
-rw-r--r--scene/animation/animation_tree.cpp7
-rw-r--r--scene/animation/tween.cpp10
-rw-r--r--scene/audio/audio_stream_player_internal.cpp7
-rw-r--r--scene/gui/base_button.cpp9
-rw-r--r--scene/gui/box_container.cpp4
-rw-r--r--scene/gui/button.cpp117
-rw-r--r--scene/gui/button.h12
-rw-r--r--scene/gui/check_box.cpp8
-rw-r--r--scene/gui/check_button.cpp8
-rw-r--r--scene/gui/code_edit.cpp2
-rw-r--r--scene/gui/color_picker.cpp50
-rw-r--r--scene/gui/container.cpp18
-rw-r--r--scene/gui/control.cpp41
-rw-r--r--scene/gui/dialogs.cpp44
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp11
-rw-r--r--scene/gui/graph_edit.cpp85
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/graph_node.cpp13
-rw-r--r--scene/gui/graph_node.h5
-rw-r--r--scene/gui/item_list.cpp3
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/margin_container.cpp4
-rw-r--r--scene/gui/menu_button.cpp1
-rw-r--r--scene/gui/nine_patch_rect.cpp3
-rw-r--r--scene/gui/option_button.cpp3
-rw-r--r--scene/gui/popup.cpp20
-rw-r--r--scene/gui/popup_menu.cpp10
-rw-r--r--scene/gui/range.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp31
-rw-r--r--scene/gui/scroll_bar.cpp18
-rw-r--r--scene/gui/spin_box.cpp6
-rw-r--r--scene/gui/split_container.cpp22
-rw-r--r--scene/gui/split_container.h3
-rw-r--r--scene/gui/subviewport_container.cpp2
-rw-r--r--scene/gui/tab_bar.cpp3
-rw-r--r--scene/gui/tab_container.cpp6
-rw-r--r--scene/gui/text_edit.cpp139
-rw-r--r--scene/gui/texture_button.cpp31
-rw-r--r--scene/gui/tree.cpp28
-rw-r--r--scene/gui/tree.h1
-rw-r--r--scene/gui/video_stream_player.cpp5
-rw-r--r--scene/main/canvas_item.compat.inc24
-rw-r--r--scene/main/canvas_item.cpp47
-rw-r--r--scene/main/canvas_item.h14
-rw-r--r--scene/main/canvas_layer.cpp2
-rw-r--r--scene/main/instance_placeholder.cpp131
-rw-r--r--scene/main/instance_placeholder.h4
-rw-r--r--scene/main/node.cpp130
-rw-r--r--scene/main/node.h3
-rw-r--r--scene/main/scene_tree.cpp3
-rw-r--r--scene/main/shader_globals_override.cpp13
-rw-r--r--scene/main/status_indicator.cpp2
-rw-r--r--scene/main/viewport.cpp5
-rw-r--r--scene/main/window.cpp52
-rw-r--r--scene/main/window.h2
-rw-r--r--scene/property_list_helper.cpp26
-rw-r--r--scene/property_list_helper.h7
-rw-r--r--scene/register_scene_types.cpp4
-rw-r--r--scene/resources/2d/tile_set.cpp56
-rw-r--r--scene/resources/3d/world_3d.cpp1
-rw-r--r--scene/resources/animation.cpp1
-rw-r--r--scene/resources/animation_library.cpp4
-rw-r--r--scene/resources/atlas_texture.cpp2
-rw-r--r--scene/resources/canvas_item_material.cpp26
-rw-r--r--scene/resources/canvas_item_material.h3
-rw-r--r--scene/resources/curve_texture.cpp2
-rw-r--r--scene/resources/gradient_texture.cpp3
-rw-r--r--scene/resources/material.cpp58
-rw-r--r--scene/resources/material.h4
-rw-r--r--scene/resources/packed_scene.cpp13
-rw-r--r--scene/resources/particle_process_material.cpp43
-rw-r--r--scene/resources/particle_process_material.h3
-rw-r--r--scene/resources/portable_compressed_texture.cpp6
-rw-r--r--scene/resources/resource_format_text.cpp322
-rw-r--r--scene/resources/resource_format_text.h8
-rw-r--r--scene/resources/shader.cpp5
-rw-r--r--scene/resources/sprite_frames.cpp2
-rw-r--r--scene/resources/visual_shader.cpp98
-rw-r--r--scene/resources/visual_shader.h4
-rw-r--r--scene/resources/visual_shader_nodes.cpp79
-rw-r--r--scene/resources/visual_shader_nodes.h31
-rw-r--r--scene/scene_string_names.cpp89
-rw-r--r--scene/scene_string_names.h86
-rw-r--r--scene/theme/SCsub1
-rw-r--r--scene/theme/default_theme.cpp23
-rw-r--r--scene/theme/icons/SCsub1
-rw-r--r--scene/theme/theme_db.cpp6
-rw-r--r--scene/theme/theme_owner.cpp12
139 files changed, 1737 insertions, 1527 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 37e9d1f8c1..6d380aed3c 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -31,7 +31,6 @@
#include "animated_sprite_2d.h"
#include "scene/main/viewport.h"
-#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
Dictionary AnimatedSprite2D::_edit_get_state() const {
@@ -202,7 +201,7 @@ void AnimatedSprite2D::_notification(int p_what) {
} else {
frame = last_frame;
pause();
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal(SceneStringName(animation_finished));
return;
}
} else {
@@ -211,7 +210,7 @@ void AnimatedSprite2D::_notification(int p_what) {
_calc_frame_speed_scale();
frame_progress = 0.0;
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining);
frame_progress += to_process * abs_speed;
@@ -226,7 +225,7 @@ void AnimatedSprite2D::_notification(int p_what) {
} else {
frame = 0;
pause();
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal(SceneStringName(animation_finished));
return;
}
} else {
@@ -235,7 +234,7 @@ void AnimatedSprite2D::_notification(int p_what) {
_calc_frame_speed_scale();
frame_progress = 1.0;
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
double to_process = MIN(frame_progress / abs_speed, remaining);
frame_progress -= to_process * abs_speed;
@@ -291,12 +290,12 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
}
if (frames.is_valid()) {
- frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed));
+ frames->disconnect(CoreStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed));
}
stop();
frames = p_frames;
if (frames.is_valid()) {
- frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed));
+ frames->connect(CoreStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed));
List<StringName> al;
frames->get_animation_list(&al);
@@ -363,7 +362,7 @@ void AnimatedSprite2D::set_frame_and_progress(int p_frame, real_t p_progress) {
return; // No change, don't redraw.
}
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
void AnimatedSprite2D::set_speed_scale(float p_speed_scale) {
@@ -482,7 +481,7 @@ void AnimatedSprite2D::play(const StringName &p_name, float p_custom_scale, bool
} else {
set_frame_and_progress(0, 0.0);
}
- emit_signal("animation_changed");
+ emit_signal(SceneStringName(animation_changed));
} else {
bool is_backward = signbit(speed_scale * custom_speed_scale);
if (p_from_end && is_backward && frame == 0 && frame_progress <= 0.0) {
@@ -537,7 +536,7 @@ void AnimatedSprite2D::set_animation(const StringName &p_name) {
animation = p_name;
- emit_signal("animation_changed");
+ emit_signal(SceneStringName(animation_changed));
if (frames == nullptr) {
animation = StringName();
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 4fc0fe0268..f88db0e3f4 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -37,7 +37,6 @@
#include "scene/audio/audio_stream_player_internal.h"
#include "scene/main/viewport.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
#include "servers/audio_server.h"
@@ -81,10 +80,10 @@ StringName AudioStreamPlayer2D::_get_actual_bus() {
//check if any area is diverting sound into a bus
Ref<World2D> world_2d = get_world_2d();
- ERR_FAIL_COND_V(world_2d.is_null(), SceneStringNames::get_singleton()->Master);
+ ERR_FAIL_COND_V(world_2d.is_null(), SceneStringName(Master));
PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space());
- ERR_FAIL_NULL_V(space_state, SceneStringNames::get_singleton()->Master);
+ ERR_FAIL_NULL_V(space_state, SceneStringName(Master));
PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS];
PhysicsDirectSpaceState2D::PointParameters point_params;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 822f1b58fd..18ef2d8505 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -54,16 +54,18 @@ void Camera2D::_update_scroll() {
if (is_current()) {
ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id));
+ Size2 screen_size = _get_camera_screen_size();
+
Transform2D xform;
if (is_physics_interpolated_and_enabled()) {
xform = _interpolation_data.xform_prev.interpolate_with(_interpolation_data.xform_curr, Engine::get_singleton()->get_physics_interpolation_fraction());
+ camera_screen_center = xform.affine_inverse().xform(0.5 * screen_size);
} else {
xform = get_camera_transform();
}
viewport->set_canvas_transform(xform);
- Size2 screen_size = _get_camera_screen_size();
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5) : Point2());
Point2 adj_screen_pos = camera_screen_center - (screen_size * 0.5);
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 2cd59776ec..9c9ba93b41 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -35,7 +35,6 @@
#include "scene/resources/curve_texture.h"
#include "scene/resources/gradient_texture.h"
#include "scene/resources/particle_process_material.h"
-#include "scene/scene_string_names.h"
void CPUParticles2D::set_emitting(bool p_emitting) {
if (emitting == p_emitting) {
@@ -997,7 +996,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
}
if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) {
active = false;
- emit_signal(SceneStringNames::get_singleton()->finished);
+ emit_signal(SceneStringName(finished));
}
}
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index bc39513c03..1d3f1ceada 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -35,7 +35,6 @@
#include "scene/resources/curve_texture.h"
#include "scene/resources/gradient_texture.h"
#include "scene/resources/particle_process_material.h"
-#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
#include "core/config/engine.h"
@@ -731,7 +730,7 @@ void GPUParticles2D::_notification(int p_what) {
}
if (time > active_time) {
if (active && !signal_canceled) {
- emit_signal(SceneStringNames::get_singleton()->finished);
+ emit_signal(SceneStringName(finished));
}
active = false;
if (!emitting) {
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 4fc375ff8d..ae45d431fe 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -30,8 +30,6 @@
#include "mesh_instance_2d.h"
-#include "scene/scene_string_names.h"
-
void MeshInstance2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
@@ -70,7 +68,7 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
}
texture = p_texture;
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
+ emit_signal(SceneStringName(texture_changed));
}
Ref<Texture2D> MeshInstance2D::get_texture() const {
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index 9631b2cc4e..417e628517 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -30,8 +30,6 @@
#include "multimesh_instance_2d.h"
-#include "scene/scene_string_names.h"
-
void MultiMeshInstance2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
@@ -79,7 +77,7 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
}
texture = p_texture;
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
+ emit_signal(SceneStringName(texture_changed));
}
Ref<Texture2D> MultiMeshInstance2D::get_texture() const {
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 5d14358120..9e3e6ea583 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -796,7 +796,7 @@ void NavigationAgent2D::_trigger_waypoint_reached() {
Dictionary details;
const Vector2 waypoint = navigation_path[navigation_path_index];
- details[SNAME("position")] = waypoint;
+ details[CoreStringName(position)] = waypoint;
int waypoint_type = -1;
if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) {
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index ab44e57d05..bad9de5daa 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -162,8 +162,19 @@ void NavigationRegion2D::_notification(int p_what) {
set_physics_process_internal(true);
} break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+#ifdef DEBUG_ENABLED
+ if (debug_instance_rid.is_valid()) {
+ RS::get_singleton()->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
+ }
+#endif // DEBUG_ENABLED
+ } break;
+
case NOTIFICATION_EXIT_TREE: {
_region_exit_navigation_map();
+#ifdef DEBUG_ENABLED
+ _free_debug();
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -189,6 +200,9 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
}
navigation_polygon = p_navigation_polygon;
+#ifdef DEBUG_ENABLED
+ debug_mesh_dirty = true;
+#endif // DEBUG_ENABLED
NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
if (navigation_polygon.is_valid()) {
@@ -420,12 +434,42 @@ void NavigationRegion2D::_region_update_transform() {
#ifdef DEBUG_ENABLED
void NavigationRegion2D::_update_debug_mesh() {
- Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
- if (navigation_polygon_vertices.size() < 3) {
+ if (!is_inside_tree()) {
+ _free_debug();
return;
}
const NavigationServer2D *ns2d = NavigationServer2D::get_singleton();
+ RenderingServer *rs = RenderingServer::get_singleton();
+
+ if (!debug_instance_rid.is_valid()) {
+ debug_instance_rid = rs->canvas_item_create();
+ }
+ if (!debug_mesh_rid.is_valid()) {
+ debug_mesh_rid = rs->mesh_create();
+ }
+
+ const Transform2D region_gt = get_global_transform();
+
+ rs->canvas_item_set_parent(debug_instance_rid, get_world_2d()->get_canvas());
+ rs->canvas_item_set_transform(debug_instance_rid, region_gt);
+
+ if (!debug_mesh_dirty) {
+ return;
+ }
+
+ rs->mesh_clear(debug_mesh_rid);
+ debug_mesh_dirty = false;
+
+ const Vector<Vector2> &vertices = navigation_polygon->get_vertices();
+ if (vertices.size() < 3) {
+ return;
+ }
+
+ int polygon_count = navigation_polygon->get_polygon_count();
+ if (polygon_count == 0) {
+ return;
+ }
bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color();
bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines();
@@ -438,39 +482,109 @@ void NavigationRegion2D::_update_debug_mesh() {
debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color();
}
+ int vertex_count = 0;
+ int line_count = 0;
+
+ for (int i = 0; i < polygon_count; i++) {
+ const Vector<int> &polygon = navigation_polygon->get_polygon(i);
+ int polygon_size = polygon.size();
+ if (polygon_size < 3) {
+ continue;
+ }
+ line_count += polygon_size * 2;
+ vertex_count += (polygon_size - 2) * 3;
+ }
+
+ Vector<Vector2> face_vertex_array;
+ face_vertex_array.resize(vertex_count);
+
+ Vector<Color> face_color_array;
+ if (enabled_geometry_face_random_color) {
+ face_color_array.resize(vertex_count);
+ }
+
+ Vector<Vector2> line_vertex_array;
+ if (enabled_edge_lines) {
+ line_vertex_array.resize(line_count);
+ }
+
RandomPCG rand;
+ Color polygon_color = debug_face_color;
- for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) {
- // An array of vertices for this polygon.
- Vector<int> polygon = navigation_polygon->get_polygon(i);
- Vector<Vector2> debug_polygon_vertices;
- debug_polygon_vertices.resize(polygon.size());
- for (int j = 0; j < polygon.size(); j++) {
- ERR_FAIL_INDEX(polygon[j], navigation_polygon_vertices.size());
- debug_polygon_vertices.write[j] = navigation_polygon_vertices[polygon[j]];
+ int face_vertex_index = 0;
+ int line_vertex_index = 0;
+
+ Vector2 *face_vertex_array_ptrw = face_vertex_array.ptrw();
+ Color *face_color_array_ptrw = face_color_array.ptrw();
+ Vector2 *line_vertex_array_ptrw = line_vertex_array.ptrw();
+
+ for (int polygon_index = 0; polygon_index < polygon_count; polygon_index++) {
+ const Vector<int> &polygon_indices = navigation_polygon->get_polygon(polygon_index);
+ int polygon_indices_size = polygon_indices.size();
+ if (polygon_indices_size < 3) {
+ continue;
}
- // Generate the polygon color, slightly randomly modified from the settings one.
- Color random_variation_color = debug_face_color;
if (enabled_geometry_face_random_color) {
- random_variation_color.set_hsv(
- debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1,
- debug_face_color.get_s(),
- debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
+ // Generate the polygon color, slightly randomly modified from the settings one.
+ polygon_color.set_hsv(debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, debug_face_color.get_s(), debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
+ polygon_color.a = debug_face_color.a;
}
- random_variation_color.a = debug_face_color.a;
- Vector<Color> debug_face_colors;
- debug_face_colors.push_back(random_variation_color);
- RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_polygon_vertices, debug_face_colors);
+ for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size - 2; polygon_indices_index++) {
+ face_vertex_array_ptrw[face_vertex_index] = vertices[polygon_indices[0]];
+ face_vertex_array_ptrw[face_vertex_index + 1] = vertices[polygon_indices[polygon_indices_index + 1]];
+ face_vertex_array_ptrw[face_vertex_index + 2] = vertices[polygon_indices[polygon_indices_index + 2]];
+ if (enabled_geometry_face_random_color) {
+ face_color_array_ptrw[face_vertex_index] = polygon_color;
+ face_color_array_ptrw[face_vertex_index + 1] = polygon_color;
+ face_color_array_ptrw[face_vertex_index + 2] = polygon_color;
+ }
+ face_vertex_index += 3;
+ }
if (enabled_edge_lines) {
- Vector<Color> debug_edge_colors;
- debug_edge_colors.push_back(debug_edge_color);
- debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline.
- RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_polygon_vertices, debug_edge_colors);
+ for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size; polygon_indices_index++) {
+ line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index]];
+ line_vertex_index += 1;
+ if (polygon_indices_index + 1 == polygon_indices_size) {
+ line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[0]];
+ line_vertex_index += 1;
+ } else {
+ line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index + 1]];
+ line_vertex_index += 1;
+ }
+ }
}
}
+
+ if (!enabled_geometry_face_random_color) {
+ face_color_array.resize(face_vertex_array.size());
+ face_color_array.fill(debug_face_color);
+ }
+
+ Array face_mesh_array;
+ face_mesh_array.resize(Mesh::ARRAY_MAX);
+ face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array;
+ face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array;
+
+ rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_TRIANGLES, face_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
+
+ if (enabled_edge_lines) {
+ Vector<Color> line_color_array;
+ line_color_array.resize(line_vertex_array.size());
+ line_color_array.fill(debug_edge_color);
+
+ Array line_mesh_array;
+ line_mesh_array.resize(Mesh::ARRAY_MAX);
+ line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array;
+ line_mesh_array[Mesh::ARRAY_COLOR] = line_color_array;
+
+ rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_LINES, line_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
+ }
+
+ rs->canvas_item_add_mesh(debug_instance_rid, debug_mesh_rid, Transform2D());
+ rs->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
}
#endif // DEBUG_ENABLED
@@ -512,3 +626,19 @@ void NavigationRegion2D::_update_debug_baking_rect() {
}
}
#endif // DEBUG_ENABLED
+
+#ifdef DEBUG_ENABLED
+void NavigationRegion2D::_free_debug() {
+ RenderingServer *rs = RenderingServer::get_singleton();
+ ERR_FAIL_NULL(rs);
+ if (debug_instance_rid.is_valid()) {
+ rs->canvas_item_clear(debug_instance_rid);
+ rs->free(debug_instance_rid);
+ debug_instance_rid = RID();
+ }
+ if (debug_mesh_rid.is_valid()) {
+ rs->free(debug_mesh_rid);
+ debug_mesh_rid = RID();
+ }
+}
+#endif // DEBUG_ENABLED
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 5a86dd607d..52101cb93e 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -52,6 +52,12 @@ class NavigationRegion2D : public Node2D {
#ifdef DEBUG_ENABLED
private:
+ RID debug_mesh_rid;
+ RID debug_instance_rid;
+
+ bool debug_mesh_dirty = true;
+
+ void _free_debug();
void _update_debug_mesh();
void _update_debug_edge_connections_mesh();
void _update_debug_baking_rect();
diff --git a/scene/2d/physics/area_2d.cpp b/scene/2d/physics/area_2d.cpp
index b1ff94dda4..305ac8248e 100644
--- a/scene/2d/physics/area_2d.cpp
+++ b/scene/2d/physics/area_2d.cpp
@@ -30,7 +30,6 @@
#include "area_2d.h"
-#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
void Area2D::set_gravity_space_override_mode(SpaceOverride p_mode) {
@@ -142,9 +141,9 @@ void Area2D::_body_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(E->value.in_tree);
E->value.in_tree = true;
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
}
}
@@ -156,9 +155,9 @@ void Area2D::_body_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->value.in_tree);
E->value.in_tree = false;
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
}
}
@@ -172,9 +171,9 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
lock_callback();
locked = true;
if (body_in) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
} else {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
}
locked = false;
unlock_callback();
@@ -200,10 +199,10 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
E->value.rc = 0;
E->value.in_tree = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree).bind(objid));
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
}
}
}
@@ -213,7 +212,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
}
if (!node || E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape);
}
} else {
@@ -227,15 +226,15 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
if (E->value.rc == 0) {
body_map.remove(E);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree));
if (in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
+ emit_signal(SceneStringName(body_exited), obj);
}
}
}
if (!node || in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape);
}
}
@@ -253,9 +252,9 @@ void Area2D::_area_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(E->value.in_tree);
E->value.in_tree = true;
- emit_signal(SceneStringNames::get_singleton()->area_entered, node);
+ emit_signal(SceneStringName(area_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
}
}
@@ -267,9 +266,9 @@ void Area2D::_area_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->value.in_tree);
E->value.in_tree = false;
- emit_signal(SceneStringNames::get_singleton()->area_exited, node);
+ emit_signal(SceneStringName(area_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
}
}
@@ -283,9 +282,9 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
lock_callback();
locked = true;
if (area_in) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
} else {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
}
locked = false;
unlock_callback();
@@ -311,10 +310,10 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
E->value.rc = 0;
E->value.in_tree = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree).bind(objid));
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_entered, node);
+ emit_signal(SceneStringName(area_entered), node);
}
}
}
@@ -324,7 +323,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
}
if (!node || E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape);
}
} else {
@@ -338,15 +337,15 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
if (E->value.rc == 0) {
area_map.remove(E);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree));
if (in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
+ emit_signal(SceneStringName(area_exited), obj);
}
}
}
if (!node || in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape);
}
}
@@ -370,18 +369,18 @@ void Area2D::_clear_monitoring() {
continue;
}
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree));
if (!E.value.in_tree) {
continue;
}
for (int i = 0; i < E.value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
}
- emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
+ emit_signal(SceneStringName(body_exited), obj);
}
}
@@ -398,18 +397,18 @@ void Area2D::_clear_monitoring() {
continue;
}
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree));
if (!E.value.in_tree) {
continue;
}
for (int i = 0; i < E.value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
}
- emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
+ emit_signal(SceneStringName(area_exited), obj);
}
}
}
@@ -538,7 +537,7 @@ StringName Area2D::get_audio_bus_name() const {
return audio_bus;
}
}
- return SceneStringNames::get_singleton()->Master;
+ return SceneStringName(Master);
}
void Area2D::_validate_property(PropertyInfo &p_property) const {
diff --git a/scene/2d/physics/collision_object_2d.cpp b/scene/2d/physics/collision_object_2d.cpp
index 4e5852984b..00b6085f0c 100644
--- a/scene/2d/physics/collision_object_2d.cpp
+++ b/scene/2d/physics/collision_object_2d.cpp
@@ -31,7 +31,6 @@
#include "collision_object_2d.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
void CollisionObject2D::_notification(int p_what) {
switch (p_what) {
@@ -519,27 +518,27 @@ bool CollisionObject2D::is_pickable() const {
void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape);
- emit_signal(SceneStringNames::get_singleton()->input_event, p_viewport, p_input_event, p_shape);
+ emit_signal(SceneStringName(input_event), p_viewport, p_input_event, p_shape);
}
void CollisionObject2D::_mouse_enter() {
GDVIRTUAL_CALL(_mouse_enter);
- emit_signal(SceneStringNames::get_singleton()->mouse_entered);
+ emit_signal(SceneStringName(mouse_entered));
}
void CollisionObject2D::_mouse_exit() {
GDVIRTUAL_CALL(_mouse_exit);
- emit_signal(SceneStringNames::get_singleton()->mouse_exited);
+ emit_signal(SceneStringName(mouse_exited));
}
void CollisionObject2D::_mouse_shape_enter(int p_shape) {
GDVIRTUAL_CALL(_mouse_shape_enter, p_shape);
- emit_signal(SceneStringNames::get_singleton()->mouse_shape_entered, p_shape);
+ emit_signal(SceneStringName(mouse_shape_entered), p_shape);
}
void CollisionObject2D::_mouse_shape_exit(int p_shape) {
GDVIRTUAL_CALL(_mouse_shape_exit, p_shape);
- emit_signal(SceneStringNames::get_singleton()->mouse_shape_exited, p_shape);
+ emit_signal(SceneStringName(mouse_shape_exited), p_shape);
}
void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
diff --git a/scene/2d/physics/joints/joint_2d.cpp b/scene/2d/physics/joints/joint_2d.cpp
index 1afac7c150..a32bcbae78 100644
--- a/scene/2d/physics/joints/joint_2d.cpp
+++ b/scene/2d/physics/joints/joint_2d.cpp
@@ -31,19 +31,18 @@
#include "joint_2d.h"
#include "scene/2d/physics/physics_body_2d.h"
-#include "scene/scene_string_names.h"
void Joint2D::_disconnect_signals() {
Node *node_a = get_node_or_null(a);
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
if (body_a) {
- body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree));
}
Node *node_b = get_node_or_null(b);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (body_b) {
- body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree));
}
}
@@ -117,8 +116,12 @@ void Joint2D::_update_joint(bool p_only_free) {
ba = body_a->get_rid();
bb = body_b->get_rid();
- body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
- body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ if (!body_a->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree))) {
+ body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree));
+ }
+ if (!body_b->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree))) {
+ body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree));
+ }
PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}
diff --git a/scene/2d/physics/rigid_body_2d.cpp b/scene/2d/physics/rigid_body_2d.cpp
index 5e05c563a4..402e5c8b95 100644
--- a/scene/2d/physics/rigid_body_2d.cpp
+++ b/scene/2d/physics/rigid_body_2d.cpp
@@ -30,8 +30,6 @@
#include "rigid_body_2d.h"
-#include "scene/scene_string_names.h"
-
void RigidBody2D::_body_enter_tree(ObjectID p_id) {
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
@@ -44,10 +42,10 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) {
contact_monitor->locked = true;
E->value.in_scene = true;
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
+ emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
}
contact_monitor->locked = false;
@@ -65,10 +63,10 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) {
contact_monitor->locked = true;
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
+ emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
}
contact_monitor->locked = false;
@@ -93,10 +91,10 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
//E->value.rc=0;
E->value.in_scene = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid));
if (E->value.in_scene) {
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
}
}
@@ -108,7 +106,7 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
}
if (E->value.in_scene) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape);
}
} else {
@@ -122,17 +120,17 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
if (E->value.shapes.is_empty()) {
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree));
if (in_scene) {
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
}
}
contact_monitor->body_map.remove(E);
}
if (node && in_scene) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, node, p_body_shape, p_local_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, node, p_body_shape, p_local_shape);
}
}
}
@@ -158,7 +156,7 @@ void RigidBody2D::_sync_body_state(PhysicsDirectBodyState2D *p_state) {
if (sleeping != p_state->is_sleeping()) {
sleeping = p_state->is_sleeping();
- emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
+ emit_signal(SceneStringName(sleeping_state_changed));
}
}
@@ -605,8 +603,8 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
Node *node = Object::cast_to<Node>(obj);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree));
}
}
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index 5745a59297..efb5029ac4 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -31,7 +31,6 @@
#include "sprite_2d.h"
#include "scene/main/window.h"
-#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
Dictionary Sprite2D::_edit_get_state() const {
@@ -146,7 +145,7 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) {
}
queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
+ emit_signal(SceneStringName(texture_changed));
item_rect_changed();
}
@@ -260,7 +259,7 @@ void Sprite2D::set_frame(int p_frame) {
frame = p_frame;
item_rect_changed();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
int Sprite2D::get_frame() const {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 165d4d5a67..f7d672620d 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -31,7 +31,6 @@
#include "tile_map.h"
#include "tile_map.compat.inc"
-#include "core/core_string_names.h"
#include "core/io/marshalls.h"
#include "scene/gui/control.h"
@@ -54,7 +53,7 @@ void TileMap::_tile_set_changed() {
}
void TileMap::_emit_changed() {
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMap::_set_tile_map_data_using_compatibility_format(int p_layer, TileMapDataFormat p_format, const Vector<int> &p_data) {
@@ -226,91 +225,6 @@ int TileMap::get_rendering_quadrant_size() const {
return rendering_quadrant_size;
}
-void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
- ERR_FAIL_COND(!p_tile_set.is_valid());
- ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
- ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
- ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
- TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
- TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
- if (atlas_source) {
- // Check for the frame.
- if (p_frame >= 0) {
- ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
- }
-
- // Get the texture.
- Ref<Texture2D> tex = atlas_source->get_runtime_texture();
- if (!tex.is_valid()) {
- return;
- }
-
- // Check if we are in the texture, return otherwise.
- Vector2i grid_size = atlas_source->get_atlas_grid_size();
- if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
- return;
- }
-
- // Get tile data.
- const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
-
- // Get the tile modulation.
- Color modulate = tile_data->get_modulate() * p_modulation;
-
- // Compute the offset.
- Vector2 tile_offset = tile_data->get_texture_origin();
-
- // Get destination rect.
- Rect2 dest_rect;
- dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
- dest_rect.size.x += FP_ADJUST;
- dest_rect.size.y += FP_ADJUST;
-
- bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
- if (transpose) {
- dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
- } else {
- dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
- }
-
- if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
- dest_rect.size.x = -dest_rect.size.x;
- }
-
- if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
- dest_rect.size.y = -dest_rect.size.y;
- }
-
- // Draw the tile.
- if (p_frame >= 0) {
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
- } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
- } else {
- real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
- real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
- real_t animation_offset = p_normalized_animation_offset * animation_duration;
- // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
- // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
- real_t time_unscaled = 0.0;
- for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
- real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
- real_t slice_start = time_unscaled / speed;
- real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
- RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);
-
- Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
- tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
-
- time_unscaled += frame_duration_unscaled;
- }
- RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
- }
- }
-}
-
void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
if (p_tileset == tile_set) {
return;
@@ -360,7 +274,7 @@ void TileMap::add_layer(int p_to_pos) {
for (uint32_t i = 0; i < layers.size(); i++) {
layers[i]->set_as_tile_map_internal_node(i);
}
- new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
+ new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed));
notify_property_list_changed();
@@ -768,7 +682,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
new_layer->set_as_tile_map_internal_node(index);
new_layer->set_name(vformat("Layer%d", index));
new_layer->set_tile_set(tile_set);
- new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
+ new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed));
layers.push_back(new_layer);
}
@@ -1051,7 +965,7 @@ void TileMap::_bind_methods() {
ADD_PROPERTY_DEFAULT("format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1);
- ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed));
+ ADD_SIGNAL(MethodInfo(CoreStringName(changed)));
BIND_ENUM_CONSTANT(VISIBILITY_MODE_DEFAULT);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_HIDE);
@@ -1064,7 +978,7 @@ TileMap::TileMap() {
new_layer->set_as_tile_map_internal_node(0);
new_layer->set_name("Layer0");
new_layer->set_tile_set(tile_set);
- new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
+ new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed));
layers.push_back(new_layer);
if (!base_property_helper.is_initialized()) {
@@ -1073,6 +987,7 @@ TileMap::TileMap() {
TileMapLayer *defaults = memnew(TileMapLayer);
base_property_helper.set_prefix("layer_");
+ base_property_helper.set_array_length_getter(&TileMap::get_layers_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults->get_name(), &TileMap::set_layer_name, &TileMap::get_layer_name);
base_property_helper.register_property(PropertyInfo(Variant::BOOL, "enabled"), defaults->is_enabled(), &TileMap::set_layer_enabled, &TileMap::is_layer_enabled);
base_property_helper.register_property(PropertyInfo(Variant::COLOR, "modulate"), defaults->get_modulate(), &TileMap::set_layer_modulate, &TileMap::get_layer_modulate);
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 45604bfb8a..690102f730 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -63,8 +63,6 @@ private:
// A compatibility enum to specify how is the data if formatted.
mutable TileMapDataFormat format = TileMapDataFormat::TILE_MAP_DATA_FORMAT_3;
- static constexpr float FP_ADJUST = 0.00001;
-
// Properties.
Ref<TileSet> tile_set;
int rendering_quadrant_size = 16;
@@ -123,8 +121,6 @@ public:
void set_rendering_quadrant_size(int p_size);
int get_rendering_quadrant_size() const;
- static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);
-
// Accessors.
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp
index fd1a638b58..0ac236eaa7 100644
--- a/scene/2d/tile_map_layer.cpp
+++ b/scene/2d/tile_map_layer.cpp
@@ -30,7 +30,6 @@
#include "tile_map_layer.h"
-#include "core/core_string_names.h"
#include "core/io/marshalls.h"
#include "scene/2d/tile_map.h"
#include "scene/gui/control.h"
@@ -341,7 +340,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
}
// Drawing the tile in the canvas item.
- TileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
+ draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
}
// Reset physics interpolation for any recreated canvas items.
@@ -604,6 +603,7 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid());
rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index));
+ rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index));
} else {
// Clear occluder.
if (occluder.is_valid()) {
@@ -1598,11 +1598,11 @@ RBSet<TerrainConstraint> TileMapLayer::_get_terrain_constraints_from_painted_cel
void TileMapLayer::_tile_set_changed() {
dirty.flags[DIRTY_FLAGS_TILE_SET] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::_renamed() {
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::_update_notify_local_transform() {
@@ -1696,18 +1696,18 @@ void TileMapLayer::_notification(int p_what) {
_internal_update(true);
} break;
- case TileMap::NOTIFICATION_ENTER_CANVAS: {
+ case NOTIFICATION_ENTER_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
_queue_internal_update();
} break;
- case TileMap::NOTIFICATION_EXIT_CANVAS: {
+ case NOTIFICATION_EXIT_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
// Update immediately on exiting, and force cleanup.
_internal_update(true);
} break;
- case TileMap::NOTIFICATION_VISIBILITY_CHANGED: {
+ case NOTIFICATION_VISIBILITY_CHANGED: {
dirty.flags[DIRTY_FLAGS_LAYER_VISIBILITY] = true;
_queue_internal_update();
} break;
@@ -1805,7 +1805,7 @@ void TileMapLayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "navigation_enabled"), "set_navigation_enabled", "is_navigation_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode");
- ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed));
+ ADD_SIGNAL(MethodInfo(CoreStringName(changed)));
ADD_PROPERTY_DEFAULT("tile_map_data_format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1);
@@ -1819,7 +1819,7 @@ void TileMapLayer::_update_self_texture_filter(RS::CanvasItemTextureFilter p_tex
CanvasItem::_update_self_texture_filter(p_texture_filter);
dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat) {
@@ -1827,7 +1827,7 @@ void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_tex
CanvasItem::_update_self_texture_repeat(p_texture_repeat);
dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::set_as_tile_map_internal_node(int p_index) {
@@ -2162,6 +2162,91 @@ TileMapCell TileMapLayer::get_cell(const Vector2i &p_coords) const {
}
}
+void TileMapLayer::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
+ ERR_FAIL_COND(p_tile_set.is_null());
+ ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
+ ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
+ ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
+ TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ // Check for the frame.
+ if (p_frame >= 0) {
+ ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
+ }
+
+ // Get the texture.
+ Ref<Texture2D> tex = atlas_source->get_runtime_texture();
+ if (tex.is_null()) {
+ return;
+ }
+
+ // Check if we are in the texture, return otherwise.
+ Vector2i grid_size = atlas_source->get_atlas_grid_size();
+ if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
+ return;
+ }
+
+ // Get tile data.
+ const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
+
+ // Get the tile modulation.
+ Color modulate = tile_data->get_modulate() * p_modulation;
+
+ // Compute the offset.
+ Vector2 tile_offset = tile_data->get_texture_origin();
+
+ // Get destination rect.
+ Rect2 dest_rect;
+ dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
+ dest_rect.size.x += FP_ADJUST;
+ dest_rect.size.y += FP_ADJUST;
+
+ bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
+ if (transpose) {
+ dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
+ } else {
+ dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
+ }
+
+ if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
+ dest_rect.size.x = -dest_rect.size.x;
+ }
+
+ if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
+ dest_rect.size.y = -dest_rect.size.y;
+ }
+
+ // Draw the tile.
+ if (p_frame >= 0) {
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+ } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+ } else {
+ real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
+ real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
+ real_t animation_offset = p_normalized_animation_offset * animation_duration;
+ // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
+ // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
+ real_t time_unscaled = 0.0;
+ for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
+ real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
+ real_t slice_start = time_unscaled / speed;
+ real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
+ RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);
+
+ Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
+ tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
+
+ time_unscaled += frame_duration_unscaled;
+ }
+ RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
+ }
+ }
+}
+
void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile) {
// Set the current cell tile (using integer position).
Vector2i pk(p_coords);
@@ -2212,7 +2297,7 @@ void TileMapLayer::erase_cell(const Vector2i &p_coords) {
}
void TileMapLayer::fix_invalid_tiles() {
- ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet.");
+ ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMapLayer without a valid TileSet.");
RBSet<Vector2i> coords;
for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) {
@@ -2502,7 +2587,7 @@ void TileMapLayer::update_internals() {
void TileMapLayer::notify_runtime_tile_data_update() {
dirty.flags[TileMapLayer::DIRTY_FLAGS_LAYER_RUNTIME_UPDATE] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
Vector2i TileMapLayer::map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern) {
@@ -2537,7 +2622,7 @@ void TileMapLayer::set_enabled(bool p_enabled) {
enabled = p_enabled;
dirty.flags[DIRTY_FLAGS_LAYER_ENABLED] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
bool TileMapLayer::is_enabled() const {
@@ -2563,7 +2648,7 @@ void TileMapLayer::set_tile_set(const Ref<TileSet> &p_tile_set) {
tile_set->connect_changed(callable_mp(this, &TileMapLayer::_tile_set_changed));
}
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
// Trigger updates for TileSet's read-only status.
notify_property_list_changed();
@@ -2675,7 +2760,7 @@ void TileMapLayer::set_self_modulate(const Color &p_self_modulate) {
CanvasItem::set_self_modulate(p_self_modulate);
dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) {
@@ -2685,7 +2770,7 @@ void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) {
CanvasItem::set_y_sort_enabled(p_y_sort_enabled);
dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
_update_notify_local_transform();
}
@@ -2697,7 +2782,7 @@ void TileMapLayer::set_y_sort_origin(int p_y_sort_origin) {
y_sort_origin = p_y_sort_origin;
dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
int TileMapLayer::get_y_sort_origin() const {
@@ -2711,7 +2796,7 @@ void TileMapLayer::set_z_index(int p_z_index) {
CanvasItem::set_z_index(p_z_index);
dirty.flags[DIRTY_FLAGS_LAYER_Z_INDEX] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::set_light_mask(int p_light_mask) {
@@ -2721,7 +2806,7 @@ void TileMapLayer::set_light_mask(int p_light_mask) {
CanvasItem::set_light_mask(p_light_mask);
dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
void TileMapLayer::set_rendering_quadrant_size(int p_size) {
@@ -2733,7 +2818,7 @@ void TileMapLayer::set_rendering_quadrant_size(int p_size) {
rendering_quadrant_size = p_size;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
int TileMapLayer::get_rendering_quadrant_size() const {
@@ -2747,7 +2832,7 @@ void TileMapLayer::set_collision_enabled(bool p_enabled) {
collision_enabled = p_enabled;
dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_ENABLED] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
bool TileMapLayer::is_collision_enabled() const {
@@ -2758,7 +2843,7 @@ void TileMapLayer::set_use_kinematic_bodies(bool p_use_kinematic_bodies) {
use_kinematic_bodies = p_use_kinematic_bodies;
dirty.flags[DIRTY_FLAGS_LAYER_USE_KINEMATIC_BODIES] = p_use_kinematic_bodies;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
bool TileMapLayer::is_using_kinematic_bodies() const {
@@ -2772,7 +2857,7 @@ void TileMapLayer::set_collision_visibility_mode(TileMapLayer::DebugVisibilityMo
collision_visibility_mode = p_show_collision;
dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_VISIBILITY_MODE] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
TileMapLayer::DebugVisibilityMode TileMapLayer::get_collision_visibility_mode() const {
@@ -2786,7 +2871,7 @@ void TileMapLayer::set_navigation_enabled(bool p_enabled) {
navigation_enabled = p_enabled;
dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_ENABLED] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
bool TileMapLayer::is_navigation_enabled() const {
@@ -2800,7 +2885,7 @@ void TileMapLayer::set_navigation_map(RID p_map) {
navigation_map_override = p_map;
dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_MAP] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
RID TileMapLayer::get_navigation_map() const {
@@ -2819,7 +2904,7 @@ void TileMapLayer::set_navigation_visibility_mode(TileMapLayer::DebugVisibilityM
navigation_visibility_mode = p_show_navigation;
dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE] = true;
_queue_internal_update();
- emit_signal(CoreStringNames::get_singleton()->changed);
+ emit_signal(CoreStringName(changed));
}
TileMapLayer::DebugVisibilityMode TileMapLayer::get_navigation_visibility_mode() const {
diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h
index 5861433c8a..57c83d7c4c 100644
--- a/scene/2d/tile_map_layer.h
+++ b/scene/2d/tile_map_layer.h
@@ -269,6 +269,8 @@ public:
};
private:
+ static constexpr float FP_ADJUST = 0.00001;
+
// Properties.
HashMap<Vector2i, CellData> tile_map_layer_data;
@@ -407,6 +409,8 @@ public:
// Not exposed to users.
TileMapCell get_cell(const Vector2i &p_coords) const;
+ static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);
+
////////////// Exposed functions //////////////
// --- Cells manipulation ---
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 5ed7fadb2a..ff409272c5 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -31,18 +31,17 @@
#include "touch_screen_button.h"
#include "scene/main/window.h"
-#include "scene/scene_string_names.h"
void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) {
if (texture_normal == p_texture) {
return;
}
if (texture_normal.is_valid()) {
- texture_normal->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
+ texture_normal->disconnect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
}
texture_normal = p_texture;
if (texture_normal.is_valid()) {
- texture_normal->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED);
+ texture_normal->connect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED);
}
queue_redraw();
}
@@ -56,11 +55,11 @@ void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pres
return;
}
if (texture_pressed.is_valid()) {
- texture_pressed->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
+ texture_pressed->disconnect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
}
texture_pressed = p_texture_pressed;
if (texture_pressed.is_valid()) {
- texture_pressed->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED);
+ texture_pressed->connect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED);
}
queue_redraw();
}
@@ -306,7 +305,7 @@ void TouchScreenButton::_press(int p_finger_pressed) {
get_viewport()->push_input(iea, true);
}
- emit_signal(SNAME("pressed"));
+ emit_signal(SceneStringName(pressed));
queue_redraw();
}
@@ -371,10 +370,10 @@ bool TouchScreenButton::is_passby_press_enabled() const {
#ifndef DISABLE_DEPRECATED
bool TouchScreenButton::_set(const StringName &p_name, const Variant &p_value) {
- if (p_name == SNAME("normal")) { // Compatibility with Godot 3.x.
+ if (p_name == CoreStringName(normal)) { // Compatibility with Godot 3.x.
set_texture_normal(p_value);
return true;
- } else if (p_name == SNAME("pressed")) { // Compatibility with Godot 3.x.
+ } else if (p_name == SceneStringName(pressed)) { // Compatibility with Godot 3.x.
set_texture_pressed(p_value);
return true;
}
diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp
index 89b2c20b20..c64507fe32 100644
--- a/scene/2d/visible_on_screen_notifier_2d.cpp
+++ b/scene/2d/visible_on_screen_notifier_2d.cpp
@@ -30,8 +30,6 @@
#include "visible_on_screen_notifier_2d.h"
-#include "scene/scene_string_names.h"
-
#ifdef TOOLS_ENABLED
Rect2 VisibleOnScreenNotifier2D::_edit_get_rect() const {
return rect;
@@ -48,7 +46,7 @@ void VisibleOnScreenNotifier2D::_visibility_enter() {
}
on_screen = true;
- emit_signal(SceneStringNames::get_singleton()->screen_entered);
+ emit_signal(SceneStringName(screen_entered));
_screen_enter();
}
void VisibleOnScreenNotifier2D::_visibility_exit() {
@@ -57,7 +55,7 @@ void VisibleOnScreenNotifier2D::_visibility_exit() {
}
on_screen = false;
- emit_signal(SceneStringNames::get_singleton()->screen_exited);
+ emit_signal(SceneStringName(screen_exited));
_screen_exit();
}
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index 6afbc68e42..2716738684 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -149,7 +149,7 @@ void BoneAttachment3D::_check_bind() {
bone_idx = sk->find_bone(bone_name);
}
if (bone_idx != -1) {
- sk->connect(SNAME("skeleton_updated"), callable_mp(this, &BoneAttachment3D::on_skeleton_update));
+ sk->connect(SceneStringName(skeleton_updated), callable_mp(this, &BoneAttachment3D::on_skeleton_update));
bound = true;
callable_mp(this, &BoneAttachment3D::on_skeleton_update);
}
@@ -177,7 +177,7 @@ void BoneAttachment3D::_check_unbind() {
Skeleton3D *sk = _get_skeleton3d();
if (sk) {
- sk->disconnect(SNAME("skeleton_updated"), callable_mp(this, &BoneAttachment3D::on_skeleton_update));
+ sk->disconnect(SceneStringName(skeleton_updated), callable_mp(this, &BoneAttachment3D::on_skeleton_update));
}
bound = false;
}
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 5aa50a4a21..03fe5e1fad 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -37,7 +37,6 @@
#include "scene/resources/gradient_texture.h"
#include "scene/resources/image_texture.h"
#include "scene/resources/particle_process_material.h"
-#include "scene/scene_string_names.h"
AABB CPUParticles3D::get_aabb() const {
return AABB();
@@ -880,7 +879,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
} break;
case EMISSION_SHAPE_RING: {
real_t ring_random_angle = Math::randf() * Math_TAU;
- real_t ring_random_radius = Math::sqrt(Math::randf() * (emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
+ real_t ring_random_radius = Math::sqrt(Math::randf() * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
Vector3 axis = emission_ring_axis == Vector3(0.0, 0.0, 0.0) ? Vector3(0.0, 0.0, 1.0) : emission_ring_axis.normalized();
Vector3 ortho_axis;
if (axis.abs() == Vector3(1.0, 0.0, 0.0)) {
@@ -1156,7 +1155,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
}
if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) {
active = false;
- emit_signal(SceneStringNames::get_singleton()->finished);
+ emit_signal(SceneStringName(finished));
}
}
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index 16813b9017..3771b385e5 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -34,7 +34,6 @@
#include "scene/resources/curve_texture.h"
#include "scene/resources/gradient_texture.h"
#include "scene/resources/particle_process_material.h"
-#include "scene/scene_string_names.h"
AABB GPUParticles3D::get_aabb() const {
return AABB();
@@ -478,7 +477,7 @@ void GPUParticles3D::_notification(int p_what) {
}
if (time > active_time) {
if (active && !signal_canceled) {
- emit_signal(SceneStringNames::get_singleton()->finished);
+ emit_signal(SceneStringName(finished));
}
active = false;
if (!emitting) {
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 54370f42da..0f2ce829eb 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -32,7 +32,6 @@
#include "scene/main/viewport.h"
#include "scene/resources/theme.h"
-#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
void Label3D::_bind_methods() {
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index cc923b6676..ef492a6994 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -1102,7 +1102,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
}
}
- Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, denoiser_strength, bounces, bounce_indirect_energy, bias, max_texture_size, directional, use_texture_for_bounces, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization);
+ Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, denoiser_strength, denoiser_range, bounces, bounce_indirect_energy, bias, max_texture_size, directional, use_texture_for_bounces, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization);
if (bake_err == Lightmapper::BAKE_ERROR_LIGHTMAP_TOO_SMALL) {
return BAKE_ERROR_TEXTURE_SIZE_TOO_SMALL;
@@ -1450,6 +1450,14 @@ float LightmapGI::get_denoiser_strength() const {
return denoiser_strength;
}
+void LightmapGI::set_denoiser_range(int p_denoiser_range) {
+ denoiser_range = p_denoiser_range;
+}
+
+int LightmapGI::get_denoiser_range() const {
+ return denoiser_range;
+}
+
void LightmapGI::set_directional(bool p_enable) {
directional = p_enable;
}
@@ -1593,6 +1601,9 @@ void LightmapGI::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "denoiser_strength" && !use_denoiser) {
p_property.usage = PROPERTY_USAGE_NONE;
}
+ if (p_property.name == "denoiser_range" && !use_denoiser) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
}
void LightmapGI::_bind_methods() {
@@ -1638,6 +1649,9 @@ void LightmapGI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_denoiser_strength", "denoiser_strength"), &LightmapGI::set_denoiser_strength);
ClassDB::bind_method(D_METHOD("get_denoiser_strength"), &LightmapGI::get_denoiser_strength);
+ ClassDB::bind_method(D_METHOD("set_denoiser_range", "denoiser_range"), &LightmapGI::set_denoiser_range);
+ ClassDB::bind_method(D_METHOD("get_denoiser_range"), &LightmapGI::get_denoiser_range);
+
ClassDB::bind_method(D_METHOD("set_interior", "enable"), &LightmapGI::set_interior);
ClassDB::bind_method(D_METHOD("is_interior"), &LightmapGI::is_interior);
@@ -1661,6 +1675,7 @@ void LightmapGI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "denoiser_strength", PROPERTY_HINT_RANGE, "0.001,0.2,0.001,or_greater"), "set_denoiser_strength", "get_denoiser_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "denoiser_range", PROPERTY_HINT_RANGE, "1,20"), "set_denoiser_range", "get_denoiser_range");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texel_scale", PROPERTY_HINT_RANGE, "0.01,100.0,0.01"), "set_texel_scale", "get_texel_scale");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_texture_size", PROPERTY_HINT_RANGE, "2048,16384,1"), "set_max_texture_size", "get_max_texture_size");
diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h
index 765e4a731d..527667177b 100644
--- a/scene/3d/lightmap_gi.h
+++ b/scene/3d/lightmap_gi.h
@@ -156,6 +156,7 @@ private:
BakeQuality bake_quality = BAKE_QUALITY_MEDIUM;
bool use_denoiser = true;
float denoiser_strength = 0.1f;
+ int denoiser_range = 10;
int bounces = 3;
float bounce_indirect_energy = 1.0;
float bias = 0.0005;
@@ -256,6 +257,9 @@ public:
void set_denoiser_strength(float p_denoiser_strength);
float get_denoiser_strength() const;
+ void set_denoiser_range(int p_denoiser_range);
+ int get_denoiser_range() const;
+
void set_directional(bool p_enable);
bool is_directional() const;
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
index 521013d600..39181ad9a2 100644
--- a/scene/3d/lightmapper.h
+++ b/scene/3d/lightmapper.h
@@ -180,7 +180,7 @@ public:
virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) = 0;
virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) = 0;
virtual void add_probe(const Vector3 &p_position) = 0;
- virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_bounces, float p_bounce_indirect_energy, float p_bias, int p_max_texture_size, bool p_bake_sh, bool p_texture_for_bounces, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0;
+ virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_denoiser_range, int p_bounces, float p_bounce_indirect_energy, float p_bias, int p_max_texture_size, bool p_bake_sh, bool p_texture_for_bounces, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0;
virtual int get_bake_texture_count() const = 0;
virtual Ref<Image> get_bake_texture(int p_index) const = 0;
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 43c41c1b5b..dff413f5d2 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -865,7 +865,7 @@ void NavigationAgent3D::_trigger_waypoint_reached() {
Dictionary details;
const Vector3 waypoint = navigation_path[navigation_path_index];
- details[SNAME("position")] = waypoint;
+ details[CoreStringName(position)] = waypoint;
int waypoint_type = -1;
if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) {
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 856c52b5d5..40e04f0fb4 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -474,7 +474,7 @@ void NavigationRegion3D::_update_debug_mesh() {
return;
}
- if (!NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) {
+ if (!NavigationServer3D::get_singleton()->get_debug_enabled() || !NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) {
if (debug_instance.is_valid()) {
RS::get_singleton()->instance_set_visible(debug_instance, false);
}
@@ -640,7 +640,7 @@ void NavigationRegion3D::_update_debug_mesh() {
#ifdef DEBUG_ENABLED
void NavigationRegion3D::_update_debug_edge_connections_mesh() {
- if (!NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) {
+ if (!NavigationServer3D::get_singleton()->get_debug_enabled() || !NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) {
if (debug_edge_connections_instance.is_valid()) {
RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false);
}
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 98a5134283..2e08afb30d 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -33,7 +33,6 @@
#include "scene/3d/visual_instance_3d.h"
#include "scene/main/viewport.h"
#include "scene/property_utils.h"
-#include "scene/scene_string_names.h"
/*
@@ -193,12 +192,12 @@ void Node3D::_notification(int p_what) {
ERR_FAIL_NULL(data.viewport);
if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world);
+ get_script_instance()->call(SNAME("_enter_world"));
}
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id());
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id());
}
#endif
} break;
@@ -211,7 +210,7 @@ void Node3D::_notification(int p_what) {
#endif
if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_exit_world);
+ get_script_instance()->call(SNAME("_exit_world"));
}
data.viewport = nullptr;
@@ -564,7 +563,7 @@ void Node3D::update_gizmos() {
}
if (data.gizmos.is_empty()) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id());
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id());
return;
}
if (data.gizmos_dirty) {
@@ -583,7 +582,7 @@ void Node3D::set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transfor
}
if (is_part_of_edited_scene()) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_set_subgizmo_selection, this, p_gizmo, p_id, p_transform);
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_set_subgizmo_selection"), this, p_gizmo, p_id, p_transform);
}
#endif
}
@@ -600,7 +599,7 @@ void Node3D::clear_subgizmo_selection() {
}
if (is_part_of_edited_scene()) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_clear_subgizmo_selection, this);
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_clear_subgizmo_selection"), this);
}
#endif
}
@@ -777,7 +776,7 @@ Ref<World3D> Node3D::get_world_3d() const {
void Node3D::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
- emit_signal(SceneStringNames::get_singleton()->visibility_changed);
+ emit_signal(SceneStringName(visibility_changed));
#ifdef TOOLS_ENABLED
if (!data.gizmos.is_empty()) {
diff --git a/scene/3d/physical_bone_simulator_3d.cpp b/scene/3d/physical_bone_simulator_3d.cpp
index aba052165c..ef3c51b032 100644
--- a/scene/3d/physical_bone_simulator_3d.cpp
+++ b/scene/3d/physical_bone_simulator_3d.cpp
@@ -35,16 +35,16 @@ void PhysicalBoneSimulator3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p
if (p_old->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) {
p_old->disconnect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed));
}
- if (p_old->is_connected(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
- p_old->disconnect(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
+ if (p_old->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
+ p_old->disconnect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
}
}
if (p_new) {
if (!p_new->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) {
p_new->connect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed));
}
- if (!p_new->is_connected(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
- p_new->connect(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
+ if (!p_new->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
+ p_new->connect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
}
}
_bone_list_changed();
diff --git a/scene/3d/physics/area_3d.cpp b/scene/3d/physics/area_3d.cpp
index 014c33cad0..be95512bea 100644
--- a/scene/3d/physics/area_3d.cpp
+++ b/scene/3d/physics/area_3d.cpp
@@ -30,7 +30,6 @@
#include "area_3d.h"
-#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
void Area3D::set_gravity_space_override_mode(SpaceOverride p_mode) {
@@ -199,9 +198,9 @@ void Area3D::_body_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(E->value.in_tree);
E->value.in_tree = true;
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
}
}
@@ -213,9 +212,9 @@ void Area3D::_body_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->value.in_tree);
E->value.in_tree = false;
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape);
}
}
@@ -229,9 +228,9 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
locked = true;
// Emit the appropriate signals.
if (body_in) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
} else {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape);
}
locked = false;
unlock_callback();
@@ -257,10 +256,10 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
E->value.rc = 0;
E->value.in_tree = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree).bind(objid));
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
}
}
}
@@ -270,7 +269,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
}
if (!node || E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape);
}
} else {
@@ -284,15 +283,15 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
if (E->value.rc == 0) {
body_map.remove(E);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree));
if (in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
+ emit_signal(SceneStringName(body_exited), obj);
}
}
}
if (!node || in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape);
}
}
@@ -317,18 +316,18 @@ void Area3D::_clear_monitoring() {
}
//ERR_CONTINUE(!node);
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree));
if (!E.value.in_tree) {
continue;
}
for (int i = 0; i < E.value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
+ emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
}
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
}
}
@@ -346,18 +345,18 @@ void Area3D::_clear_monitoring() {
}
//ERR_CONTINUE(!node);
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree));
if (!E.value.in_tree) {
continue;
}
for (int i = 0; i < E.value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
}
- emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
+ emit_signal(SceneStringName(area_exited), obj);
}
}
}
@@ -405,9 +404,9 @@ void Area3D::_area_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(E->value.in_tree);
E->value.in_tree = true;
- emit_signal(SceneStringNames::get_singleton()->area_entered, node);
+ emit_signal(SceneStringName(area_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
}
}
@@ -419,9 +418,9 @@ void Area3D::_area_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->value.in_tree);
E->value.in_tree = false;
- emit_signal(SceneStringNames::get_singleton()->area_exited, node);
+ emit_signal(SceneStringName(area_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
+ emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape);
}
}
@@ -435,9 +434,9 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
locked = true;
// Emit the appropriate signals.
if (area_in) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
} else {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape);
}
locked = false;
unlock_callback();
@@ -463,10 +462,10 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
E->value.rc = 0;
E->value.in_tree = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree).bind(objid));
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_entered, node);
+ emit_signal(SceneStringName(area_entered), node);
}
}
}
@@ -476,7 +475,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
}
if (!node || E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape);
}
} else {
@@ -490,15 +489,15 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
if (E->value.rc == 0) {
area_map.remove(E);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree));
if (in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
+ emit_signal(SceneStringName(area_exited), obj);
}
}
}
if (!node || in_tree) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape);
+ emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape);
}
}
@@ -605,7 +604,7 @@ StringName Area3D::get_audio_bus_name() const {
return audio_bus;
}
}
- return SceneStringNames::get_singleton()->Master;
+ return SceneStringName(Master);
}
void Area3D::set_use_reverb_bus(bool p_enable) {
@@ -626,7 +625,7 @@ StringName Area3D::get_reverb_bus_name() const {
return reverb_bus;
}
}
- return SceneStringNames::get_singleton()->Master;
+ return SceneStringName(Master);
}
void Area3D::set_reverb_amount(float p_amount) {
@@ -812,6 +811,8 @@ void Area3D::_bind_methods() {
Area3D::Area3D() :
CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) {
+ audio_bus = SceneStringName(Master);
+ reverb_bus = SceneStringName(Master);
set_gravity(9.8);
set_gravity_direction(Vector3(0, -1, 0));
set_monitoring(true);
diff --git a/scene/3d/physics/area_3d.h b/scene/3d/physics/area_3d.h
index 41382b6128..8848f9c23a 100644
--- a/scene/3d/physics/area_3d.h
+++ b/scene/3d/physics/area_3d.h
@@ -33,7 +33,6 @@
#include "core/templates/vset.h"
#include "scene/3d/physics/collision_object_3d.h"
-#include "scene/scene_string_names.h"
class Area3D : public CollisionObject3D {
GDCLASS(Area3D, CollisionObject3D);
@@ -135,10 +134,10 @@ private:
void _clear_monitoring();
bool audio_bus_override = false;
- StringName audio_bus = SceneStringNames::get_singleton()->Master;
+ StringName audio_bus;
bool use_reverb_bus = false;
- StringName reverb_bus = SceneStringNames::get_singleton()->Master;
+ StringName reverb_bus;
float reverb_amount = 0.0;
float reverb_uniformity = 0.0;
diff --git a/scene/3d/physics/collision_object_3d.cpp b/scene/3d/physics/collision_object_3d.cpp
index 54752b1281..dddaf7eb4a 100644
--- a/scene/3d/physics/collision_object_3d.cpp
+++ b/scene/3d/physics/collision_object_3d.cpp
@@ -31,7 +31,6 @@
#include "collision_object_3d.h"
#include "scene/resources/3d/shape_3d.h"
-#include "scene/scene_string_names.h"
void CollisionObject3D::_notification(int p_what) {
switch (p_what) {
@@ -291,17 +290,17 @@ void CollisionObject3D::_apply_enabled() {
void CollisionObject3D::_input_event_call(Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
GDVIRTUAL_CALL(_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
- emit_signal(SceneStringNames::get_singleton()->input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
+ emit_signal(SceneStringName(input_event), p_camera, p_input_event, p_pos, p_normal, p_shape);
}
void CollisionObject3D::_mouse_enter() {
GDVIRTUAL_CALL(_mouse_enter);
- emit_signal(SceneStringNames::get_singleton()->mouse_entered);
+ emit_signal(SceneStringName(mouse_entered));
}
void CollisionObject3D::_mouse_exit() {
GDVIRTUAL_CALL(_mouse_exit);
- emit_signal(SceneStringNames::get_singleton()->mouse_exited);
+ emit_signal(SceneStringName(mouse_exited));
}
void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) {
diff --git a/scene/3d/physics/joints/cone_twist_joint_3d.cpp b/scene/3d/physics/joints/cone_twist_joint_3d.cpp
index 404c074911..3da0cbee71 100644
--- a/scene/3d/physics/joints/cone_twist_joint_3d.cpp
+++ b/scene/3d/physics/joints/cone_twist_joint_3d.cpp
@@ -30,8 +30,6 @@
#include "cone_twist_joint_3d.h"
-#include "scene/scene_string_names.h"
-
void ConeTwistJoint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ConeTwistJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &ConeTwistJoint3D::get_param);
diff --git a/scene/3d/physics/joints/joint_3d.cpp b/scene/3d/physics/joints/joint_3d.cpp
index a9c2526bd0..47c89f37e2 100644
--- a/scene/3d/physics/joints/joint_3d.cpp
+++ b/scene/3d/physics/joints/joint_3d.cpp
@@ -30,19 +30,17 @@
#include "joint_3d.h"
-#include "scene/scene_string_names.h"
-
void Joint3D::_disconnect_signals() {
Node *node_a = get_node_or_null(a);
PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
if (body_a) {
- body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree));
}
Node *node_b = get_node_or_null(b);
PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
if (body_b) {
- body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree));
}
}
@@ -108,12 +106,16 @@ void Joint3D::_update_joint(bool p_only_free) {
if (body_a) {
ba = body_a->get_rid();
- body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ if (!body_a->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree))) {
+ body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree));
+ }
}
if (body_b) {
bb = body_b->get_rid();
- body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ if (!body_b->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree))) {
+ body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree));
+ }
}
PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
diff --git a/scene/3d/physics/joints/slider_joint_3d.cpp b/scene/3d/physics/joints/slider_joint_3d.cpp
index 2e87ae1e83..df6b1cc045 100644
--- a/scene/3d/physics/joints/slider_joint_3d.cpp
+++ b/scene/3d/physics/joints/slider_joint_3d.cpp
@@ -30,8 +30,6 @@
#include "slider_joint_3d.h"
-#include "scene/scene_string_names.h"
-
void SliderJoint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &SliderJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &SliderJoint3D::get_param);
diff --git a/scene/3d/physics/rigid_body_3d.cpp b/scene/3d/physics/rigid_body_3d.cpp
index 6cd621c1c7..5ea413f2c4 100644
--- a/scene/3d/physics/rigid_body_3d.cpp
+++ b/scene/3d/physics/rigid_body_3d.cpp
@@ -30,8 +30,6 @@
#include "rigid_body_3d.h"
-#include "scene/scene_string_names.h"
-
void RigidBody3D::_body_enter_tree(ObjectID p_id) {
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
@@ -45,10 +43,10 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) {
contact_monitor->locked = true;
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
+ emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
}
contact_monitor->locked = false;
@@ -66,10 +64,10 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) {
contact_monitor->locked = true;
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
for (int i = 0; i < E->value.shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
+ emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape);
}
contact_monitor->locked = false;
@@ -94,10 +92,10 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
//E->value.rc=0;
E->value.in_tree = node && node->is_inside_tree();
if (node) {
- node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid));
- node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid));
+ node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid));
+ node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid));
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_entered, node);
+ emit_signal(SceneStringName(body_entered), node);
}
}
}
@@ -107,7 +105,7 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
}
if (E->value.in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape);
+ emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape);
}
} else {
@@ -121,17 +119,17 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan
if (E->value.shapes.is_empty()) {
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree));
if (in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ emit_signal(SceneStringName(body_exited), node);
}
}
contact_monitor->body_map.remove(E);
}
if (node && in_tree) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_local_shape);
+ emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_local_shape);
}
}
}
@@ -157,7 +155,7 @@ void RigidBody3D::_sync_body_state(PhysicsDirectBodyState3D *p_state) {
if (sleeping != p_state->is_sleeping()) {
sleeping = p_state->is_sleeping();
- emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
+ emit_signal(SceneStringName(sleeping_state_changed));
}
}
@@ -613,8 +611,8 @@ void RigidBody3D::set_contact_monitor(bool p_enabled) {
Node *node = Object::cast_to<Node>(obj);
if (node) {
- node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree));
- node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree));
+ node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree));
+ node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree));
}
}
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 72b5b53b19..a4804e928a 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -34,7 +34,6 @@
#include "core/variant/type_info.h"
#include "scene/3d/skeleton_modifier_3d.h"
#include "scene/resources/surface_tool.h"
-#include "scene/scene_string_names.h"
#ifndef DISABLE_DEPRECATED
#include "scene/3d/physical_bone_simulator_3d.h"
#endif // _DISABLE_DEPRECATED
@@ -314,7 +313,7 @@ void Skeleton3D::_notification(int p_what) {
_process_modifiers();
}
- emit_signal(SceneStringNames::get_singleton()->skeleton_updated);
+ emit_signal(SceneStringName(skeleton_updated));
// Update skins.
RenderingServer *rs = RenderingServer::get_singleton();
@@ -605,7 +604,7 @@ void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) {
ERR_FAIL_INDEX(p_bone, bone_size);
bones.write[p_bone].enabled = p_enabled;
- emit_signal(SceneStringNames::get_singleton()->bone_enabled_changed, p_bone);
+ emit_signal(SceneStringName(bone_enabled_changed), p_bone);
_make_dirty();
}
@@ -617,7 +616,7 @@ bool Skeleton3D::is_bone_enabled(int p_bone) const {
void Skeleton3D::set_show_rest_only(bool p_enabled) {
show_rest_only = p_enabled;
- emit_signal(SceneStringNames::get_singleton()->show_rest_only_changed);
+ emit_signal(SceneStringName(show_rest_only_changed));
_make_dirty();
}
@@ -840,7 +839,7 @@ void Skeleton3D::force_update_all_bone_transforms() {
if (updating) {
return;
}
- emit_signal(SceneStringNames::get_singleton()->pose_updated);
+ emit_signal(SceneStringName(pose_updated));
}
void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
@@ -848,12 +847,13 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
ERR_FAIL_INDEX(p_bone_idx, bone_size);
Bone *bonesptr = bones.ptrw();
- List<int> bones_to_process = List<int>();
+ thread_local LocalVector<int> bones_to_process;
+ bones_to_process.clear();
bones_to_process.push_back(p_bone_idx);
- while (bones_to_process.size() > 0) {
- int current_bone_idx = bones_to_process.front()->get();
- bones_to_process.erase(current_bone_idx);
+ uint32_t index = 0;
+ while (index < bones_to_process.size()) {
+ int current_bone_idx = bones_to_process[index];
Bone &b = bonesptr[current_bone_idx];
bool bone_enabled = b.enabled && !show_rest_only;
@@ -906,6 +906,8 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
for (int i = 0; i < child_bone_size; i++) {
bones_to_process.push_back(b.child_bones[i]);
}
+
+ index++;
}
}
diff --git a/scene/3d/skeleton_modifier_3d.cpp b/scene/3d/skeleton_modifier_3d.cpp
index 96e3e33841..8d806ef5fc 100644
--- a/scene/3d/skeleton_modifier_3d.cpp
+++ b/scene/3d/skeleton_modifier_3d.cpp
@@ -110,7 +110,7 @@ void SkeletonModifier3D::process_modification() {
}
void SkeletonModifier3D::_process_modification() {
- //
+ GDVIRTUAL_CALL(_process_modification);
}
void SkeletonModifier3D::_notification(int p_what) {
@@ -133,6 +133,7 @@ void SkeletonModifier3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "influence", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_influence", "get_influence");
ADD_SIGNAL(MethodInfo("modification_processed"));
+ GDVIRTUAL_BIND(_process_modification);
}
SkeletonModifier3D::SkeletonModifier3D() {
diff --git a/scene/3d/skeleton_modifier_3d.h b/scene/3d/skeleton_modifier_3d.h
index 25c09f3b93..d00a1e94a9 100644
--- a/scene/3d/skeleton_modifier_3d.h
+++ b/scene/3d/skeleton_modifier_3d.h
@@ -60,6 +60,7 @@ protected:
virtual void _set_active(bool p_active);
virtual void _process_modification();
+ GDVIRTUAL0(_process_modification);
public:
virtual PackedStringArray get_configuration_warnings() const override;
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 7d2a821d16..ba3b32a031 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -31,7 +31,6 @@
#include "sprite_3d.h"
#include "scene/resources/atlas_texture.h"
-#include "scene/scene_string_names.h"
Color SpriteBase3D::_get_color_accum() {
if (!color_dirty) {
@@ -796,15 +795,15 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
return;
}
if (texture.is_valid()) {
- texture->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw));
+ texture->disconnect(CoreStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw));
}
texture = p_texture;
if (texture.is_valid()) {
- texture->connect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw));
+ texture->connect(CoreStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw));
}
_queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
+ emit_signal(SceneStringName(texture_changed));
}
Ref<Texture2D> Sprite3D::get_texture() const {
@@ -849,7 +848,7 @@ void Sprite3D::set_frame(int p_frame) {
frame = p_frame;
_queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
int Sprite3D::get_frame() const {
@@ -1122,7 +1121,7 @@ void AnimatedSprite3D::_notification(int p_what) {
} else {
frame = last_frame;
pause();
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal(SceneStringName(animation_finished));
return;
}
} else {
@@ -1131,7 +1130,7 @@ void AnimatedSprite3D::_notification(int p_what) {
_calc_frame_speed_scale();
frame_progress = 0.0;
_queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining);
frame_progress += to_process * abs_speed;
@@ -1146,7 +1145,7 @@ void AnimatedSprite3D::_notification(int p_what) {
} else {
frame = 0;
pause();
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ emit_signal(SceneStringName(animation_finished));
return;
}
} else {
@@ -1155,7 +1154,7 @@ void AnimatedSprite3D::_notification(int p_what) {
_calc_frame_speed_scale();
frame_progress = 1.0;
_queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
double to_process = MIN(frame_progress / abs_speed, remaining);
frame_progress -= to_process * abs_speed;
@@ -1177,12 +1176,12 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
}
if (frames.is_valid()) {
- frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed));
+ frames->disconnect(CoreStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed));
}
stop();
frames = p_frames;
if (frames.is_valid()) {
- frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed));
+ frames->connect(CoreStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed));
List<StringName> al;
frames->get_animation_list(&al);
@@ -1249,7 +1248,7 @@ void AnimatedSprite3D::set_frame_and_progress(int p_frame, real_t p_progress) {
return; // No change, don't redraw.
}
_queue_redraw();
- emit_signal(SceneStringNames::get_singleton()->frame_changed);
+ emit_signal(SceneStringName(frame_changed));
}
void AnimatedSprite3D::set_speed_scale(float p_speed_scale) {
@@ -1343,7 +1342,7 @@ void AnimatedSprite3D::play(const StringName &p_name, float p_custom_scale, bool
} else {
set_frame_and_progress(0, 0.0);
}
- emit_signal("animation_changed");
+ emit_signal(SceneStringName(animation_changed));
} else {
bool is_backward = signbit(speed_scale * custom_speed_scale);
if (p_from_end && is_backward && frame == 0 && frame_progress <= 0.0) {
@@ -1398,7 +1397,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_name) {
animation = p_name;
- emit_signal("animation_changed");
+ emit_signal(SceneStringName(animation_changed));
if (frames == nullptr) {
animation = StringName();
diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp
index 272852e8fa..a510540e4e 100644
--- a/scene/3d/visible_on_screen_notifier_3d.cpp
+++ b/scene/3d/visible_on_screen_notifier_3d.cpp
@@ -30,15 +30,13 @@
#include "visible_on_screen_notifier_3d.h"
-#include "scene/scene_string_names.h"
-
void VisibleOnScreenNotifier3D::_visibility_enter() {
if (!is_inside_tree() || Engine::get_singleton()->is_editor_hint()) {
return;
}
on_screen = true;
- emit_signal(SceneStringNames::get_singleton()->screen_entered);
+ emit_signal(SceneStringName(screen_entered));
_screen_enter();
}
void VisibleOnScreenNotifier3D::_visibility_exit() {
@@ -47,7 +45,7 @@ void VisibleOnScreenNotifier3D::_visibility_exit() {
}
on_screen = false;
- emit_signal(SceneStringNames::get_singleton()->screen_exited);
+ emit_signal(SceneStringName(screen_exited));
_screen_exit();
}
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index e0dc300a6b..f14ae3a285 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -30,9 +30,6 @@
#include "visual_instance_3d.h"
-#include "core/core_string_names.h"
-#include "scene/scene_string_names.h"
-
AABB VisualInstance3D::get_aabb() const {
AABB ret;
GDVIRTUAL_CALL(_get_aabb, ret);
@@ -169,11 +166,11 @@ VisualInstance3D::~VisualInstance3D() {
void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) {
if (material_override.is_valid()) {
- material_override->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed));
+ material_override->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed));
}
material_override = p_material;
if (material_override.is_valid()) {
- material_override->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed));
+ material_override->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed));
}
RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID());
}
@@ -279,12 +276,12 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value)
return true;
}
#ifndef DISABLE_DEPRECATED
- if (p_name == SceneStringNames::get_singleton()->use_in_baked_light && bool(p_value)) {
+ if (p_name == SNAME("use_in_baked_light") && bool(p_value)) {
set_gi_mode(GI_MODE_STATIC);
return true;
}
- if (p_name == SceneStringNames::get_singleton()->use_dynamic_gi && bool(p_value)) {
+ if (p_name == SNAME("use_dynamic_gi") && bool(p_value)) {
set_gi_mode(GI_MODE_DYNAMIC);
return true;
}
diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp
index fbdda67526..ffca856fba 100644
--- a/scene/3d/voxel_gi.cpp
+++ b/scene/3d/voxel_gi.cpp
@@ -31,7 +31,6 @@
#include "voxel_gi.h"
#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
#include "mesh_instance_3d.h"
#include "multimesh_instance_3d.h"
#include "scene/resources/camera_attributes.h"
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index f3385b4cdc..6e33a1b27c 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -31,7 +31,6 @@
#include "animation_blend_tree.h"
#include "scene/resources/animation.h"
-#include "scene/scene_string_names.h"
void AnimationNodeAnimation::set_animation(const StringName &p_name) {
animation = p_name;
@@ -194,8 +193,8 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
nti.is_just_looped = is_just_looped;
// 3. Progress for Animation.
- double prev_playback_time = prev_time - start_offset;
- double cur_playback_time = cur_time - start_offset;
+ double prev_playback_time = prev_time + start_offset;
+ double cur_playback_time = cur_time + start_offset;
if (stretch_time_scale) {
double mlt = anim_size / cur_len;
cur_playback_time *= mlt;
@@ -238,11 +237,11 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
if (process_state->tree && !p_test_only) {
// AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection.
if (p_seek && !p_is_external_seeking && cur_playback_time == 0) {
- process_state->tree->call_deferred(SNAME("emit_signal"), "animation_started", animation);
+ process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation);
}
// Finished.
- if (prev_time - start_offset < anim_size && cur_playback_time >= anim_size) {
- process_state->tree->call_deferred(SNAME("emit_signal"), "animation_finished", animation);
+ if (prev_time + start_offset < anim_size && cur_playback_time >= anim_size) {
+ process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_finished), animation);
}
}
}
@@ -1421,7 +1420,7 @@ AnimationNodeOutput::AnimationNodeOutput() {
void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
- ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
+ ERR_FAIL_COND(p_name == SceneStringName(output));
ERR_FAIL_COND(String(p_name).contains("/"));
Node n;
@@ -1491,7 +1490,7 @@ Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const Strin
void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!nodes.has(p_name));
- ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output
+ ERR_FAIL_COND(p_name == SceneStringName(output)); //can't delete output
{
Ref<AnimationNode> node = nodes[p_name].node;
@@ -1520,8 +1519,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) {
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(nodes.has(p_new_name));
- ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
- ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output);
+ ERR_FAIL_COND(p_name == SceneStringName(output));
+ ERR_FAIL_COND(p_new_name == SceneStringName(output));
nodes[p_name].node->disconnect_changed(callable_mp(this, &AnimationNodeBlendTree::_node_changed));
@@ -1546,7 +1545,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) {
ERR_FAIL_COND(!nodes.has(p_output_node));
ERR_FAIL_COND(!nodes.has(p_input_node));
- ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output);
+ ERR_FAIL_COND(p_output_node == SceneStringName(output));
ERR_FAIL_COND(p_input_node == p_output_node);
Ref<AnimationNode> input = nodes[p_input_node].node;
@@ -1574,7 +1573,7 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp
}
AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const {
- if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) {
+ if (!nodes.has(p_output_node) || p_output_node == SceneStringName(output)) {
return CONNECTION_ERROR_NO_OUTPUT;
}
@@ -1627,8 +1626,8 @@ String AnimationNodeBlendTree::get_caption() const {
}
AnimationNode::NodeTimeInfo AnimationNodeBlendTree::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) {
- Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
- node_state.connections = nodes[SceneStringNames::get_singleton()->output].connections;
+ Ref<AnimationNodeOutput> output = nodes[SceneStringName(output)].node;
+ node_state.connections = nodes[SceneStringName(output)].connections;
ERR_FAIL_COND_V(output.is_null(), NodeTimeInfo());
AnimationMixer::PlaybackInfo pi = p_playback_info;
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index d22b58346f..e600de6b8b 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -35,7 +35,6 @@
#include "core/config/project_settings.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
-#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
#ifndef _3D_DISABLED
@@ -301,7 +300,7 @@ Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref<
ald.library->connect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added).bind(p_name));
ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed).bind(p_name));
ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed).bind(p_name));
- ald.library->connect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed));
+ ald.library->connect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed));
_animation_set_cache_update();
@@ -325,7 +324,7 @@ void AnimationMixer::remove_animation_library(const StringName &p_name) {
animation_libraries[at_pos].library->disconnect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added));
animation_libraries[at_pos].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed));
animation_libraries[at_pos].library->disconnect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed));
- animation_libraries[at_pos].library->disconnect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed));
+ animation_libraries[at_pos].library->disconnect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed));
animation_libraries.remove_at(at_pos);
_animation_set_cache_update();
@@ -502,6 +501,7 @@ AnimationMixer::AnimationCallbackModeMethod AnimationMixer::get_callback_mode_me
void AnimationMixer::set_callback_mode_discrete(AnimationCallbackModeDiscrete p_mode) {
callback_mode_discrete = p_mode;
+ _clear_caches();
emit_signal(SNAME("mixer_updated"));
}
@@ -628,9 +628,9 @@ bool AnimationMixer::_update_caches() {
#endif
Ref<Animation> reset_anim;
- bool has_reset_anim = has_animation(SceneStringNames::get_singleton()->RESET);
+ bool has_reset_anim = has_animation(SceneStringName(RESET));
if (has_reset_anim) {
- reset_anim = get_animation(SceneStringNames::get_singleton()->RESET);
+ reset_anim = get_animation(SceneStringName(RESET));
}
for (const StringName &E : sname) {
Ref<Animation> anim = get_animation(E);
@@ -689,7 +689,7 @@ bool AnimationMixer::_update_caches() {
track_value->init_value = anim->track_get_key_value(i, 0);
track_value->init_value.zero();
- track_value->init_use_continuous = callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS;
+ track_value->is_init = false;
// Can't interpolate them, need to convert.
track_value->is_variant_interpolatable = Animation::is_variant_interpolatable(track_value->init_value);
@@ -699,7 +699,6 @@ bool AnimationMixer::_update_caches() {
int rt = reset_anim->find_track(path, track_src_type);
if (rt >= 0) {
if (track_src_type == Animation::TYPE_VALUE) {
- track_value->init_use_continuous = track_value->init_use_continuous || (reset_anim->value_track_get_update_mode(rt) != Animation::UPDATE_DISCRETE); // Take precedence Force Continuous.
if (reset_anim->track_get_key_count(rt) > 0) {
track_value->init_value = reset_anim->track_get_key_value(rt, 0);
}
@@ -1007,7 +1006,7 @@ void AnimationMixer::_blend_init() {
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
t->value = Animation::cast_to_blendwise(t->init_value);
t->element_size = t->init_value.is_string() ? (real_t)(t->init_value.operator String()).length() : 0;
- t->use_continuous = t->init_use_continuous;
+ t->use_continuous = false;
t->use_discrete = false;
} break;
case Animation::TYPE_AUDIO: {
@@ -1463,12 +1462,12 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
t->value = Animation::blend_variant(t->value, value, blend);
}
} else {
- t->use_discrete = true;
if (seeked) {
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT, true);
if (idx < 0) {
continue;
}
+ t->use_discrete = true;
Variant value = a->track_get_key_value(i, idx);
value = post_process_key_value(a, i, value, t->object_id);
Object *t_obj = ObjectDB::get_instance(t->object_id);
@@ -1479,6 +1478,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
List<int> indices;
a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
for (int &F : indices) {
+ t->use_discrete = true;
Variant value = a->track_get_key_value(i, F);
value = post_process_key_value(a, i, value, t->object_id);
Object *t_obj = ObjectDB::get_instance(t->object_id);
@@ -1683,7 +1683,8 @@ void AnimationMixer::_blend_apply() {
// Finally, set the tracks.
for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) {
TrackCache *track = K.value;
- if (!deterministic && Math::is_zero_approx(track->total_weight)) {
+ bool is_zero_amount = Math::is_zero_approx(track->total_weight);
+ if (!deterministic && is_zero_amount) {
continue;
}
switch (track->type) {
@@ -1743,10 +1744,24 @@ void AnimationMixer::_blend_apply() {
case Animation::TYPE_VALUE: {
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
- if (!t->is_variant_interpolatable || !t->use_continuous || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) {
+ if (t->use_discrete && !t->use_continuous) {
+ t->is_init = true; // If only disctere value is applied, no more RESET.
+ }
+
+ if ((t->is_init && (is_zero_amount || !t->use_continuous)) ||
+ (callback_mode_discrete != ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS &&
+ !is_zero_amount &&
+ callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT &&
+ t->use_discrete)) {
break; // Don't overwrite the value set by UPDATE_DISCRETE.
}
+ if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) {
+ t->is_init = false; // Always update in Force Continuous.
+ } else {
+ t->is_init = !t->use_continuous; // If there is no Continuous in non-Force Continuous type, it means RESET.
+ }
+
// Trim unused elements if init array/string is not blended.
if (t->value.is_array()) {
int actual_blended_size = (int)Math::round(Math::abs(t->element_size.operator real_t()));
@@ -1926,7 +1941,7 @@ bool AnimationMixer::is_reset_on_save_enabled() const {
}
bool AnimationMixer::can_apply_reset() const {
- return has_animation(SceneStringNames::get_singleton()->RESET);
+ return has_animation(SceneStringName(RESET));
}
void AnimationMixer::_build_backup_track_cache() {
@@ -2013,7 +2028,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
Ref<AnimatedValuesBackup> backup;
backup.instantiate();
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>());
_blend_init();
@@ -2022,7 +2037,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
pi.delta = 0;
pi.seeked = true;
pi.weight = 1.0;
- make_animation_instance(SceneStringNames::get_singleton()->RESET, pi);
+ make_animation_instance(SceneStringName(RESET), pi);
_build_backup_track_cache();
backup->set_data(track_cache);
@@ -2034,7 +2049,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() {
void AnimationMixer::reset() {
ERR_FAIL_COND(!can_apply_reset());
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND(reset_anim.is_null());
Node *root_node_object = get_node_or_null(root_node);
@@ -2044,11 +2059,11 @@ void AnimationMixer::reset() {
root_node_object->add_child(aux_player);
Ref<AnimationLibrary> al;
al.instantiate();
- al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim);
+ al->add_animation(SceneStringName(RESET), reset_anim);
aux_player->set_reset_on_save_enabled(false);
aux_player->set_root_node(aux_player->get_path_to(root_node_object));
aux_player->add_animation_library("", al);
- aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET);
+ aux_player->set_assigned_animation(SceneStringName(RESET));
aux_player->seek(0.0f, true);
aux_player->queue_free();
}
@@ -2068,7 +2083,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::apply_reset(bool p_user_initiated) {
}
ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>());
- Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation;
+ Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation;
ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>());
Ref<AnimatedValuesBackup> backup_current = make_backup();
@@ -2286,7 +2301,7 @@ void AnimationMixer::_bind_methods() {
}
AnimationMixer::AnimationMixer() {
- root_node = SceneStringNames::get_singleton()->path_pp;
+ root_node = SceneStringName(path_pp);
}
AnimationMixer::~AnimationMixer() {
diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h
index b7898cffc9..089a210193 100644
--- a/scene/animation/animation_mixer.h
+++ b/scene/animation/animation_mixer.h
@@ -126,7 +126,7 @@ protected:
/* ---- General settings for animation ---- */
AnimationCallbackModeProcess callback_mode_process = ANIMATION_CALLBACK_MODE_PROCESS_IDLE;
AnimationCallbackModeMethod callback_mode_method = ANIMATION_CALLBACK_MODE_METHOD_DEFERRED;
- AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT;
+ AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE;
int audio_max_polyphony = 32;
NodePath root_node;
@@ -224,7 +224,7 @@ protected:
Vector<StringName> subpath;
// TODO: There are many boolean, can be packed into one integer.
- bool init_use_continuous = false;
+ bool is_init = false;
bool use_continuous = false;
bool use_discrete = false;
bool is_using_angle = false;
@@ -237,7 +237,7 @@ protected:
init_value(p_other.init_value),
value(p_other.value),
subpath(p_other.subpath),
- init_use_continuous(p_other.init_use_continuous),
+ is_init(p_other.is_init),
use_continuous(p_other.use_continuous),
use_discrete(p_other.use_discrete),
is_using_angle(p_other.is_using_angle),
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2213800476..0c24d79ad7 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -32,7 +32,6 @@
#include "animation_player.compat.inc"
#include "core/config/engine.h"
-#include "scene/scene_string_names.h"
bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
@@ -41,7 +40,7 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
} else if (name.begins_with("next/")) {
String which = name.get_slicec('/', 1);
animation_set_next(which, p_value);
- } else if (p_name == SceneStringNames::get_singleton()->blend_times) {
+ } else if (p_name == SceneStringName(blend_times)) {
Array array = p_value;
int len = array.size();
ERR_FAIL_COND_V(len % 3, false);
@@ -77,7 +76,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
String which = name.get_slicec('/', 1);
r_ret = animation_get_next(which);
- } else if (name == "blend_times") {
+ } else if (p_name == SceneStringName(blend_times)) {
Vector<BlendKey> keys;
for (const KeyValue<BlendKey, double> &E : blend_times) {
keys.ordered_insert(E.key);
@@ -326,14 +325,14 @@ void AnimationPlayer::_blend_post_process() {
String new_name = playback.assigned;
playback_queue.pop_front();
if (end_notify) {
- emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
+ emit_signal(SceneStringName(animation_changed), old, new_name);
}
} else {
_clear_caches();
playing = false;
_set_process(false);
if (end_notify) {
- emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
+ emit_signal(SceneStringName(animation_finished), playback.assigned);
if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) {
print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path()));
get_tree()->quit();
@@ -448,10 +447,10 @@ void AnimationPlayer::_play(const StringName &p_name, double p_custom_blend, flo
} else {
if (p_from_end && c.current.pos == 0) {
// Animation reset but played backwards, set position to the end.
- c.current.pos = c.current.from->animation->get_length();
+ seek(c.current.from->animation->get_length(), true, true);
} else if (!p_from_end && c.current.pos == c.current.from->animation->get_length()) {
// Animation resumed but already ended, set position to the beginning.
- c.current.pos = 0;
+ seek(0, true, true);
} else if (playing) {
return;
}
@@ -463,7 +462,7 @@ void AnimationPlayer::_play(const StringName &p_name, double p_custom_blend, flo
_set_process(true); // Always process when starting an animation.
playing = true;
- emit_signal(SceneStringNames::get_singleton()->animation_started, c.assigned);
+ emit_signal(SceneStringName(animation_started), c.assigned);
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return; // No next in this case.
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 28a163768f..d4061ab167 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -34,7 +34,6 @@
#include "animation_blend_tree.h"
#include "core/config/engine.h"
#include "scene/animation/animation_player.h"
-#include "scene/scene_string_names.h"
void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
Array parameters;
@@ -627,7 +626,7 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const
for (int i = 0; i < p_track_count; i++) {
src_blendsw[i] = 1.0; // By default all go to 1 for the root input.
}
- root_animation_node->node_state.base_path = SceneStringNames::get_singleton()->parameters_base_path;
+ root_animation_node->node_state.base_path = SceneStringName(parameters_base_path);
root_animation_node->node_state.parent = nullptr;
}
@@ -788,7 +787,7 @@ void AnimationTree::_update_properties() {
input_activity_map_get.clear();
if (root_animation_node.is_valid()) {
- _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root_animation_node);
+ _update_properties_for_node(SceneStringName(parameters_base_path), root_animation_node);
}
properties_dirty = false;
@@ -810,7 +809,7 @@ void AnimationTree::_notification(int p_what) {
void AnimationTree::set_animation_player(const NodePath &p_path) {
animation_player = p_path;
if (p_path.is_empty()) {
- set_root_node(SceneStringNames::get_singleton()->path_pp);
+ set_root_node(SceneStringName(path_pp));
while (animation_libraries.size()) {
remove_animation_library(animation_libraries[0].name);
}
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 56c582e2d7..6a61e8693d 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -351,7 +351,7 @@ bool Tween::step(double p_delta) {
if (loops_done == loops) {
running = false;
dead = true;
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
break;
} else {
emit_signal(SNAME("loop_finished"), loops_done);
@@ -614,7 +614,7 @@ bool PropertyTweener::step(double &r_delta) {
target_instance->set_indexed(property, final_val);
finished = true;
r_delta = elapsed_time - delay - duration;
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
return false;
}
}
@@ -674,7 +674,7 @@ bool IntervalTweener::step(double &r_delta) {
} else {
finished = true;
r_delta = elapsed_time - duration;
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
return false;
}
}
@@ -717,7 +717,7 @@ bool CallbackTweener::step(double &r_delta) {
finished = true;
r_delta = elapsed_time - delay;
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
return false;
}
@@ -803,7 +803,7 @@ bool MethodTweener::step(double &r_delta) {
} else {
finished = true;
r_delta = elapsed_time - delay - duration;
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
return false;
}
}
diff --git a/scene/audio/audio_stream_player_internal.cpp b/scene/audio/audio_stream_player_internal.cpp
index 19b3ec481b..a7b8faaaae 100644
--- a/scene/audio/audio_stream_player_internal.cpp
+++ b/scene/audio/audio_stream_player_internal.cpp
@@ -31,7 +31,6 @@
#include "audio_stream_player_internal.h"
#include "scene/main/node.h"
-#include "scene/scene_string_names.h"
#include "servers/audio/audio_stream.h"
void AudioStreamPlayerInternal::_set_process(bool p_enabled) {
@@ -78,7 +77,7 @@ void AudioStreamPlayerInternal::process() {
_set_process(false);
}
if (!playbacks_to_remove.is_empty()) {
- node->emit_signal(SNAME("finished"));
+ node->emit_signal(SceneStringName(finished));
}
}
@@ -307,14 +306,14 @@ StringName AudioStreamPlayerInternal::get_bus() const {
return bus;
}
}
- return SceneStringNames::get_singleton()->Master;
+ return SceneStringName(Master);
}
AudioStreamPlayerInternal::AudioStreamPlayerInternal(Node *p_node, const Callable &p_play_callable, bool p_physical) {
node = p_node;
play_callable = p_play_callable;
physical = p_physical;
- bus = SceneStringNames::get_singleton()->Master;
+ bus = SceneStringName(Master);
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp((Object *)node, &Object::notify_property_list_changed));
AudioServer::get_singleton()->connect("bus_renamed", callable_mp((Object *)node, &Object::notify_property_list_changed).unbind(3));
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 66b14dc967..01e3cce78b 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -33,7 +33,6 @@
#include "core/config/project_settings.h"
#include "core/os/keyboard.h"
#include "scene/main/window.h"
-#include "scene/scene_string_names.h"
void BaseButton::_unpress_group() {
if (!button_group.is_valid()) {
@@ -135,7 +134,7 @@ void BaseButton::_notification(int p_what) {
void BaseButton::_pressed() {
GDVIRTUAL_CALL(_pressed);
pressed();
- emit_signal(SNAME("pressed"));
+ emit_signal(SceneStringName(pressed));
}
void BaseButton::_toggled(bool p_pressed) {
@@ -162,7 +161,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
status.pressed = !status.pressed;
_unpress_group();
if (button_group.is_valid()) {
- button_group->emit_signal(SNAME("pressed"), this);
+ button_group->emit_signal(SceneStringName(pressed), this);
}
_toggled(status.pressed);
_pressed();
@@ -226,7 +225,7 @@ void BaseButton::set_pressed(bool p_pressed) {
if (p_pressed) {
_unpress_group();
if (button_group.is_valid()) {
- button_group->emit_signal(SNAME("pressed"), this);
+ button_group->emit_signal(SceneStringName(pressed), this);
}
}
_toggled(status.pressed);
@@ -368,7 +367,7 @@ void BaseButton::shortcut_input(const Ref<InputEvent> &p_event) {
_unpress_group();
if (button_group.is_valid()) {
- button_group->emit_signal(SNAME("pressed"), this);
+ button_group->emit_signal(SceneStringName(pressed), this);
}
_toggled(status.pressed);
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index 88f65ca1bc..d8fcbbb883 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -243,8 +243,8 @@ Size2 BoxContainer::get_minimum_size() const {
bool first = true;
for (int i = 0; i < get_child_count(); i++) {
- Control *c = as_sortable_control(get_child(i));
- if (!c) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c || !c->is_visible() || c->is_set_as_top_level()) {
continue;
}
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index ad3f607661..3bf9d79c7f 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -50,6 +50,83 @@ void Button::_set_internal_margin(Side p_side, float p_value) {
void Button::_queue_update_size_cache() {
}
+void Button::_update_theme_item_cache() {
+ Control::_update_theme_item_cache();
+
+ const bool rtl = is_layout_rtl();
+ if (rtl && has_theme_stylebox(SNAME("normal_mirrored"))) {
+ theme_cache.max_style_size = theme_cache.normal_mirrored->get_minimum_size();
+ theme_cache.style_margin_left = theme_cache.normal_mirrored->get_margin(SIDE_LEFT);
+ theme_cache.style_margin_right = theme_cache.normal_mirrored->get_margin(SIDE_RIGHT);
+ theme_cache.style_margin_top = theme_cache.normal_mirrored->get_margin(SIDE_TOP);
+ theme_cache.style_margin_bottom = theme_cache.normal_mirrored->get_margin(SIDE_BOTTOM);
+ } else {
+ theme_cache.max_style_size = theme_cache.normal->get_minimum_size();
+ theme_cache.style_margin_left = theme_cache.normal->get_margin(SIDE_LEFT);
+ theme_cache.style_margin_right = theme_cache.normal->get_margin(SIDE_RIGHT);
+ theme_cache.style_margin_top = theme_cache.normal->get_margin(SIDE_TOP);
+ theme_cache.style_margin_bottom = theme_cache.normal->get_margin(SIDE_BOTTOM);
+ }
+ if (has_theme_stylebox("hover_pressed")) {
+ if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_pressed_mirrored->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_pressed_mirrored->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_pressed_mirrored->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_pressed_mirrored->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_pressed_mirrored->get_margin(SIDE_BOTTOM));
+ } else {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_pressed->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_pressed->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_pressed->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_pressed->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_pressed->get_margin(SIDE_BOTTOM));
+ }
+ }
+ if (rtl && has_theme_stylebox(SNAME("pressed_mirrored"))) {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.pressed_mirrored->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.pressed_mirrored->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.pressed_mirrored->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.pressed_mirrored->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.pressed_mirrored->get_margin(SIDE_BOTTOM));
+ } else {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.pressed->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.pressed->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.pressed->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.pressed->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.pressed->get_margin(SIDE_BOTTOM));
+ }
+ if (rtl && has_theme_stylebox(SNAME("hover_mirrored"))) {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_mirrored->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_mirrored->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_mirrored->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_mirrored->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_mirrored->get_margin(SIDE_BOTTOM));
+ } else {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover->get_margin(SIDE_BOTTOM));
+ }
+ if (rtl && has_theme_stylebox(SNAME("disabled_mirrored"))) {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.disabled_mirrored->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.disabled_mirrored->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.disabled_mirrored->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.disabled_mirrored->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.disabled_mirrored->get_margin(SIDE_BOTTOM));
+ } else {
+ theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.disabled->get_minimum_size());
+ theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.disabled->get_margin(SIDE_LEFT));
+ theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.disabled->get_margin(SIDE_RIGHT));
+ theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.disabled->get_margin(SIDE_TOP));
+ theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.disabled->get_margin(SIDE_BOTTOM));
+ }
+}
+
+Size2 Button::_get_largest_stylebox_size() const {
+ return theme_cache.max_style_size;
+}
+
Ref<StyleBox> Button::_get_current_stylebox() const {
Ref<StyleBox> stylebox = theme_cache.normal;
const bool rtl = is_layout_rtl();
@@ -137,16 +214,13 @@ void Button::_notification(int p_what) {
const RID ci = get_canvas_item();
const Size2 size = get_size();
- const Ref<StyleBox> style = _get_current_stylebox();
- { // Draws the stylebox in the current state.
- if (!flat) {
- style->draw(ci, Rect2(Point2(), size));
- }
+ // Draws the stylebox in the current state.
+ if (!flat) {
+ _get_current_stylebox()->draw(ci, Rect2(Point2(), size));
+ }
- if (has_focus()) {
- Ref<StyleBox> style2 = theme_cache.focus;
- style2->draw(ci, Rect2(Point2(), size));
- }
+ if (has_focus()) {
+ theme_cache.focus->draw(ci, Rect2(Point2(), size));
}
Ref<Texture2D> _icon = icon;
@@ -158,16 +232,11 @@ void Button::_notification(int p_what) {
break;
}
- const float style_margin_left = style->get_margin(SIDE_LEFT);
- const float style_margin_right = style->get_margin(SIDE_RIGHT);
- const float style_margin_top = style->get_margin(SIDE_TOP);
- const float style_margin_bottom = style->get_margin(SIDE_BOTTOM);
-
Size2 drawable_size_remained = size;
{ // The size after the stelybox is stripped.
- drawable_size_remained.width -= style_margin_left + style_margin_right;
- drawable_size_remained.height -= style_margin_top + style_margin_bottom;
+ drawable_size_remained.width -= theme_cache.style_margin_left + theme_cache.style_margin_right;
+ drawable_size_remained.height -= theme_cache.style_margin_top + theme_cache.style_margin_bottom;
}
const int h_separation = MAX(0, theme_cache.h_separation);
@@ -298,6 +367,7 @@ void Button::_notification(int p_what) {
icon_size = Size2(icon_width, icon_height);
}
icon_size = _fit_icon_size(icon_size);
+ icon_size = icon_size.round();
}
if (icon_size.width > 0.0f) {
@@ -311,12 +381,12 @@ void Button::_notification(int p_what) {
[[fallthrough]];
case HORIZONTAL_ALIGNMENT_FILL:
case HORIZONTAL_ALIGNMENT_LEFT: {
- icon_ofs.x += style_margin_left;
+ icon_ofs.x += theme_cache.style_margin_left;
icon_ofs.x += left_internal_margin_with_h_separation;
} break;
case HORIZONTAL_ALIGNMENT_RIGHT: {
- icon_ofs.x = size.x - style_margin_right;
+ icon_ofs.x = size.x - theme_cache.style_margin_right;
icon_ofs.x -= right_internal_margin_with_h_separation;
icon_ofs.x -= icon_size.width;
} break;
@@ -329,13 +399,14 @@ void Button::_notification(int p_what) {
[[fallthrough]];
case VERTICAL_ALIGNMENT_FILL:
case VERTICAL_ALIGNMENT_TOP: {
- icon_ofs.y += style_margin_top;
+ icon_ofs.y += theme_cache.style_margin_top;
} break;
case VERTICAL_ALIGNMENT_BOTTOM: {
- icon_ofs.y = size.y - style_margin_bottom - icon_size.height;
+ icon_ofs.y = size.y - theme_cache.style_margin_bottom - icon_size.height;
} break;
}
+ icon_ofs = icon_ofs.floor();
Rect2 icon_region = Rect2(icon_ofs, icon_size);
draw_texture_rect(_icon, icon_region, false, icon_modulate_color);
@@ -371,7 +442,7 @@ void Button::_notification(int p_what) {
case HORIZONTAL_ALIGNMENT_FILL:
case HORIZONTAL_ALIGNMENT_LEFT:
case HORIZONTAL_ALIGNMENT_RIGHT: {
- text_ofs.x += style_margin_left;
+ text_ofs.x += theme_cache.style_margin_left;
text_ofs.x += left_internal_margin_with_h_separation;
if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) {
// Offset by the space's width that occupied by icon and h_separation together.
@@ -380,7 +451,7 @@ void Button::_notification(int p_what) {
} break;
}
- text_ofs.y = (drawable_size_remained.height - text_buf->get_size().height) / 2.0f + style_margin_top;
+ text_ofs.y = (drawable_size_remained.height - text_buf->get_size().height) / 2.0f + theme_cache.style_margin_top;
if (vertical_icon_alignment == VERTICAL_ALIGNMENT_TOP) {
text_ofs.y += custom_element_size.height - drawable_size_remained.height; // Offset by the icon's height.
}
@@ -450,7 +521,7 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu
}
}
- return _get_current_stylebox()->get_minimum_size() + minsize;
+ return _get_largest_stylebox_size() + minsize;
}
void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) {
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 86fdbd35d5..eefb690913 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -69,6 +69,12 @@ private:
Ref<StyleBox> disabled_mirrored;
Ref<StyleBox> focus;
+ Size2 max_style_size;
+ float style_margin_left = 0;
+ float style_margin_right = 0;
+ float style_margin_top = 0;
+ float style_margin_bottom = 0;
+
Color font_color;
Color font_focus_color;
Color font_pressed_color;
@@ -94,16 +100,18 @@ private:
int icon_max_width = 0;
} theme_cache;
- Size2 _fit_icon_size(const Size2 &p_size) const;
-
void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = "");
void _texture_changed();
protected:
+ virtual void _update_theme_item_cache() override;
+
void _set_internal_margin(Side p_side, float p_value);
virtual void _queue_update_size_cache();
+ Size2 _fit_icon_size(const Size2 &p_size) const;
Ref<StyleBox> _get_current_stylebox() const;
+ Size2 _get_largest_stylebox_size() const;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index af6696834e..99937aaf41 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -59,14 +59,14 @@ Size2 CheckBox::get_icon_size() const {
if (!theme_cache.radio_unchecked_disabled.is_null()) {
tex_size = tex_size.max(theme_cache.radio_unchecked_disabled->get_size());
}
- return tex_size;
+ return _fit_icon_size(tex_size);
}
Size2 CheckBox::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
const Size2 tex_size = get_icon_size();
if (tex_size.width > 0 || tex_size.height > 0) {
- const Size2 padding = _get_current_stylebox()->get_minimum_size();
+ const Size2 padding = _get_largest_stylebox_size();
Size2 content_size = minsize - padding;
if (content_size.width > 0 && tex_size.width > 0) {
content_size.width += MAX(0, theme_cache.h_separation);
@@ -127,9 +127,9 @@ void CheckBox::_notification(int p_what) {
ofs.y = int((get_size().height - get_icon_size().height) / 2) + theme_cache.check_v_offset;
if (is_pressed()) {
- on_tex->draw(ci, ofs);
+ on_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(on_tex->get_size())));
} else {
- off_tex->draw(ci, ofs);
+ off_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(off_tex->get_size())));
}
} break;
}
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index ab3b74a3c3..29b9504776 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -63,14 +63,14 @@ Size2 CheckButton::get_icon_size() const {
tex_size = tex_size.max(off_tex->get_size());
}
- return tex_size;
+ return _fit_icon_size(tex_size);
}
Size2 CheckButton::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
const Size2 tex_size = get_icon_size();
if (tex_size.width > 0 || tex_size.height > 0) {
- const Size2 padding = _get_current_stylebox()->get_minimum_size();
+ const Size2 padding = _get_largest_stylebox_size();
Size2 content_size = minsize - padding;
if (content_size.width > 0 && tex_size.width > 0) {
content_size.width += MAX(0, theme_cache.h_separation);
@@ -134,9 +134,9 @@ void CheckButton::_notification(int p_what) {
ofs.y = (get_size().height - tex_size.height) / 2 + theme_cache.check_v_offset;
if (is_pressed()) {
- on_tex->draw(ci, ofs);
+ on_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(on_tex->get_size())));
} else {
- off_tex->draw(ci, ofs);
+ off_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(off_tex->get_size())));
}
} break;
}
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 8131fe7aaa..c843bb8c44 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -3050,7 +3050,7 @@ void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) {
}
int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) const {
- if (delimiters.size() == 0) {
+ if (delimiters.size() == 0 || p_line >= delimiter_cache.size()) {
return -1;
}
ERR_FAIL_INDEX_V(p_line, get_line_count(), 0);
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index aeaaac1efc..245a086dda 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -95,8 +95,8 @@ void ColorPicker::_notification(int p_what) {
for (int i = 0; i < MODE_BUTTON_COUNT; i++) {
mode_btns[i]->begin_bulk_theme_override();
- mode_btns[i]->add_theme_style_override(SNAME("pressed"), theme_cache.mode_button_pressed);
- mode_btns[i]->add_theme_style_override(SNAME("normal"), theme_cache.mode_button_normal);
+ mode_btns[i]->add_theme_style_override(SceneStringName(pressed), theme_cache.mode_button_pressed);
+ mode_btns[i]->add_theme_style_override(CoreStringName(normal), theme_cache.mode_button_normal);
mode_btns[i]->add_theme_style_override(SNAME("hover"), theme_cache.mode_button_hover);
mode_btns[i]->end_bulk_theme_override();
}
@@ -420,18 +420,18 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) {
LineEdit *vle = val->get_line_edit();
vle->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed));
- vle->connect("gui_input", callable_mp(this, &ColorPicker::_line_edit_input));
+ vle->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_line_edit_input));
vle->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
- val->connect("gui_input", callable_mp(this, &ColorPicker::_slider_or_spin_input));
+ val->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_slider_or_spin_input));
slider->set_h_size_flags(SIZE_EXPAND_FILL);
slider->connect("drag_started", callable_mp(this, &ColorPicker::_slider_drag_started));
slider->connect("value_changed", callable_mp(this, &ColorPicker::_slider_value_changed).unbind(1));
slider->connect("drag_ended", callable_mp(this, &ColorPicker::_slider_drag_ended).unbind(1));
- slider->connect("draw", callable_mp(this, &ColorPicker::_slider_draw).bind(idx));
- slider->connect("gui_input", callable_mp(this, &ColorPicker::_slider_or_spin_input));
+ slider->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_slider_draw).bind(idx));
+ slider->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_slider_or_spin_input));
if (idx < SLIDER_COUNT) {
sliders[idx] = slider;
@@ -761,7 +761,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
btn_preset_new->set_button_group(preset_group);
preset_container->add_child(btn_preset_new);
btn_preset_new->set_pressed(true);
- btn_preset_new->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input).bind(p_color));
+ btn_preset_new->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_preset_input).bind(p_color));
}
void ColorPicker::_add_recent_preset_button(int p_size, const Color &p_color) {
@@ -1510,7 +1510,7 @@ void ColorPicker::_pick_button_pressed() {
if (!picker_window) {
picker_window = memnew(Popup);
picker_window->set_size(Vector2i(1, 1));
- picker_window->connect("visibility_changed", callable_mp(this, &ColorPicker::_pick_finished));
+ picker_window->connect(SceneStringName(visibility_changed), callable_mp(this, &ColorPicker::_pick_finished));
add_child(picker_window, false, INTERNAL_MODE_FRONT);
}
picker_window->popup();
@@ -1546,7 +1546,7 @@ void ColorPicker::_pick_button_pressed_legacy() {
picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT);
picker_window->add_child(picker_texture_rect);
picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND);
- picker_texture_rect->connect("gui_input", callable_mp(this, &ColorPicker::_picker_texture_input));
+ picker_texture_rect->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_picker_texture_input));
picker_preview = memnew(Panel);
picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
@@ -1823,11 +1823,11 @@ ColorPicker::ColorPicker() {
uv_edit = memnew(Control);
hb_edit->add_child(uv_edit);
- uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit));
+ uv_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit));
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit));
+ uv_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit));
sample_hbc = memnew(HBoxContainer);
real_vbox->add_child(sample_hbc);
@@ -1836,18 +1836,18 @@ ColorPicker::ColorPicker() {
sample_hbc->add_child(btn_pick);
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_CAPTURE)) {
btn_pick->set_tooltip_text(ETR("Pick a color from the screen."));
- btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed));
+ btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed));
} else {
// On unsupported platforms, use a legacy method for color picking.
btn_pick->set_tooltip_text(ETR("Pick a color from the application window."));
- btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy));
+ btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy));
}
sample = memnew(TextureRect);
sample_hbc->add_child(sample);
sample->set_h_size_flags(SIZE_EXPAND_FILL);
- sample->connect("gui_input", callable_mp(this, &ColorPicker::_sample_input));
- sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw));
+ sample->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_sample_input));
+ sample->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_sample_draw));
btn_shape = memnew(MenuButton);
btn_shape->set_flat(false);
@@ -1883,7 +1883,7 @@ ColorPicker::ColorPicker() {
mode_btns[i]->set_toggle_mode(true);
mode_btns[i]->set_text(modes[i]->get_name());
mode_btns[i]->set_button_group(mode_group);
- mode_btns[i]->connect("pressed", callable_mp(this, &ColorPicker::set_color_mode).bind((ColorModeType)i));
+ mode_btns[i]->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::set_color_mode).bind((ColorModeType)i));
}
mode_btns[0]->set_pressed(true);
@@ -1936,7 +1936,7 @@ ColorPicker::ColorPicker() {
text_type->set_text("#");
text_type->set_tooltip_text(RTR("Switch between hexadecimal and code values."));
if (Engine::get_singleton()->is_editor_hint()) {
- text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled));
+ text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled));
} else {
text_type->set_flat(true);
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
@@ -1950,7 +1950,7 @@ ColorPicker::ColorPicker() {
c_text->set_placeholder(ETR("Hex code or named color"));
c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted));
c_text->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed));
- c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
+ c_text->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_html_focus_exit));
wheel_edit = memnew(AspectRatioContainer);
wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1969,19 +1969,19 @@ ColorPicker::ColorPicker() {
wheel = memnew(Control);
wheel_margin->add_child(wheel);
wheel->set_mouse_filter(MOUSE_FILTER_PASS);
- wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel));
+ wheel->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel));
wheel_uv = memnew(Control);
wheel_margin->add_child(wheel_uv);
- wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv));
- wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv));
+ wheel_uv->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv));
+ wheel_uv->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv));
w_edit = memnew(Control);
hb_edit->add_child(w_edit);
w_edit->set_h_size_flags(SIZE_FILL);
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
- w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit));
+ w_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_w_input));
+ w_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit));
_update_controls();
updating = false;
@@ -2026,7 +2026,7 @@ ColorPicker::ColorPicker() {
btn_add_preset = memnew(Button);
btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
btn_add_preset->set_tooltip_text(ETR("Add current color as a preset."));
- btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
+ btn_add_preset->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_add_preset_pressed));
preset_container->add_child(btn_add_preset);
}
@@ -2171,7 +2171,7 @@ void ColorPickerButton::_update_picker() {
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
popup->connect("about_to_popup", callable_mp(this, &ColorPickerButton::_about_to_popup));
popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed));
- picker->connect("minimum_size_changed", callable_mp((Window *)popup, &Window::reset_size));
+ picker->connect(SceneStringName(minimum_size_changed), callable_mp((Window *)popup, &Window::reset_size));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
picker->set_display_old_color(true);
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 5db8d69eef..f1faf3e899 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -30,8 +30,6 @@
#include "container.h"
-#include "scene/scene_string_names.h"
-
void Container::_child_minsize_changed() {
update_minimum_size();
queue_sort();
@@ -45,9 +43,9 @@ void Container::add_child_notify(Node *p_child) {
return;
}
- control->connect(SNAME("size_flags_changed"), callable_mp(this, &Container::queue_sort));
- control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed));
- control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed));
+ control->connect(SceneStringName(size_flags_changed), callable_mp(this, &Container::queue_sort));
+ control->connect(SceneStringName(minimum_size_changed), callable_mp(this, &Container::_child_minsize_changed));
+ control->connect(SceneStringName(visibility_changed), callable_mp(this, &Container::_child_minsize_changed));
update_minimum_size();
queue_sort();
@@ -72,9 +70,9 @@ void Container::remove_child_notify(Node *p_child) {
return;
}
- control->disconnect("size_flags_changed", callable_mp(this, &Container::queue_sort));
- control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed));
- control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed));
+ control->disconnect(SceneStringName(size_flags_changed), callable_mp(this, &Container::queue_sort));
+ control->disconnect(SceneStringName(minimum_size_changed), callable_mp(this, &Container::_child_minsize_changed));
+ control->disconnect(SceneStringName(visibility_changed), callable_mp(this, &Container::_child_minsize_changed));
update_minimum_size();
queue_sort();
@@ -86,10 +84,10 @@ void Container::_sort_children() {
}
notification(NOTIFICATION_PRE_SORT_CHILDREN);
- emit_signal(SceneStringNames::get_singleton()->pre_sort_children);
+ emit_signal(SceneStringName(pre_sort_children));
notification(NOTIFICATION_SORT_CHILDREN);
- emit_signal(SceneStringNames::get_singleton()->sort_children);
+ emit_signal(SceneStringName(sort_children));
pending_sort = false;
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 2dd12b92f3..0d5c69b207 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -42,7 +42,6 @@
#include "scene/gui/panel.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
-#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
#include "scene/theme/theme_owner.h"
#include "servers/rendering_server.h"
@@ -212,17 +211,17 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
const String pf = p_function;
Theme::DataType type = Theme::DATA_TYPE_MAX;
- if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") {
+ if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color" || pf == "remove_theme_color_override") {
type = Theme::DATA_TYPE_COLOR;
- } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") {
+ } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant" || pf == "remove_theme_constant_override") {
type = Theme::DATA_TYPE_CONSTANT;
- } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") {
+ } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font" || pf == "remove_theme_font_override") {
type = Theme::DATA_TYPE_FONT;
- } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") {
+ } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size" || pf == "remove_theme_font_size_override") {
type = Theme::DATA_TYPE_FONT_SIZE;
- } else if (pf == "add_theme_icon_override" || pf == "has_theme_icon" || pf == "has_theme_icon_override" || pf == "get_theme_icon") {
+ } else if (pf == "add_theme_icon_override" || pf == "has_theme_icon" || pf == "has_theme_icon_override" || pf == "get_theme_icon" || pf == "remove_theme_icon_override") {
type = Theme::DATA_TYPE_ICON;
- } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") {
+ } else if (pf == "add_theme_stylebox_override" || pf == "has_theme_stylebox" || pf == "has_theme_stylebox_override" || pf == "get_theme_stylebox" || pf == "remove_theme_stylebox_override") {
type = Theme::DATA_TYPE_STYLEBOX;
}
@@ -1606,7 +1605,7 @@ void Control::_update_minimum_size() {
if (minsize != data.last_minimum_size) {
data.last_minimum_size = minsize;
_size_changed();
- emit_signal(SceneStringNames::get_singleton()->minimum_size_changed);
+ emit_signal(SceneStringName(minimum_size_changed));
}
}
@@ -1770,7 +1769,7 @@ void Control::set_h_size_flags(BitField<SizeFlags> p_flags) {
return;
}
data.h_size_flags = p_flags;
- emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
+ emit_signal(SceneStringName(size_flags_changed));
}
BitField<Control::SizeFlags> Control::get_h_size_flags() const {
@@ -1784,7 +1783,7 @@ void Control::set_v_size_flags(BitField<SizeFlags> p_flags) {
return;
}
data.v_size_flags = p_flags;
- emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
+ emit_signal(SceneStringName(size_flags_changed));
}
BitField<Control::SizeFlags> Control::get_v_size_flags() const {
@@ -1799,7 +1798,7 @@ void Control::set_stretch_ratio(real_t p_ratio) {
}
data.expand = p_ratio;
- emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
+ emit_signal(SceneStringName(size_flags_changed));
}
real_t Control::get_stretch_ratio() const {
@@ -1811,7 +1810,7 @@ real_t Control::get_stretch_ratio() const {
void Control::_call_gui_input(const Ref<InputEvent> &p_event) {
if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
- emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); // Signal should be first, so it's possible to override an event (and then accept it).
+ emit_signal(SceneStringName(gui_input), p_event); // Signal should be first, so it's possible to override an event (and then accept it).
}
if (!is_inside_tree() || get_viewport()->is_input_handled()) {
return; // Input was handled, abort.
@@ -3223,7 +3222,7 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_READY: {
#ifdef DEBUG_ENABLED
- connect("ready", callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONE_SHOT);
+ connect(SceneStringName(ready), callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONE_SHOT);
#endif
} break;
@@ -3262,7 +3261,7 @@ void Control::_notification(int p_notification) {
data.parent_canvas_item = get_parent_item();
if (data.parent_canvas_item) {
- data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed));
+ data.parent_canvas_item->connect(SceneStringName(item_rect_changed), callable_mp(this, &Control::_size_changed));
} else {
// Connect viewport.
Viewport *viewport = get_viewport();
@@ -3273,7 +3272,7 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_EXIT_CANVAS: {
if (data.parent_canvas_item) {
- data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed));
+ data.parent_canvas_item->disconnect(SceneStringName(item_rect_changed), callable_mp(this, &Control::_size_changed));
data.parent_canvas_item = nullptr;
} else {
// Disconnect viewport.
@@ -3299,7 +3298,7 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_RESIZED: {
- emit_signal(SceneStringNames::get_singleton()->resized);
+ emit_signal(SceneStringName(resized));
} break;
case NOTIFICATION_DRAW: {
@@ -3309,25 +3308,25 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_MOUSE_ENTER: {
- emit_signal(SceneStringNames::get_singleton()->mouse_entered);
+ emit_signal(SceneStringName(mouse_entered));
} break;
case NOTIFICATION_MOUSE_EXIT: {
- emit_signal(SceneStringNames::get_singleton()->mouse_exited);
+ emit_signal(SceneStringName(mouse_exited));
} break;
case NOTIFICATION_FOCUS_ENTER: {
- emit_signal(SceneStringNames::get_singleton()->focus_entered);
+ emit_signal(SceneStringName(focus_entered));
queue_redraw();
} break;
case NOTIFICATION_FOCUS_EXIT: {
- emit_signal(SceneStringNames::get_singleton()->focus_exited);
+ emit_signal(SceneStringName(focus_exited));
queue_redraw();
} break;
case NOTIFICATION_THEME_CHANGED: {
- emit_signal(SceneStringNames::get_singleton()->theme_changed);
+ emit_signal(SceneStringName(theme_changed));
_invalidate_theme_cache();
_update_theme_item_cache();
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 4d2080dda2..3d8be38fbd 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -47,7 +47,7 @@ void AcceptDialog::_input_from_window(const Ref<InputEvent> &p_event) {
}
void AcceptDialog::_parent_focused() {
- if (!is_exclusive() && get_flag(FLAG_POPUP)) {
+ if (popped_up && !is_exclusive() && get_flag(FLAG_POPUP)) {
_cancel_pressed();
}
}
@@ -68,16 +68,25 @@ void AcceptDialog::_notification(int p_what) {
parent_visible = get_parent_visible_window();
if (parent_visible) {
- parent_visible->connect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused));
+ parent_visible->connect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused));
}
} else {
+ popped_up = false;
if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused));
+ parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused));
parent_visible = nullptr;
}
}
} break;
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
+ if (!is_in_edited_scene_root()) {
+ if (has_focus()) {
+ popped_up = true;
+ }
+ }
+ } break;
+
case NOTIFICATION_THEME_CHANGED: {
bg_panel->add_theme_style_override("panel", theme_cache.panel_style);
@@ -89,7 +98,7 @@ void AcceptDialog::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused));
+ parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused));
parent_visible = nullptr;
}
} break;
@@ -114,8 +123,14 @@ void AcceptDialog::_text_submitted(const String &p_text) {
_ok_pressed();
}
+void AcceptDialog::_post_popup() {
+ Window::_post_popup();
+ popped_up = true;
+}
+
void AcceptDialog::_ok_pressed() {
if (hide_on_ok) {
+ popped_up = false;
set_visible(false);
}
ok_pressed();
@@ -124,9 +139,10 @@ void AcceptDialog::_ok_pressed() {
}
void AcceptDialog::_cancel_pressed() {
+ popped_up = false;
Window *parent_window = parent_visible;
if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused));
+ parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused));
parent_visible = nullptr;
}
@@ -308,7 +324,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
}
button->set_meta("__right_spacer", right_spacer);
- button->connect("visibility_changed", callable_mp(this, &AcceptDialog::_custom_button_visibility_changed).bind(button));
+ button->connect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed).bind(button));
child_controls_changed();
if (is_visible()) {
@@ -316,7 +332,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
}
if (!p_action.is_empty()) {
- button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action).bind(p_action));
+ button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action).bind(p_action));
}
return button;
@@ -330,7 +346,7 @@ Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
- b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
+ b->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed));
return b;
}
@@ -345,12 +361,12 @@ void AcceptDialog::remove_button(Button *p_button) {
ERR_FAIL_COND_MSG(right_spacer->get_parent() != buttons_hbox, vformat("Cannot remove button %s as its associated spacer does not belong to this dialog.", p_button->get_name()));
}
- p_button->disconnect("visibility_changed", callable_mp(this, &AcceptDialog::_custom_button_visibility_changed));
- if (p_button->is_connected("pressed", callable_mp(this, &AcceptDialog::_custom_action))) {
- p_button->disconnect("pressed", callable_mp(this, &AcceptDialog::_custom_action));
+ p_button->disconnect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed));
+ if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action))) {
+ p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action));
}
- if (p_button->is_connected("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed))) {
- p_button->disconnect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
+ if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed))) {
+ p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed));
}
if (right_spacer) {
@@ -433,7 +449,7 @@ AcceptDialog::AcceptDialog() {
buttons_hbox->add_child(ok_button);
buttons_hbox->add_spacer();
- ok_button->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed));
+ ok_button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_ok_pressed));
set_title(ETR("Alert!"));
}
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 12b48c903a..404237bfd8 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -51,6 +51,7 @@ class AcceptDialog : public Window {
HBoxContainer *buttons_hbox = nullptr;
Button *ok_button = nullptr;
+ bool popped_up = false;
bool hide_on_ok = true;
bool close_on_escape = true;
@@ -72,6 +73,7 @@ class AcceptDialog : public Window {
protected:
virtual Size2 _get_contents_minimum_size() const override;
virtual void _input_from_window(const Ref<InputEvent> &p_event) override;
+ virtual void _post_popup() override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 97a2917dc1..0c146ce173 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -1344,6 +1344,7 @@ void FileDialog::_bind_methods() {
Option defaults;
base_property_helper.set_prefix("option_");
+ base_property_helper.set_array_length_getter(&FileDialog::get_option_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults.name, &FileDialog::set_option_name, &FileDialog::get_option_name);
base_property_helper.register_property(PropertyInfo(Variant::PACKED_STRING_ARRAY, "values"), defaults.values, &FileDialog::set_option_values, &FileDialog::get_option_values);
base_property_helper.register_property(PropertyInfo(Variant::INT, "default"), defaults.default_idx, &FileDialog::set_option_default, &FileDialog::get_option_default);
@@ -1408,9 +1409,9 @@ FileDialog::FileDialog() {
hbc->add_child(dir_prev);
hbc->add_child(dir_next);
hbc->add_child(dir_up);
- dir_prev->connect("pressed", callable_mp(this, &FileDialog::_go_back));
- dir_next->connect("pressed", callable_mp(this, &FileDialog::_go_forward));
- dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up));
+ dir_prev->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_back));
+ dir_next->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_forward));
+ dir_up->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_up));
hbc->add_child(memnew(Label(ETR("Path:"))));
@@ -1429,7 +1430,7 @@ FileDialog::FileDialog() {
refresh = memnew(Button);
refresh->set_theme_type_variation("FlatButton");
refresh->set_tooltip_text(ETR("Refresh files."));
- refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list));
+ refresh->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::update_file_list));
hbc->add_child(refresh);
show_hidden = memnew(Button);
@@ -1446,7 +1447,7 @@ FileDialog::FileDialog() {
makedir = memnew(Button);
makedir->set_theme_type_variation("FlatButton");
makedir->set_tooltip_text(ETR("Create a new folder."));
- makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir));
+ makedir->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_make_dir));
hbc->add_child(makedir);
vbox->add_child(hbc);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 646e45b27a..6c2a61d255 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -601,7 +601,7 @@ void GraphEdit::add_child_notify(Node *p_child) {
GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element);
if (graph_node) {
graph_node->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(graph_element));
- graph_node->connect("item_rect_changed", callable_mp(this, &GraphEdit::_graph_node_rect_changed).bind(graph_node));
+ graph_node->connect(SceneStringName(item_rect_changed), callable_mp(this, &GraphEdit::_graph_node_rect_changed).bind(graph_node));
_ensure_node_order_from(graph_node);
}
@@ -618,8 +618,8 @@ void GraphEdit::add_child_notify(Node *p_child) {
}
graph_element->connect("raise_request", callable_mp(this, &GraphEdit::_ensure_node_order_from).bind(graph_element));
graph_element->connect("resize_request", callable_mp(this, &GraphEdit::_graph_element_resize_request).bind(graph_element));
- graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
- graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
+ graph_element->connect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw));
+ graph_element->connect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
graph_element->set_scale(Vector2(zoom, zoom));
_graph_element_moved(graph_element);
@@ -651,7 +651,7 @@ void GraphEdit::remove_child_notify(Node *p_child) {
GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element);
if (graph_node) {
graph_node->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated));
- graph_node->disconnect("item_rect_changed", callable_mp(this, &GraphEdit::_graph_node_rect_changed));
+ graph_node->disconnect(SceneStringName(item_rect_changed), callable_mp(this, &GraphEdit::_graph_node_rect_changed));
// Invalidate all adjacent connections, so that they are removed before the next redraw.
for (const Ref<Connection> &conn : connection_map[graph_node->get_name()]) {
@@ -692,7 +692,7 @@ void GraphEdit::remove_child_notify(Node *p_child) {
// In case of the whole GraphEdit being destroyed these references can already be freed.
if (minimap != nullptr && minimap->is_inside_tree()) {
- graph_element->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
+ graph_element->disconnect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw));
}
}
}
@@ -898,6 +898,12 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
return true;
}
}
+
+ // This prevents interactions with a port hotzone that is behind another node.
+ Rect2 graph_node_rect = Rect2(graph_node->get_position(), graph_node->get_size() * zoom);
+ if (graph_node_rect.has_point(click_pos * zoom)) {
+ break;
+ }
}
return false;
@@ -1027,6 +1033,12 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
return;
}
}
+
+ // This prevents interactions with a port hotzone that is behind another node.
+ Rect2 graph_node_rect = Rect2(graph_node->get_position(), graph_node->get_size() * zoom);
+ if (graph_node_rect.has_point(click_pos * zoom)) {
+ break;
+ }
}
}
@@ -1059,7 +1071,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
int type = graph_node->get_output_port_type(j);
- if ((type == connecting_type ||
+ if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() ||
valid_connection_types.has(ConnectionType(type, connecting_type))) &&
is_in_output_hotzone(graph_node, j, mpos, port_size)) {
if (!is_node_hover_valid(graph_node->get_name(), j, connecting_from_node, connecting_from_port_index)) {
@@ -1084,7 +1096,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
port_size.height = MAX(port_size.height, child ? child->get_size().y : 0);
int type = graph_node->get_input_port_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnectionType(connecting_type, type))) &&
+ if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(connecting_type, type))) &&
is_in_input_hotzone(graph_node, j, mpos, port_size)) {
if (!is_node_hover_valid(connecting_from_node, connecting_from_port_index, graph_node->get_name(), j)) {
continue;
@@ -1117,6 +1129,8 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
emit_signal(SNAME("connection_from_empty"), connecting_from_node, connecting_from_port_index, mb->get_position());
}
}
+ } else {
+ set_selected(get_node_or_null(NodePath(connecting_from_node)));
}
if (connecting) {
@@ -1285,18 +1299,26 @@ List<Ref<GraphEdit::Connection>> GraphEdit::get_connections_intersecting_with_re
return intersecting_connections;
}
-void GraphEdit::_draw_minimap_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_from_color, const Color &p_to_color) {
- const Vector<Vector2> &points = get_connection_line(p_from, p_to);
+void GraphEdit::_draw_minimap_connection_line(const Vector2 &p_from_graph_position, const Vector2 &p_to_graph_position, const Color &p_from_color, const Color &p_to_color) {
+ Vector<Vector2> points = get_connection_line(p_from_graph_position, p_to_graph_position);
+ ERR_FAIL_COND_MSG(points.size() < 2, "\"_get_connection_line()\" returned an invalid line.");
+ // Convert to minimap points.
+ for (Vector2 &point : points) {
+ point = minimap->_convert_from_graph_position(point) + minimap->minimap_offset;
+ }
+
+ // Setup polyline colors.
LocalVector<Color> colors;
colors.reserve(points.size());
-
- float length_inv = 1.0 / (p_from).distance_to(p_to);
+ const Vector2 &from = points[0];
+ const Vector2 &to = points[points.size() - 1];
+ float length_inv = 1.0 / (from).distance_to(to);
for (const Vector2 &point : points) {
- float normalized_curve_position = (p_from).distance_to(point) * length_inv;
+ float normalized_curve_position = from.distance_to(point) * length_inv;
colors.push_back(p_from_color.lerp(p_to_color, normalized_curve_position));
}
- p_where->draw_polyline_colors(points, colors, 0.5, lines_antialiased);
+ minimap->draw_polyline_colors(points, colors, 0.5, lines_antialiased);
}
void GraphEdit::_update_connections() {
@@ -1551,8 +1573,8 @@ void GraphEdit::_minimap_draw() {
// Draw node connections.
for (const Ref<Connection> &c : connections) {
- Vector2 from_position = minimap->_convert_from_graph_position(c->_cache.from_pos * zoom - graph_offset) + minimap_offset;
- Vector2 to_position = minimap->_convert_from_graph_position(c->_cache.to_pos * zoom - graph_offset) + minimap_offset;
+ Vector2 from_graph_position = c->_cache.from_pos * zoom - graph_offset;
+ Vector2 to_graph_position = c->_cache.to_pos * zoom - graph_offset;
Color from_color = c->_cache.from_color;
Color to_color = c->_cache.to_color;
@@ -1560,7 +1582,8 @@ void GraphEdit::_minimap_draw() {
from_color = from_color.lerp(theme_cache.activity_color, c->activity);
to_color = to_color.lerp(theme_cache.activity_color, c->activity);
}
- _draw_minimap_connection_line(minimap, from_position, to_position, from_color, to_color);
+
+ _draw_minimap_connection_line(from_graph_position, to_graph_position, from_color, to_color);
}
// Draw the "camera" viewport.
@@ -1636,12 +1659,12 @@ void GraphEdit::_draw_grid() {
void GraphEdit::set_selected(Node *p_child) {
for (int i = get_child_count() - 1; i >= 0; i--) {
- GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
- if (!graph_node) {
+ GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i));
+ if (!graph_element) {
continue;
}
- graph_node->set_selected(graph_node == p_child);
+ graph_element->set_selected(graph_element == p_child);
}
}
@@ -2755,12 +2778,12 @@ GraphEdit::GraphEdit() {
add_child(top_layer, false, INTERNAL_MODE_BACK);
top_layer->set_mouse_filter(MOUSE_FILTER_IGNORE);
top_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
- top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw));
- top_layer->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
+ top_layer->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_top_layer_draw));
+ top_layer->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
connections_layer = memnew(Control);
add_child(connections_layer, false);
- connections_layer->connect("draw", callable_mp(this, &GraphEdit::_update_connections));
+ connections_layer->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_update_connections));
connections_layer->set_name("_connection_layer");
connections_layer->set_disable_visibility_clip(true); // Necessary, so it can draw freely and be offset.
connections_layer->set_mouse_filter(MOUSE_FILTER_IGNORE);
@@ -2772,7 +2795,7 @@ GraphEdit::GraphEdit() {
top_connection_layer->set_mouse_filter(MOUSE_FILTER_PASS);
top_connection_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
- top_connection_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_connection_layer_input));
+ top_connection_layer->connect(SceneStringName(gui_input), callable_mp(this, &GraphEdit::_top_connection_layer_input));
dragged_connection_line = memnew(Line2D);
dragged_connection_line->set_texture_mode(Line2D::LINE_TEXTURE_STRETCH);
@@ -2822,7 +2845,7 @@ GraphEdit::GraphEdit() {
zoom_minus_button->set_tooltip_text(ETR("Zoom Out"));
zoom_minus_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(zoom_minus_button);
- zoom_minus_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_minus));
+ zoom_minus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_minus));
zoom_reset_button = memnew(Button);
zoom_reset_button->set_theme_type_variation("FlatButton");
@@ -2830,7 +2853,7 @@ GraphEdit::GraphEdit() {
zoom_reset_button->set_tooltip_text(ETR("Zoom Reset"));
zoom_reset_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(zoom_reset_button);
- zoom_reset_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_reset));
+ zoom_reset_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_reset));
zoom_plus_button = memnew(Button);
zoom_plus_button->set_theme_type_variation("FlatButton");
@@ -2838,7 +2861,7 @@ GraphEdit::GraphEdit() {
zoom_plus_button->set_tooltip_text(ETR("Zoom In"));
zoom_plus_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(zoom_plus_button);
- zoom_plus_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_plus));
+ zoom_plus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_plus));
// Grid controls.
@@ -2850,7 +2873,7 @@ GraphEdit::GraphEdit() {
toggle_grid_button->set_tooltip_text(ETR("Toggle the visual grid."));
toggle_grid_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(toggle_grid_button);
- toggle_grid_button->connect("pressed", callable_mp(this, &GraphEdit::_show_grid_toggled));
+ toggle_grid_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_show_grid_toggled));
toggle_snapping_button = memnew(Button);
toggle_snapping_button->set_theme_type_variation("FlatButton");
@@ -2860,7 +2883,7 @@ GraphEdit::GraphEdit() {
toggle_snapping_button->set_pressed(snapping_enabled);
toggle_snapping_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(toggle_snapping_button);
- toggle_snapping_button->connect("pressed", callable_mp(this, &GraphEdit::_snapping_toggled));
+ toggle_snapping_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_snapping_toggled));
snapping_distance_spinbox = memnew(SpinBox);
snapping_distance_spinbox->set_visible(show_grid_buttons);
@@ -2882,12 +2905,12 @@ GraphEdit::GraphEdit() {
minimap_button->set_pressed(show_grid);
minimap_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(minimap_button);
- minimap_button->connect("pressed", callable_mp(this, &GraphEdit::_minimap_toggled));
+ minimap_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_minimap_toggled));
arrange_button = memnew(Button);
arrange_button->set_theme_type_variation("FlatButton");
arrange_button->set_visible(show_arrange_button);
- arrange_button->connect("pressed", callable_mp(this, &GraphEdit::arrange_nodes));
+ arrange_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::arrange_nodes));
arrange_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(arrange_button);
arrange_button->set_tooltip_text(ETR("Automatically arrange selected nodes."));
@@ -2909,7 +2932,7 @@ GraphEdit::GraphEdit() {
minimap->set_offset(Side::SIDE_TOP, -minimap_size.height - MINIMAP_OFFSET);
minimap->set_offset(Side::SIDE_RIGHT, -MINIMAP_OFFSET);
minimap->set_offset(Side::SIDE_BOTTOM, -MINIMAP_OFFSET);
- minimap->connect("draw", callable_mp(this, &GraphEdit::_minimap_draw));
+ minimap->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_minimap_draw));
set_clip_contents(true);
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index eeda9ae200..20c98c462c 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -328,7 +328,7 @@ private:
void _top_connection_layer_input(const Ref<InputEvent> &p_ev);
float _get_shader_line_width();
- void _draw_minimap_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color);
+ void _draw_minimap_connection_line(const Vector2 &p_from_graph_position, const Vector2 &p_to_graph_position, const Color &p_from_color, const Color &p_to_color);
void _invalidate_connection_line_cache();
void _update_top_connection_layer();
void _update_connections();
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 75ac5c5135..d804f83e1c 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -604,6 +604,14 @@ void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) {
emit_signal(SNAME("slot_updated"), p_slot_index);
}
+void GraphNode::set_ignore_invalid_connection_type(bool p_ignore) {
+ ignore_invalid_connection_type = p_ignore;
+}
+
+bool GraphNode::is_ignoring_valid_connection_type() const {
+ return ignore_invalid_connection_type;
+}
+
Size2 GraphNode::get_minimum_size() const {
Ref<StyleBox> sb_panel = theme_cache.panel;
Ref<StyleBox> sb_titlebar = theme_cache.titlebar;
@@ -859,6 +867,9 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "slot_index"), &GraphNode::is_slot_draw_stylebox);
ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "slot_index", "enable"), &GraphNode::set_slot_draw_stylebox);
+ ClassDB::bind_method(D_METHOD("set_ignore_invalid_connection_type", "ignore"), &GraphNode::set_ignore_invalid_connection_type);
+ ClassDB::bind_method(D_METHOD("is_ignoring_valid_connection_type"), &GraphNode::is_ignoring_valid_connection_type);
+
ClassDB::bind_method(D_METHOD("get_input_port_count"), &GraphNode::get_input_port_count);
ClassDB::bind_method(D_METHOD("get_input_port_position", "port_idx"), &GraphNode::get_input_port_position);
ClassDB::bind_method(D_METHOD("get_input_port_type", "port_idx"), &GraphNode::get_input_port_type);
@@ -874,6 +885,8 @@ void GraphNode::_bind_methods() {
GDVIRTUAL_BIND(_draw_port, "slot_index", "position", "left", "color")
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_invalid_connection_type"), "set_ignore_invalid_connection_type", "is_ignoring_valid_connection_type");
+
ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index")));
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel);
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 71cc322baa..27af3192c8 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -95,6 +95,8 @@ class GraphNode : public GraphElement {
bool port_pos_dirty = true;
+ bool ignore_invalid_connection_type = false;
+
void _port_pos_update();
protected:
@@ -147,6 +149,9 @@ public:
bool is_slot_draw_stylebox(int p_slot_index) const;
void set_slot_draw_stylebox(int p_slot_index, bool p_enable);
+ void set_ignore_invalid_connection_type(bool p_ignore);
+ bool is_ignoring_valid_connection_type() const;
+
int get_input_port_count();
Vector2 get_input_port_position(int p_port_idx);
int get_input_port_type(int p_port_idx);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 8376ef48b6..cfb46aebc8 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -1882,6 +1882,7 @@ void ItemList::_bind_methods() {
Item defaults(true);
base_property_helper.set_prefix("item_");
+ base_property_helper.set_array_length_getter(&ItemList::get_item_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &ItemList::set_item_text, &ItemList::get_item_text);
base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &ItemList::set_item_icon, &ItemList::get_item_icon);
base_property_helper.register_property(PropertyInfo(Variant::BOOL, "selectable"), defaults.selectable, &ItemList::set_item_selectable, &ItemList::is_item_selectable);
@@ -1893,7 +1894,7 @@ ItemList::ItemList() {
add_child(scroll_bar, false, INTERNAL_MODE_FRONT);
scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed));
- connect("mouse_exited", callable_mp(this, &ItemList::_mouse_exited));
+ connect(SceneStringName(mouse_exited), callable_mp(this, &ItemList::_mouse_exited));
set_focus_mode(FOCUS_ALL);
set_clip_contents(true);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index c263e14b8a..729e219825 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -2473,8 +2473,8 @@ void LineEdit::_generate_context_menu() {
menu_dir->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
menu_ctl->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
- menu->connect(SNAME("focus_entered"), callable_mp(this, &LineEdit::_validate_caret_can_draw));
- menu->connect(SNAME("focus_exited"), callable_mp(this, &LineEdit::_validate_caret_can_draw));
+ menu->connect(SceneStringName(focus_entered), callable_mp(this, &LineEdit::_validate_caret_can_draw));
+ menu->connect(SceneStringName(focus_exited), callable_mp(this, &LineEdit::_validate_caret_can_draw));
}
void LineEdit::_update_context_menu() {
diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp
index 91e6c1f092..06e4a7cc13 100644
--- a/scene/gui/margin_container.cpp
+++ b/scene/gui/margin_container.cpp
@@ -36,8 +36,8 @@ Size2 MarginContainer::get_minimum_size() const {
Size2 max;
for (int i = 0; i < get_child_count(); i++) {
- Control *c = as_sortable_control(get_child(i));
- if (!c) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c || !c->is_visible() || c->is_set_as_top_level()) {
continue;
}
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index e83d9c7c1b..998f99b2f9 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -190,6 +190,7 @@ void MenuButton::_bind_methods() {
PopupMenu::Item defaults(true);
base_property_helper.set_prefix("popup/item_");
+ base_property_helper.set_array_length_getter(&MenuButton::get_item_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text);
base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon);
base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As Checkbox,As Radio Button"), defaults.checkable_type);
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index e2ae824e60..f9181d2a2d 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -30,7 +30,6 @@
#include "nine_patch_rect.h"
-#include "scene/scene_string_names.h"
#include "servers/rendering_server.h"
void NinePatchRect::_notification(int p_what) {
@@ -111,7 +110,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
queue_redraw();
update_minimum_size();
- emit_signal(SceneStringNames::get_singleton()->texture_changed);
+ emit_signal(SceneStringName(texture_changed));
}
Ref<Texture2D> NinePatchRect::get_texture() const {
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 509c6aca99..68e72ea996 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -60,7 +60,7 @@ Size2 OptionButton::get_minimum_size() const {
}
if (has_theme_icon(SNAME("arrow"))) {
- const Size2 padding = _get_current_stylebox()->get_minimum_size();
+ const Size2 padding = _get_largest_stylebox_size();
const Size2 arrow_size = theme_cache.arrow_icon->get_size();
Size2 content_size = minsize - padding;
@@ -571,6 +571,7 @@ void OptionButton::_bind_methods() {
PopupMenu::Item defaults(true);
base_property_helper.set_prefix("popup/item_");
+ base_property_helper.set_array_length_getter(&OptionButton::get_item_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &OptionButton::_dummy_setter, &OptionButton::get_item_text);
base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &OptionButton::_dummy_setter, &OptionButton::get_item_icon);
base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), defaults.id, &OptionButton::_dummy_setter, &OptionButton::get_item_id);
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 97b33c4f74..38204af6d5 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -37,6 +37,7 @@
void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
if (get_flag(FLAG_POPUP) && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) {
+ hide_reason = HIDE_REASON_CANCELED; // ESC pressed, mark as canceled unconditionally.
_close_pressed();
}
Window::_input_from_window(p_event);
@@ -51,8 +52,8 @@ void Popup::_initialize_visible_parents() {
parent_window = parent_window->get_parent_visible_window();
if (parent_window) {
visible_parents.push_back(parent_window);
- parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
+ parent_window->connect(SceneStringName(focus_entered), callable_mp(this, &Popup::_parent_focused));
+ parent_window->connect(SceneStringName(tree_exited), callable_mp(this, &Popup::_deinitialize_visible_parents));
}
}
}
@@ -61,8 +62,8 @@ void Popup::_initialize_visible_parents() {
void Popup::_deinitialize_visible_parents() {
if (is_embedded()) {
for (Window *parent_window : visible_parents) {
- parent_window->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- parent_window->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
+ parent_window->disconnect(SceneStringName(focus_entered), callable_mp(this, &Popup::_parent_focused));
+ parent_window->disconnect(SceneStringName(tree_exited), callable_mp(this, &Popup::_deinitialize_visible_parents));
}
visible_parents.clear();
@@ -104,13 +105,18 @@ void Popup::_notification(int p_what) {
case NOTIFICATION_WM_CLOSE_REQUEST: {
if (!is_in_edited_scene_root()) {
- hide_reason = HIDE_REASON_UNFOCUSED;
+ if (hide_reason == HIDE_REASON_NONE) {
+ hide_reason = HIDE_REASON_UNFOCUSED;
+ }
_close_pressed();
}
} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
if (!is_in_edited_scene_root() && get_flag(FLAG_POPUP)) {
+ if (hide_reason == HIDE_REASON_NONE) {
+ hide_reason = HIDE_REASON_UNFOCUSED;
+ }
_close_pressed();
}
} break;
@@ -119,7 +125,9 @@ void Popup::_notification(int p_what) {
void Popup::_parent_focused() {
if (popped_up && get_flag(FLAG_POPUP)) {
- hide_reason = HIDE_REASON_UNFOCUSED;
+ if (hide_reason == HIDE_REASON_NONE) {
+ hide_reason = HIDE_REASON_UNFOCUSED;
+ }
_close_pressed();
}
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 9b991972be..bdd0102b63 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1014,9 +1014,6 @@ void PopupMenu::_notification(int p_what) {
float pm_delay = pm->get_submenu_popup_delay();
set_submenu_popup_delay(pm_delay);
}
- if (!is_embedded()) {
- set_flag(FLAG_NO_FOCUS, true);
- }
if (system_menu_id != NativeMenu::INVALID_MENU_ID) {
bind_global_menu();
}
@@ -2808,6 +2805,7 @@ void PopupMenu::_bind_methods() {
Item defaults(true);
base_property_helper.set_prefix("item_");
+ base_property_helper.set_array_length_getter(&PopupMenu::get_item_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &PopupMenu::set_item_text, &PopupMenu::get_item_text);
base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &PopupMenu::set_item_icon, &PopupMenu::get_item_icon);
base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button"), defaults.checkable_type, &PopupMenu::_set_item_checkable_type, &PopupMenu::_get_item_checkable_type);
@@ -2828,6 +2826,8 @@ void PopupMenu::popup(const Rect2i &p_bounds) {
if (native) {
NativeMenu::get_singleton()->popup(global_menu, (p_bounds != Rect2i()) ? p_bounds.position : get_position());
} else {
+ set_flag(FLAG_NO_FOCUS, !is_embedded());
+
moved = Vector2();
popup_time_msec = OS::get_singleton()->get_ticks_msec();
if (!is_embedded()) {
@@ -2855,6 +2855,8 @@ void PopupMenu::set_visible(bool p_visible) {
NativeMenu::get_singleton()->popup(global_menu, get_position());
}
} else {
+ set_flag(FLAG_NO_FOCUS, !is_embedded());
+
Popup::set_visible(p_visible);
}
}
@@ -2873,7 +2875,7 @@ PopupMenu::PopupMenu() {
control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
control->set_v_size_flags(Control::SIZE_EXPAND_FILL);
scroll_container->add_child(control, false, INTERNAL_MODE_FRONT);
- control->connect("draw", callable_mp(this, &PopupMenu::_draw_items));
+ control->connect(SceneStringName(draw), callable_mp(this, &PopupMenu::_draw_items));
submenu_timer = memnew(Timer);
submenu_timer->set_wait_time(0.3);
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 236dfcc864..00f4a1089a 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -60,7 +60,7 @@ void Range::Shared::emit_value_changed() {
}
void Range::_changed_notify(const char *p_what) {
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
queue_redraw();
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 19b02f33c6..f6942ca206 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -39,7 +39,6 @@
#include "scene/gui/label.h"
#include "scene/gui/rich_text_effect.h"
#include "scene/resources/atlas_texture.h"
-#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
#include "servers/display_server.h"
@@ -1608,8 +1607,34 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (p_meta) {
int64_t glyph_idx = TS->shaped_text_hit_test_grapheme(rid, p_click.x - rect.position.x);
if (glyph_idx >= 0) {
+ float baseline_y = rect.position.y + TS->shaped_text_get_ascent(rid);
const Glyph *glyphs = TS->shaped_text_get_glyphs(rid);
- char_pos = glyphs[glyph_idx].start;
+ if (glyphs[glyph_idx].flags & TextServer::GRAPHEME_IS_EMBEDDED_OBJECT) {
+ // Emebedded object.
+ for (int i = 0; i < objects.size(); i++) {
+ if (TS->shaped_text_get_object_glyph(rid, objects[i]) == glyph_idx) {
+ Rect2 obj_rect = TS->shaped_text_get_object_rect(rid, objects[i]);
+ obj_rect.position.y += baseline_y;
+ if (p_click.y >= obj_rect.position.y && p_click.y <= obj_rect.position.y + obj_rect.size.y) {
+ char_pos = glyphs[glyph_idx].start;
+ }
+ break;
+ }
+ }
+ } else if (glyphs[glyph_idx].font_rid != RID()) {
+ // Normal glyph.
+ float fa = TS->font_get_ascent(glyphs[glyph_idx].font_rid, glyphs[glyph_idx].font_size);
+ float fd = TS->font_get_descent(glyphs[glyph_idx].font_rid, glyphs[glyph_idx].font_size);
+ if (p_click.y >= baseline_y - fa && p_click.y <= baseline_y + fd) {
+ char_pos = glyphs[glyph_idx].start;
+ }
+ } else if (!(glyphs[glyph_idx].flags & TextServer::GRAPHEME_IS_VIRTUAL)) {
+ // Hex code box.
+ Vector2 gl_size = TS->get_hex_code_box_size(glyphs[glyph_idx].font_size, glyphs[glyph_idx].index);
+ if (p_click.y >= baseline_y - gl_size.y * 0.9 && p_click.y <= baseline_y + gl_size.y * 0.2) {
+ char_pos = glyphs[glyph_idx].start;
+ }
+ }
}
} else {
char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
@@ -2993,7 +3018,7 @@ void RichTextLabel::_process_line_caches() {
if (fit_content) {
update_minimum_size();
}
- emit_signal(SNAME("finished"));
+ emit_signal(SceneStringName(finished));
}
void RichTextLabel::_invalidate_current_line(ItemFrame *p_frame) {
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index b35c4e9308..af9f08e389 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -310,15 +310,15 @@ void ScrollBar::_notification(int p_what) {
}
if (drag_node) {
- drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
- drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT);
+ drag_node->connect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input));
+ drag_node->connect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT);
}
} break;
case NOTIFICATION_EXIT_TREE: {
if (drag_node) {
- drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
- drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit));
+ drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input));
+ drag_node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit));
}
drag_node = nullptr;
@@ -522,7 +522,7 @@ float ScrollBar::get_custom_step() const {
void ScrollBar::_drag_node_exit() {
if (drag_node) {
- drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
+ drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input));
}
drag_node = nullptr;
}
@@ -591,8 +591,8 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
void ScrollBar::set_drag_node(const NodePath &p_path) {
if (is_inside_tree()) {
if (drag_node) {
- drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
- drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit));
+ drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input));
+ drag_node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit));
}
}
@@ -606,8 +606,8 @@ void ScrollBar::set_drag_node(const NodePath &p_path) {
}
if (drag_node) {
- drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
- drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT);
+ drag_node->connect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input));
+ drag_node->connect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT);
}
}
}
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 70acaf7adf..bfea7b0fbe 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -409,9 +409,9 @@ SpinBox::SpinBox() {
line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), CONNECT_DEFERRED);
- line_edit->connect("focus_entered", callable_mp(this, &SpinBox::_line_edit_focus_enter), CONNECT_DEFERRED);
- line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED);
- line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input));
+ line_edit->connect(SceneStringName(focus_entered), callable_mp(this, &SpinBox::_line_edit_focus_enter), CONNECT_DEFERRED);
+ line_edit->connect(SceneStringName(focus_exited), callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED);
+ line_edit->connect(SceneStringName(gui_input), callable_mp(this, &SpinBox::_line_edit_input));
range_click_timer = memnew(Timer);
range_click_timer->connect("timeout", callable_mp(this, &SpinBox::_range_click_timeout));
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 98b1db4a96..925600756a 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -39,7 +39,7 @@ void SplitContainerDragger::gui_input(const Ref<InputEvent> &p_event) {
SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent());
- if (sc->collapsed || !sc->get_containable_child(0) || !sc->get_containable_child(1) || sc->dragger_visibility != SplitContainer::DRAGGER_VISIBLE) {
+ if (sc->collapsed || !sc->_get_sortable_child(0) || !sc->_get_sortable_child(1) || sc->dragger_visibility != SplitContainer::DRAGGER_VISIBLE) {
return;
}
@@ -122,12 +122,12 @@ void SplitContainerDragger::_notification(int p_what) {
}
}
-Control *SplitContainer::get_containable_child(int p_idx) const {
+Control *SplitContainer::_get_sortable_child(int p_idx) const {
int idx = 0;
for (int i = 0; i < get_child_count(false); i++) {
- Control *c = Object::cast_to<Control>(get_child(i, false));
- if (!c || !c->is_visible() || c->is_set_as_top_level()) {
+ Control *c = as_sortable_control(get_child(i, false));
+ if (!c) {
continue;
}
@@ -154,8 +154,8 @@ Ref<Texture2D> SplitContainer::_get_grabber_icon() const {
}
void SplitContainer::_compute_middle_sep(bool p_clamp) {
- Control *first = get_containable_child(0);
- Control *second = get_containable_child(1);
+ Control *first = _get_sortable_child(0);
+ Control *second = _get_sortable_child(1);
// Determine expanded children.
bool first_expanded = (vertical ? first->get_v_size_flags() : first->get_h_size_flags()) & SIZE_EXPAND;
@@ -196,8 +196,8 @@ void SplitContainer::_compute_middle_sep(bool p_clamp) {
}
void SplitContainer::_resort() {
- Control *first = get_containable_child(0);
- Control *second = get_containable_child(1);
+ Control *first = _get_sortable_child(0);
+ Control *second = _get_sortable_child(1);
// If we have only one element.
if (!first || !second) {
@@ -258,7 +258,7 @@ Size2 SplitContainer::get_minimum_size() const {
int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0;
for (int i = 0; i < 2; i++) {
- if (!get_containable_child(i)) {
+ if (!_get_sortable_child(i)) {
break;
}
@@ -270,7 +270,7 @@ Size2 SplitContainer::get_minimum_size() const {
}
}
- Size2 ms = get_containable_child(i)->get_combined_minimum_size();
+ Size2 ms = _get_sortable_child(i)->get_combined_minimum_size();
if (vertical) {
minimum.height += ms.height;
@@ -322,7 +322,7 @@ int SplitContainer::get_split_offset() const {
}
void SplitContainer::clamp_split_offset() {
- if (!get_containable_child(0) || !get_containable_child(1)) {
+ if (!_get_sortable_child(0) || !_get_sortable_child(1)) {
return;
}
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index 0f45ef166d..95f26f5e0b 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -82,12 +82,11 @@ private:
Ref<Texture2D> _get_grabber_icon() const;
void _compute_middle_sep(bool p_clamp);
void _resort();
+ Control *_get_sortable_child(int p_idx) const;
protected:
bool is_fixed = false;
- Control *get_containable_child(int p_idx) const;
-
void _notification(int p_what);
void _validate_property(PropertyInfo &p_property) const;
static void _bind_methods();
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index f6cfe6ab18..c715aceb0b 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -287,7 +287,7 @@ void SubViewportContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_stretch_shrink"), &SubViewportContainer::get_stretch_shrink);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch"), "set_stretch", "is_stretch_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink"), "set_stretch_shrink", "get_stretch_shrink");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), "set_stretch_shrink", "get_stretch_shrink");
GDVIRTUAL_BIND(_propagate_input_event, "event");
}
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 0e130d60af..ddc757c452 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -1868,6 +1868,7 @@ void TabBar::_bind_methods() {
Tab defaults(true);
base_property_helper.set_prefix("tab_");
+ base_property_helper.set_array_length_getter(&TabBar::get_tab_count);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "title"), defaults.text, &TabBar::set_tab_title, &TabBar::get_tab_title);
base_property_helper.register_property(PropertyInfo(Variant::STRING, "tooltip"), defaults.tooltip, &TabBar::set_tab_tooltip, &TabBar::get_tab_tooltip);
base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &TabBar::set_tab_icon, &TabBar::get_tab_icon);
@@ -1877,7 +1878,7 @@ void TabBar::_bind_methods() {
TabBar::TabBar() {
set_size(Size2(get_size().width, get_minimum_size().height));
set_focus_mode(FOCUS_ALL);
- connect("mouse_exited", callable_mp(this, &TabBar::_on_mouse_exited));
+ connect(SceneStringName(mouse_exited), callable_mp(this, &TabBar::_on_mouse_exited));
property_helper.setup_for_instance(base_property_helper, this);
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index dc53cf82e6..d0c3f3d65e 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -554,7 +554,7 @@ void TabContainer::add_child_notify(Node *p_child) {
}
p_child->connect("renamed", callable_mp(this, &TabContainer::_refresh_tab_names));
- p_child->connect(SNAME("visibility_changed"), callable_mp(this, &TabContainer::_on_tab_visibility_changed).bind(c));
+ p_child->connect(SceneStringName(visibility_changed), callable_mp(this, &TabContainer::_on_tab_visibility_changed).bind(c));
// TabBar won't emit the "tab_changed" signal when not inside the tree.
if (!is_inside_tree()) {
@@ -607,7 +607,7 @@ void TabContainer::remove_child_notify(Node *p_child) {
p_child->remove_meta("_tab_index");
p_child->remove_meta("_tab_name");
p_child->disconnect("renamed", callable_mp(this, &TabContainer::_refresh_tab_names));
- p_child->disconnect(SNAME("visibility_changed"), callable_mp(this, &TabContainer::_on_tab_visibility_changed));
+ p_child->disconnect(SceneStringName(visibility_changed), callable_mp(this, &TabContainer::_on_tab_visibility_changed));
// TabBar won't emit the "tab_changed" signal when not inside the tree.
if (!is_inside_tree()) {
@@ -1121,5 +1121,5 @@ TabContainer::TabContainer() {
tab_bar->connect("tab_button_pressed", callable_mp(this, &TabContainer::_on_tab_button_pressed));
tab_bar->connect("active_tab_rearranged", callable_mp(this, &TabContainer::_on_active_tab_rearranged));
- connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited));
+ connect(SceneStringName(mouse_exited), callable_mp(this, &TabContainer::_on_mouse_exited));
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 49cfa8a030..1dd00fab4d 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -558,8 +558,6 @@ void TextEdit::_notification(int p_what) {
int visible_rows = get_visible_line_count() + 1;
- Color color = !editable ? theme_cache.font_readonly_color : theme_cache.font_color;
-
if (theme_cache.background_color.a > 0.01) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), theme_cache.background_color);
}
@@ -734,7 +732,7 @@ void TextEdit::_notification(int p_what) {
if (draw_minimap) {
int minimap_visible_lines = get_minimap_visible_lines();
int minimap_line_height = (minimap_char_size.y + minimap_line_spacing);
- int minimap_tab_size = minimap_char_size.x * text.get_tab_size();
+ int tab_size = text.get_tab_size();
// Calculate viewport size and y offset.
int viewport_height = (draw_amount - 1) * minimap_line_height;
@@ -839,68 +837,74 @@ void TextEdit::_notification(int p_what) {
}
}
- Color previous_color;
+ Color next_color = current_color;
int characters = 0;
- int tabs = 0;
+ int tab_alignment = 0;
+ int xpos = xmargin_end + 2 + indent_px;
for (int j = 0; j < str.length(); j++) {
- const Variant *color_data = color_map.getptr(last_wrap_column + j);
- if (color_data != nullptr) {
- current_color = (color_data->operator Dictionary()).get("color", theme_cache.font_color);
- if (!editable) {
- current_color.a = theme_cache.font_readonly_color.a;
+ bool next_is_whitespace = false;
+ bool next_is_tab = false;
+ // Get the number of characters to draw together.
+ for (characters = 0; j + characters < str.length(); characters++) {
+ int next_char_index = j + characters;
+ const Variant *color_data = color_map.getptr(last_wrap_column + next_char_index);
+ if (color_data != nullptr) {
+ next_color = (color_data->operator Dictionary()).get("color", theme_cache.font_color);
+ if (!editable) {
+ next_color.a = theme_cache.font_readonly_color.a;
+ }
+ next_color.a *= 0.6;
}
- }
- color = current_color;
-
- if (j == 0) {
- previous_color = color;
- }
-
- int xpos = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * j)) + tabs;
- bool out_of_bounds = (xpos >= xmargin_end + minimap_width);
-
- bool whitespace = is_whitespace(str[j]);
- if (!whitespace) {
- characters++;
-
- if (j < str.length() - 1 && color == previous_color && !out_of_bounds) {
- continue;
+ if (characters == 0) {
+ current_color = next_color;
}
-
- // If we've changed color we are at the start of a new section, therefore we need to go back to the end
- // of the previous section to draw it, we'll also add the character back on.
- if (color != previous_color) {
- characters--;
- j--;
-
- if (str[j] == '\t') {
- tabs -= minimap_tab_size;
+ if (next_color != current_color) {
+ break;
+ }
+ next_is_whitespace = is_whitespace(str[next_char_index]);
+ if (next_is_whitespace) {
+ if (str[next_char_index] == '\t') {
+ next_is_tab = true;
}
+ break;
+ }
+ bool out_of_bounds = xpos + minimap_char_size.x * characters >= xmargin_end + minimap_width;
+ if (out_of_bounds) {
+ break;
}
}
+ if (!next_is_whitespace && characters == 0) {
+ break;
+ }
if (characters > 0) {
- previous_color.a *= 0.6;
- // Take one for zero indexing, and if we hit whitespace / the end of a word.
- int chars = MAX(0, (j - (characters - 1)) - (whitespace ? 1 : 0)) + 1;
- int char_x_ofs = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * chars)) + tabs;
if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - char_x_ofs - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), previous_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
} else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(char_x_ofs, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), previous_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color);
}
}
- if (out_of_bounds) {
- break;
- }
+ j += characters - 1;
+ xpos += minimap_char_size.x * characters;
+ tab_alignment += characters;
- if (str[j] == '\t') {
- tabs += minimap_tab_size;
+ if (next_is_whitespace) {
+ if (next_is_tab) {
+ tab_alignment %= tab_size;
+ xpos += minimap_char_size.x * (tab_size - tab_alignment);
+ tab_alignment = 0;
+ } else {
+ xpos += minimap_char_size.x;
+ tab_alignment += 1;
+ }
+ j += 1;
}
- previous_color = color;
- characters = 0;
+ if (xpos >= xmargin_end + minimap_width) {
+ // Out of bounds.
+ break;
+ }
}
}
}
@@ -999,23 +1003,12 @@ void TextEdit::_notification(int p_what) {
}
}
- if (str.length() == 0) {
- // Draw line background if empty as we won't loop at all.
- if (caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index) && highlight_current_line) {
- if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
- } else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
- }
- }
- } else {
- // If it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
- if (caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index) && highlight_current_line) {
- if (rtl) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
- } else {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
- }
+ // Draw current line highlight.
+ if (highlight_current_line && caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index)) {
+ if (rtl) {
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
+ } else {
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color);
}
}
@@ -1188,6 +1181,7 @@ void TextEdit::_notification(int p_what) {
if (!clipped && lookup_symbol_word.length() != 0) { // Highlight word
if (is_ascii_alphabet_char(lookup_symbol_word[0]) || lookup_symbol_word[0] == '_' || lookup_symbol_word[0] == '.') {
+ Color highlight_underline_color = !editable ? theme_cache.font_readonly_color : theme_cache.font_color;
int lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
int lookup_symbol_word_len = lookup_symbol_word.length();
while (lookup_symbol_word_col != -1) {
@@ -1205,7 +1199,7 @@ void TextEdit::_notification(int p_what) {
}
rect.position.y += ceil(TS->shaped_text_get_ascent(rid)) + ceil(theme_cache.font->get_underline_position(theme_cache.font_size));
rect.size.y = MAX(1, theme_cache.font->get_underline_thickness(theme_cache.font_size));
- draw_rect(rect, color);
+ draw_rect(rect, highlight_underline_color);
}
lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, lookup_symbol_word_col + lookup_symbol_word_len);
@@ -4243,8 +4237,11 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
}
Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds) const {
- float rows = p_pos.y;
- rows -= theme_cache.style_normal->get_margin(SIDE_TOP);
+ float rows = p_pos.y - theme_cache.style_normal->get_margin(SIDE_TOP);
+ if (!editable) {
+ rows -= theme_cache.style_readonly->get_offset().y / 2;
+ rows += theme_cache.style_normal->get_offset().y / 2;
+ }
rows /= get_line_height();
rows += _get_v_scroll_offset();
int first_vis_line = get_first_visible_line();
@@ -4275,6 +4272,10 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_
int col = 0;
int colx = p_pos.x - (theme_cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
colx += first_visible_col;
+ if (!editable) {
+ colx -= theme_cache.style_readonly->get_offset().x / 2;
+ colx += theme_cache.style_normal->get_offset().x / 2;
+ }
col = _get_char_pos_for_line(colx, row, wrap_index);
if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE && wrap_index < get_line_wrap_count(row)) {
// Move back one if we are at the end of the row.
@@ -7973,7 +7974,7 @@ void TextEdit::_update_minimap_click() {
Point2 mp = get_local_mouse_pos();
int xmargin_end = get_size().width - theme_cache.style_normal->get_margin(SIDE_RIGHT);
- if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.y > xmargin_end)) {
+ if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.x > xmargin_end)) {
minimap_clicked = false;
return;
}
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index df90257e03..c267ff93c6 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -178,13 +178,14 @@ void TextureButton::_notification(int p_what) {
texdraw = focused;
}
- if (texdraw.is_valid()) {
- size = texdraw->get_size();
- _texture_region = Rect2(Point2(), texdraw->get_size());
+ if (texdraw.is_valid() || click_mask.is_valid()) {
+ const Size2 texdraw_size = texdraw.is_valid() ? texdraw->get_size() : Size2(click_mask->get_size());
+
+ size = texdraw_size;
+ _texture_region = Rect2(Point2(), texdraw_size);
_tile = false;
switch (stretch_mode) {
case STRETCH_KEEP:
- size = texdraw->get_size();
break;
case STRETCH_SCALE:
size = get_size();
@@ -194,18 +195,17 @@ void TextureButton::_notification(int p_what) {
_tile = true;
break;
case STRETCH_KEEP_CENTERED:
- ofs = (get_size() - texdraw->get_size()) / 2;
- size = texdraw->get_size();
+ ofs = (get_size() - texdraw_size) / 2;
break;
case STRETCH_KEEP_ASPECT_CENTERED:
case STRETCH_KEEP_ASPECT: {
Size2 _size = get_size();
- float tex_width = texdraw->get_width() * _size.height / texdraw->get_height();
+ float tex_width = texdraw_size.width * _size.height / texdraw_size.height;
float tex_height = _size.height;
if (tex_width > _size.width) {
tex_width = _size.width;
- tex_height = texdraw->get_height() * tex_width / texdraw->get_width();
+ tex_height = texdraw_size.height * tex_width / texdraw_size.width;
}
if (stretch_mode == STRETCH_KEEP_ASPECT_CENTERED) {
@@ -217,10 +217,9 @@ void TextureButton::_notification(int p_what) {
} break;
case STRETCH_KEEP_ASPECT_COVERED: {
size = get_size();
- Size2 tex_size = texdraw->get_size();
- Size2 scale_size(size.width / tex_size.width, size.height / tex_size.height);
+ Size2 scale_size = size / texdraw_size;
float scale = scale_size.width > scale_size.height ? scale_size.width : scale_size.height;
- Size2 scaled_tex_size = tex_size * scale;
+ Size2 scaled_tex_size = texdraw_size * scale;
Point2 ofs2 = ((scaled_tex_size - size) / scale).abs() / 2.0f;
_texture_region = Rect2(ofs2, size / scale);
} break;
@@ -233,10 +232,12 @@ void TextureButton::_notification(int p_what) {
if (draw_focus_only) {
// Do nothing, we only needed to calculate the rectangle.
- } else if (_tile) {
- draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
- } else {
- draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region);
+ } else if (texdraw.is_valid()) {
+ if (_tile) {
+ draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
+ } else {
+ draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region);
+ }
}
} else {
_position_rect = Rect2();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index e2de585a69..fc5b942918 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -3152,8 +3152,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
void Tree::_text_editor_popup_modal_close() {
+ if (popup_edit_commited) {
+ return; // Already processed by LineEdit/TextEdit commit.
+ }
+
if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) {
- return;
+ return; // ESC pressed, app focus lost, or forced close from code.
}
if (value_editor->has_point(value_editor->get_local_mouse_position())) {
@@ -3172,9 +3176,18 @@ void Tree::_text_editor_popup_modal_close() {
}
void Tree::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
+ if (popup_edit_commited) {
+ return; // Already processed by _text_editor_popup_modal_close
+ }
+
+ if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) {
+ return; // ESC pressed, app focus lost, or forced close from code.
+ }
+
if (p_event->is_action_pressed("ui_text_newline_blank", true)) {
accept_event();
} else if (p_event->is_action_pressed("ui_text_newline")) {
+ popup_edit_commited = true; // End edit popup processing.
popup_editor->hide();
_apply_multiline_edit();
accept_event();
@@ -3205,6 +3218,15 @@ void Tree::_apply_multiline_edit() {
}
void Tree::_line_editor_submit(String p_text) {
+ if (popup_edit_commited) {
+ return; // Already processed by _text_editor_popup_modal_close
+ }
+
+ if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) {
+ return; // ESC pressed, app focus lost, or forced close from code.
+ }
+
+ popup_edit_commited = true; // End edit popup processing.
popup_editor->hide();
if (!popup_edited_item) {
@@ -4072,6 +4094,7 @@ bool Tree::edit_selected(bool p_force_edit) {
if (!popup_editor->is_embedded()) {
popup_editor->set_content_scale_factor(popup_scale);
}
+ popup_edit_commited = false; // Start edit popup processing.
popup_editor->popup();
popup_editor->child_controls_changed();
@@ -4091,6 +4114,7 @@ bool Tree::edit_selected(bool p_force_edit) {
if (!popup_editor->is_embedded()) {
popup_editor->set_content_scale_factor(popup_scale);
}
+ popup_edit_commited = false; // Start edit popup processing.
popup_editor->popup();
popup_editor->child_controls_changed();
@@ -5795,7 +5819,7 @@ Tree::Tree() {
h_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
v_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
line_editor->connect("text_submitted", callable_mp(this, &Tree::_line_editor_submit));
- text_editor->connect("gui_input", callable_mp(this, &Tree::_text_editor_gui_input));
+ text_editor->connect(SceneStringName(gui_input), callable_mp(this, &Tree::_text_editor_gui_input));
popup_editor->connect("popup_hide", callable_mp(this, &Tree::_text_editor_popup_modal_close));
popup_menu->connect("id_pressed", callable_mp(this, &Tree::popup_select));
value_editor->connect("value_changed", callable_mp(this, &Tree::value_editor_changed));
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 311055a2f8..e9c93c6e03 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -479,6 +479,7 @@ private:
VBoxContainer *popup_editor_vb = nullptr;
+ bool popup_edit_commited = true;
Popup *popup_editor = nullptr;
LineEdit *line_editor = nullptr;
TextEdit *text_editor = nullptr;
diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp
index 687a9e46a0..0b521f926d 100644
--- a/scene/gui/video_stream_player.cpp
+++ b/scene/gui/video_stream_player.cpp
@@ -31,7 +31,6 @@
#include "video_stream_player.h"
#include "core/os/os.h"
-#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
int VideoStreamPlayer::sp_get_channel_count() const {
@@ -163,7 +162,7 @@ void VideoStreamPlayer::_notification(int p_notification) {
play();
return;
}
- emit_signal(SceneStringNames::get_singleton()->finished);
+ emit_signal(SceneStringName(finished));
}
} break;
@@ -460,7 +459,7 @@ StringName VideoStreamPlayer::get_bus() const {
return bus;
}
}
- return SceneStringNames::get_singleton()->Master;
+ return SceneStringName(Master);
}
void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const {
diff --git a/scene/main/canvas_item.compat.inc b/scene/main/canvas_item.compat.inc
index 7136fded15..9bc3d01a69 100644
--- a/scene/main/canvas_item.compat.inc
+++ b/scene/main/canvas_item.compat.inc
@@ -30,12 +30,32 @@
#ifndef DISABLE_DEPRECATED
-void CanvasItem::_draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
+void CanvasItem::_draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
draw_circle(p_pos, p_radius, p_color, true, -1.0, false);
}
+void CanvasItem::_draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) {
+ draw_rect(p_rect, p_color, p_filled, p_width, false);
+}
+
+void CanvasItem::_draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) {
+ draw_dashed_line(p_from, p_to, p_color, p_width, p_dash, p_aligned, false);
+}
+
+void CanvasItem::_draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) {
+ draw_multiline(p_points, p_color, p_width, false);
+}
+
+void CanvasItem::_draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) {
+ draw_multiline_colors(p_points, p_colors, p_width, false);
+}
+
void CanvasItem::_bind_compatibility_methods() {
- ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_compat_84472);
+ ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_bind_compat_84472);
+ ClassDB::bind_compatibility_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::_draw_rect_bind_compat_84523, DEFVAL(true), DEFVAL(-1.0));
+ ClassDB::bind_compatibility_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::_draw_dashed_line_bind_compat_84523, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true));
+ ClassDB::bind_compatibility_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::_draw_multiline_bind_compat_84523, DEFVAL(-1.0));
+ ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::_draw_multiline_colors_bind_compat_84523, DEFVAL(-1.0));
}
#endif
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 50cae48e34..c0386b056f 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -40,7 +40,6 @@
#include "scene/resources/multimesh.h"
#include "scene/resources/style_box.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#define ERR_DRAW_GUARD \
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside this node's `_draw()`, functions connected to its `draw` signal, or when it receives NOTIFICATION_DRAW.")
@@ -96,7 +95,7 @@ void CanvasItem::_handle_visibility_change(bool p_visible) {
if (p_visible) {
queue_redraw();
} else {
- emit_signal(SceneStringNames::get_singleton()->hidden);
+ emit_signal(SceneStringName(hidden));
}
_block();
@@ -142,7 +141,7 @@ void CanvasItem::_redraw_callback() {
drawing = true;
current_item_drawn = this;
notification(NOTIFICATION_DRAW);
- emit_signal(SceneStringNames::get_singleton()->draw);
+ emit_signal(SceneStringName(draw));
GDVIRTUAL_CALL(_draw);
current_item_drawn = nullptr;
drawing = false;
@@ -310,7 +309,7 @@ void CanvasItem::_notification(int p_what) {
window = Object::cast_to<Window>(viewport);
if (window) {
- window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
+ window->connect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed));
parent_visible_in_tree = window->is_visible();
} else {
parent_visible_in_tree = true;
@@ -364,7 +363,7 @@ void CanvasItem::_notification(int p_what) {
C = nullptr;
}
if (window) {
- window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
+ window->disconnect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed));
window = nullptr;
}
_set_global_invalid(true);
@@ -384,7 +383,7 @@ void CanvasItem::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
ERR_MAIN_THREAD_GUARD;
- emit_signal(SceneStringNames::get_singleton()->visibility_changed);
+ emit_signal(SceneStringName(visibility_changed));
} break;
case NOTIFICATION_WORLD_2D_CHANGED: {
ERR_MAIN_THREAD_GUARD;
@@ -556,7 +555,7 @@ void CanvasItem::item_rect_changed(bool p_size_changed) {
if (p_size_changed) {
queue_redraw();
}
- emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
+ emit_signal(SceneStringName(item_rect_changed));
}
void CanvasItem::set_z_index(int p_z) {
@@ -610,7 +609,7 @@ bool CanvasItem::is_y_sort_enabled() const {
return y_sort_enabled;
}
-void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) {
+void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned, bool p_antialiased) {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_dash <= 0.0);
@@ -619,7 +618,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons
Vector2 step = p_dash * (p_to - p_from).normalized();
if (length < p_dash || step == Vector2()) {
- RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased);
return;
}
@@ -643,7 +642,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons
Vector<Color> colors = { p_color };
- RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width, p_antialiased);
}
void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, bool p_antialiased) {
@@ -684,22 +683,22 @@ void CanvasItem::draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_sta
draw_polyline(points, p_color, p_width, p_antialiased);
}
-void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) {
+void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width, bool p_antialiased) {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
Vector<Color> colors = { p_color };
- RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased);
}
-void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) {
+void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width, bool p_antialiased) {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
- RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
-void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) {
+void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width, bool p_antialiased) {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
@@ -710,9 +709,9 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\".");
}
- RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color, p_antialiased);
} else if (p_width >= rect.size.width || p_width >= rect.size.height) {
- RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color, p_antialiased);
} else {
Vector<Vector2> points;
points.resize(5);
@@ -724,7 +723,7 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
Vector<Color> colors = { p_color };
- RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width);
+ RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width, p_antialiased);
}
}
@@ -737,9 +736,9 @@ void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color &
WARN_PRINT("The draw_circle() \"width\" argument has no effect when \"filled\" is \"true\".");
}
- RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
+ RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color, p_antialiased);
} else if (p_width >= 2.0 * p_radius) {
- RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color);
+ RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color, p_antialiased);
} else {
// Tessellation count is hardcoded. Keep in sync with the same variable in `RendererCanvasCull::canvas_item_add_circle()`.
const int circle_segments = 64;
@@ -1197,13 +1196,13 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled);
ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(-1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned", "antialiased"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(-1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(-1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(-1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(-1.0));
- ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0));
- ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0));
+ ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(-1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color", "filled", "width", "antialiased"), &CanvasItem::draw_circle, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false));
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index ae7b195ead..028c2cb2cf 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -168,7 +168,11 @@ protected:
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
- void _draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color);
+ void _draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color);
+ void _draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width);
+ void _draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned);
+ void _draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width);
+ void _draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width);
static void _bind_compatibility_methods();
#endif
@@ -271,14 +275,14 @@ public:
/* DRAWING API */
- void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true);
+ void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true, bool p_antialiased = false);
void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false);
void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false);
void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false);
void draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false);
- void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0);
- void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0);
- void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0);
+ void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false);
+ void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false);
+ void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false);
void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false);
void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1));
void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index c9cca76dea..11d074f014 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -52,7 +52,7 @@ void CanvasLayer::set_visible(bool p_visible) {
}
visible = p_visible;
- emit_signal(SNAME("visibility_changed"));
+ emit_signal(SceneStringName(visibility_changed));
for (int i = 0; i < get_child_count(); i++) {
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index fe23ca1800..f36bbe9395 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -88,16 +88,16 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
if (!ps.is_valid()) {
return nullptr;
}
- Node *scene = ps->instantiate();
- if (!scene) {
+ Node *instance = ps->instantiate();
+ if (!instance) {
return nullptr;
}
- scene->set_name(get_name());
- scene->set_multiplayer_authority(get_multiplayer_authority());
+ instance->set_name(get_name());
+ instance->set_multiplayer_authority(get_multiplayer_authority());
int pos = get_index();
for (const PropSet &E : stored_values) {
- scene->set(E.name, E.value);
+ set_value_on_instance(this, instance, E);
}
if (p_replace) {
@@ -105,10 +105,125 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
base->remove_child(this);
}
- base->add_child(scene);
- base->move_child(scene, pos);
+ base->add_child(instance);
+ base->move_child(instance, pos);
- return scene;
+ return instance;
+}
+
+// This method will attempt to set the correct values on the placeholder instance
+// for regular types this is trivial and unnecessary.
+// For nodes however this becomes a bit tricky because they might now have existed until the instantiation,
+// so this method will try to find the correct nodes and resolve them.
+void InstancePlaceholder::set_value_on_instance(InstancePlaceholder *p_placeholder, Node *p_instance, const PropSet &p_set) {
+ bool is_valid;
+
+ // If we don't have any info, we can't do anything,
+ // so try setting the value directly.
+ Variant current = p_instance->get(p_set.name, &is_valid);
+ if (!is_valid) {
+ p_instance->set(p_set.name, p_set.value, &is_valid);
+ return;
+ }
+
+ Variant::Type current_type = current.get_type();
+ Variant::Type placeholder_type = p_set.value.get_type();
+
+ // Arrays are a special case, because their containing type might be different.
+ if (current_type != Variant::Type::ARRAY) {
+ // Check if the variant types match.
+ if (Variant::evaluate(Variant::OP_EQUAL, current_type, placeholder_type)) {
+ p_instance->set(p_set.name, p_set.value, &is_valid);
+ if (is_valid) {
+ return;
+ }
+ // Types match but setting failed? This is strange, so let's print a warning!
+ WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name()));
+ return;
+ }
+ } else {
+ // We are dealing with an Array.
+ // Let's check if the subtype of the array matches first.
+ // This is needed because the set method of ScriptInstance checks for type,
+ // but the ClassDB set method doesn't! So we cannot reliably know what actually happens.
+ Array current_array = current;
+ Array placeholder_array = p_set.value;
+ if (current_array.is_same_typed(placeholder_array)) {
+ p_instance->set(p_set.name, p_set.value, &is_valid);
+ if (is_valid) {
+ return;
+ }
+ // Internal array types match but setting failed? This is strange, so let's print a warning!
+ WARN_PRINT(vformat("Array Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(Variant::Type(current_array.get_typed_builtin())), p_placeholder->get_name()));
+ }
+ // Arrays are not the same internal type. This should be happening because we have a NodePath Array,
+ // but the instance wants a Node Array.
+ }
+
+ switch (current_type) {
+ case Variant::Type::NIL:
+ if (placeholder_type != Variant::Type::NODE_PATH) {
+ break;
+ }
+ // If it's nil but we have a NodePath, we guess what works.
+
+ p_instance->set(p_set.name, p_set.value, &is_valid);
+ if (is_valid) {
+ break;
+ }
+
+ p_instance->set(p_set.name, try_get_node(p_placeholder, p_instance, p_set.value), &is_valid);
+ break;
+ case Variant::Type::OBJECT:
+ if (placeholder_type != Variant::Type::NODE_PATH) {
+ break;
+ }
+ // Easiest case, we want a node, but we have a deferred NodePath.
+ p_instance->set(p_set.name, try_get_node(p_placeholder, p_instance, p_set.value));
+ break;
+ case Variant::Type::ARRAY: {
+ // If we have reached here it means our array types don't match,
+ // so we will convert the placeholder array into the correct type
+ // and resolve nodes if necessary.
+ Array current_array = current;
+ Array converted_array;
+ Array placeholder_array = p_set.value;
+ converted_array = current_array.duplicate();
+ converted_array.resize(placeholder_array.size());
+
+ if (Variant::evaluate(Variant::OP_EQUAL, current_array.get_typed_builtin(), Variant::Type::NODE_PATH)) {
+ // We want a typed NodePath array.
+ for (int i = 0; i < placeholder_array.size(); i++) {
+ converted_array.set(i, placeholder_array[i]);
+ }
+ } else {
+ // We want Nodes, convert NodePaths.
+ for (int i = 0; i < placeholder_array.size(); i++) {
+ converted_array.set(i, try_get_node(p_placeholder, p_instance, placeholder_array[i]));
+ }
+ }
+
+ p_instance->set(p_set.name, converted_array, &is_valid);
+ if (!is_valid) {
+ WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name()));
+ }
+ break;
+ }
+ default:
+ WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name()));
+ break;
+ }
+}
+
+Node *InstancePlaceholder::try_get_node(InstancePlaceholder *p_placeholder, Node *p_instance, const NodePath &p_path) {
+ // First try to resolve internally,
+ // if that fails try resolving externally.
+ Node *node = p_instance->get_node_or_null(p_path);
+ if (node == nullptr) {
+ node = p_placeholder->get_node_or_null(p_path);
+ }
+
+ return node;
}
Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) {
diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h
index 480474d0bd..ccf1e63a16 100644
--- a/scene/main/instance_placeholder.h
+++ b/scene/main/instance_placeholder.h
@@ -46,6 +46,10 @@ class InstancePlaceholder : public Node {
List<PropSet> stored_values;
+private:
+ void set_value_on_instance(InstancePlaceholder *p_placeholder, Node *p_instance, const PropSet &p_set);
+ Node *try_get_node(InstancePlaceholder *p_placeholder, Node *p_instance, const NodePath &p_path);
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index e54209c1dd..884fc6de07 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -31,7 +31,6 @@
#include "node.h"
#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/object/message_queue.h"
#include "core/object/script_language.h"
@@ -42,7 +41,6 @@
#include "scene/main/multiplayer_api.h"
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
-#include "scene/scene_string_names.h"
#include "viewport.h"
#include <stdint.h>
@@ -266,7 +264,7 @@ void Node::_propagate_ready() {
if (data.ready_first) {
data.ready_first = false;
notification(NOTIFICATION_READY);
- emit_signal(SceneStringNames::get_singleton()->ready);
+ emit_signal(SceneStringName(ready));
}
}
@@ -295,7 +293,7 @@ void Node::_propagate_enter_tree() {
GDVIRTUAL_CALL(_enter_tree);
- emit_signal(SceneStringNames::get_singleton()->tree_entered);
+ emit_signal(SceneStringName(tree_entered));
data.tree->node_added(this);
@@ -350,7 +348,7 @@ void Node::_propagate_after_exit_tree() {
data.blocked--;
- emit_signal(SceneStringNames::get_singleton()->tree_exited);
+ emit_signal(SceneStringName(tree_exited));
}
void Node::_propagate_exit_tree() {
@@ -372,7 +370,7 @@ void Node::_propagate_exit_tree() {
GDVIRTUAL_CALL(_exit_tree);
- emit_signal(SceneStringNames::get_singleton()->tree_exiting);
+ emit_signal(SceneStringName(tree_exiting));
notification(NOTIFICATION_EXIT_TREE, true);
if (data.tree) {
@@ -1738,12 +1736,10 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
StringName name = p_path.get_name(i);
Node *next = nullptr;
- if (name == SceneStringNames::get_singleton()->dot) { // .
-
+ if (name == SNAME(".")) {
next = current;
- } else if (name == SceneStringNames::get_singleton()->doubledot) { // ..
-
+ } else if (name == SNAME("..")) {
if (current == nullptr || !current->data.parent) {
return nullptr;
}
@@ -2667,8 +2663,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
node->data.editable_instance = data.editable_instance;
}
- StringName script_property_name = CoreStringNames::get_singleton()->_script;
-
List<const Node *> hidden_roots;
List<const Node *> node_tree;
node_tree.push_front(this);
@@ -2770,45 +2764,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
parent->move_child(dup, pos);
}
}
-
- for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
- Node *current_node = node->get_node(get_path_to(N->get()));
- ERR_CONTINUE(!current_node);
-
- if (p_flags & DUPLICATE_SCRIPTS) {
- bool is_valid = false;
- Variant scr = N->get()->get(script_property_name, &is_valid);
- if (is_valid) {
- current_node->set(script_property_name, scr);
- }
- }
-
- List<PropertyInfo> plist;
- N->get()->get_property_list(&plist);
-
- for (const PropertyInfo &E : plist) {
- if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
- continue;
- }
- String name = E.name;
- if (name == script_property_name) {
- continue;
- }
-
- Variant value = N->get()->get(name).duplicate(true);
-
- if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
- Resource *res = Object::cast_to<Resource>(value);
- if (res) { // Duplicate only if it's a resource
- current_node->set(name, res->duplicate());
- }
-
- } else {
- current_node->set(name, value);
- }
- }
- }
-
return node;
}
@@ -2820,7 +2775,7 @@ Node *Node::duplicate(int p_flags) const {
_duplicate_signals(this, dupe);
}
- _duplicate_properties_node(this, this, dupe);
+ _duplicate_properties(this, this, dupe, p_flags);
return dupe;
}
@@ -2831,7 +2786,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) con
}
Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
- Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap);
+ int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR;
+ Node *dupe = _duplicate(flags, &r_duplimap);
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
if (!p_resource_remap.is_empty()) {
@@ -2843,7 +2799,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
// if the emitter node comes later in tree order than the receiver
_duplicate_signals(this, dupe);
- _duplicate_properties_node(this, this, dupe);
+ _duplicate_properties(this, this, dupe, flags);
return dupe;
}
@@ -2897,34 +2853,58 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re
}
#endif
-// Duplicates properties that store a Node.
-// This has to be called after nodes have been duplicated since
-// only then do we get a full picture of how the duplicated node tree looks like.
-void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const {
+// Duplicate node's properties.
+// This has to be called after nodes have been duplicated since there might be properties
+// of type Node that can be updated properly only if duplicated node tree is complete.
+void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const {
List<PropertyInfo> props;
- p_copy->get_property_list(&props);
+ p_original->get_property_list(&props);
+ const StringName &script_property_name = CoreStringName(script);
+ if (p_flags & DUPLICATE_SCRIPTS) {
+ bool is_valid = false;
+ Variant scr = p_original->get(script_property_name, &is_valid);
+ if (is_valid) {
+ p_copy->set(script_property_name, scr);
+ }
+ }
for (const PropertyInfo &E : props) {
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
- String name = E.name;
+ const StringName name = E.name;
+
+ if (name == script_property_name) {
+ continue;
+ }
+
Variant value = p_original->get(name).duplicate(true);
- if (value.get_type() == Variant::OBJECT) {
- Node *property_node = Object::cast_to<Node>(value);
- if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
- value = p_copy->get_node_or_null(p_original->get_path_to(property_node));
- p_copy->set(name, value);
+
+ if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
+ Resource *res = Object::cast_to<Resource>(value);
+ if (res) { // Duplicate only if it's a resource
+ p_copy->set(name, res->duplicate());
}
- } else if (value.get_type() == Variant::ARRAY) {
- Array arr = value;
- if (arr.get_typed_builtin() == Variant::OBJECT) {
- for (int i = 0; i < arr.size(); i++) {
- Node *property_node = Object::cast_to<Node>(arr[i]);
- if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
- arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ } else {
+ if (value.get_type() == Variant::OBJECT) {
+ Node *property_node = Object::cast_to<Node>(value);
+ Variant out_value = value;
+ if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
+ out_value = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ }
+ p_copy->set(name, out_value);
+ } else if (value.get_type() == Variant::ARRAY) {
+ Array arr = value;
+ if (arr.get_typed_builtin() == Variant::OBJECT) {
+ for (int i = 0; i < arr.size(); i++) {
+ Node *property_node = Object::cast_to<Node>(arr[i]);
+ if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) {
+ arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node));
+ }
}
+ value = arr;
+ p_copy->set(name, value);
}
- value = arr;
+ } else {
p_copy->set(name, value);
}
}
@@ -2933,7 +2913,7 @@ void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original
for (int i = 0; i < p_original->get_child_count(); i++) {
Node *copy_child = p_copy->get_child(i);
ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating.");
- _duplicate_properties_node(p_root, p_original->get_child(i), copy_child);
+ _duplicate_properties(p_root, p_original->get_child(i), copy_child, p_flags);
}
}
@@ -3323,7 +3303,7 @@ void Node::update_configuration_warnings() {
return;
}
if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
- get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this);
+ get_tree()->emit_signal(SceneStringName(node_configuration_warning_changed), this);
}
#endif
}
diff --git a/scene/main/node.h b/scene/main/node.h
index fe212ae0f7..6b93724478 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -35,6 +35,7 @@
#include "core/templates/rb_map.h"
#include "core/variant/typed_array.h"
#include "scene/main/scene_tree.h"
+#include "scene/scene_string_names.h"
class Viewport;
class Window;
@@ -266,7 +267,7 @@ private:
void _propagate_groups_dirty();
Array _get_node_and_resource(const NodePath &p_path);
- void _duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const;
+ void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
Node *_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap = nullptr) const;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 870bed7409..ced6d9aaa6 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -55,7 +55,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#include "servers/display_server.h"
#include "servers/navigation_server_3d.h"
#include "servers/physics_server_2d.h"
@@ -1876,7 +1875,7 @@ SceneTree::SceneTree() {
root->connect("close_requested", callable_mp(this, &SceneTree::_main_window_close));
root->connect("go_back_requested", callable_mp(this, &SceneTree::_main_window_go_back));
- root->connect("focus_entered", callable_mp(this, &SceneTree::_main_window_focus_in));
+ root->connect(SceneStringName(focus_entered), callable_mp(this, &SceneTree::_main_window_focus_in));
#ifdef TOOLS_ENABLED
edited_scene_root = nullptr;
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 091e6249bf..41e0aa739e 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -31,7 +31,6 @@
#include "shader_globals_override.h"
#include "scene/main/node.h"
-#include "scene/scene_string_names.h"
StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {
StringName *r = param_remaps.getptr(p_name);
@@ -223,11 +222,11 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
void ShaderGlobalsOverride::_activate() {
ERR_FAIL_NULL(get_tree());
List<Node *> nodes;
- get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes);
+ get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active), &nodes);
if (nodes.size() == 0) {
//good we are the only override, enable all
active = true;
- add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
+ add_to_group(SceneStringName(shader_overrides_group_active));
for (const KeyValue<StringName, Override> &E : overrides) {
const Override *o = &E.value;
@@ -248,7 +247,7 @@ void ShaderGlobalsOverride::_activate() {
void ShaderGlobalsOverride::_notification(int p_what) {
switch (p_what) {
case Node::NOTIFICATION_ENTER_TREE: {
- add_to_group(SceneStringNames::get_singleton()->shader_overrides_group);
+ add_to_group(SceneStringName(shader_overrides_group));
_activate();
} break;
@@ -263,9 +262,9 @@ void ShaderGlobalsOverride::_notification(int p_what) {
}
}
- remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
- remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group);
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed
+ remove_from_group(SceneStringName(shader_overrides_group_active));
+ remove_from_group(SceneStringName(shader_overrides_group));
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(shader_overrides_group), "_activate"); //another may want to activate when this is removed
active = false;
} break;
}
diff --git a/scene/main/status_indicator.cpp b/scene/main/status_indicator.cpp
index 891974f68f..f0ba5db1a0 100644
--- a/scene/main/status_indicator.cpp
+++ b/scene/main/status_indicator.cpp
@@ -91,7 +91,7 @@ void StatusIndicator::_bind_methods() {
}
void StatusIndicator::_callback(MouseButton p_index, const Point2i &p_pos) {
- emit_signal(SNAME("pressed"), p_index, p_pos);
+ emit_signal(SceneStringName(pressed), p_index, p_pos);
}
void StatusIndicator::set_icon(const Ref<Texture2D> &p_icon) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index b8c691c6e7..26128a08ab 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -54,7 +54,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/text_line.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_globals.h"
@@ -81,7 +80,7 @@ void ViewportTexture::setup_local_to_scene() {
if (loc_scene->is_ready()) {
_setup_local_to_scene(loc_scene);
} else {
- loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
+ loc_scene->connect(SceneStringName(ready), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
vp_pending = true;
}
}
@@ -1465,7 +1464,7 @@ void Viewport::_gui_show_tooltip() {
gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel"));
gui.tooltip_label->set_text(gui.tooltip_text);
base_tooltip = gui.tooltip_label;
- panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip));
+ panel->connect(SceneStringName(mouse_entered), callable_mp(this, &Viewport::_gui_cancel_tooltip));
}
base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 929720fcf4..addbd6078a 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -37,7 +37,6 @@
#include "core/string/translation.h"
#include "core/variant/variant_parser.h"
#include "scene/gui/control.h"
-#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
#include "scene/theme/theme_owner.h"
@@ -307,10 +306,21 @@ String Window::get_title() const {
return title;
}
+void Window::_settings_changed() {
+ if (visible && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE && is_in_edited_scene_root()) {
+ Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
+ position = (screen_size - size) / 2;
+ if (embedder) {
+ embedder->_sub_window_update(this);
+ }
+ }
+}
+
void Window::set_initial_position(Window::WindowInitialPosition p_initial_position) {
ERR_MAIN_THREAD_GUARD;
initial_position = p_initial_position;
+ _settings_changed();
notify_property_list_changed();
}
@@ -742,13 +752,13 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
focused = true;
_propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN);
- emit_signal(SNAME("focus_entered"));
+ emit_signal(SceneStringName(focus_entered));
} break;
case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
focused = false;
_propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT);
- emit_signal(SNAME("focus_exited"));
+ emit_signal(SceneStringName(focus_exited));
} break;
case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: {
if (exclusive_child != nullptr) {
@@ -830,7 +840,12 @@ void Window::set_visible(bool p_visible) {
if (visible) {
embedder = embedder_vp;
if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
- position = (embedder->get_visible_rect().size - size) / 2;
+ if (is_in_edited_scene_root()) {
+ Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
+ position = (screen_size - size) / 2;
+ } else {
+ position = (embedder->get_visible_rect().size - size) / 2;
+ }
}
embedder->_sub_window_register(this);
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
@@ -846,7 +861,7 @@ void Window::set_visible(bool p_visible) {
focused = false;
}
notification(NOTIFICATION_VISIBILITY_CHANGED);
- emit_signal(SceneStringNames::get_singleton()->visibility_changed);
+ emit_signal(SceneStringName(visibility_changed));
RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible);
@@ -1266,6 +1281,12 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
+ if (is_in_edited_scene_root()) {
+ if (!ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) {
+ ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Window::_settings_changed));
+ }
+ }
+
bool embedded = false;
{
embedder = get_embedder();
@@ -1281,7 +1302,12 @@ void Window::_notification(int p_what) {
// Create as embedded.
if (embedder) {
if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
- position = (embedder->get_visible_rect().size - size) / 2;
+ if (is_in_edited_scene_root()) {
+ Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
+ position = (screen_size - size) / 2;
+ } else {
+ position = (embedder->get_visible_rect().size - size) / 2;
+ }
}
embedder->_sub_window_register(this);
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
@@ -1321,7 +1347,7 @@ void Window::_notification(int p_what) {
}
if (visible) {
notification(NOTIFICATION_VISIBILITY_CHANGED);
- emit_signal(SceneStringNames::get_singleton()->visibility_changed);
+ emit_signal(SceneStringName(visibility_changed));
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
}
@@ -1337,7 +1363,7 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- emit_signal(SceneStringNames::get_singleton()->theme_changed);
+ emit_signal(SceneStringName(theme_changed));
_invalidate_theme_cache();
_update_theme_item_cache();
} break;
@@ -1378,6 +1404,10 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ if (ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) {
+ ProjectSettings::get_singleton()->disconnect("settings_changed", callable_mp(this, &Window::_settings_changed));
+ }
+
set_theme_context(nullptr, false);
if (transient) {
@@ -1404,11 +1434,11 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_VP_MOUSE_ENTER: {
- emit_signal(SceneStringNames::get_singleton()->mouse_entered);
+ emit_signal(SceneStringName(mouse_entered));
} break;
case NOTIFICATION_VP_MOUSE_EXIT: {
- emit_signal(SceneStringNames::get_singleton()->mouse_exited);
+ emit_signal(SceneStringName(mouse_exited));
} break;
}
}
@@ -1622,7 +1652,7 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
_input_from_window(p_ev);
if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) {
- emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
+ emit_signal(SceneStringName(window_input), p_ev);
}
if (is_inside_tree()) {
diff --git a/scene/main/window.h b/scene/main/window.h
index ffcf50ccdd..33d593711f 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -214,6 +214,8 @@ private:
int resize_margin = 0;
} theme_cache;
+ void _settings_changed();
+
Viewport *embedder = nullptr;
Transform2D window_transform;
diff --git a/scene/property_list_helper.cpp b/scene/property_list_helper.cpp
index b666e4c52d..152ecaf89d 100644
--- a/scene/property_list_helper.cpp
+++ b/scene/property_list_helper.cpp
@@ -36,14 +36,17 @@ const PropertyListHelper::Property *PropertyListHelper::_get_property(const Stri
return nullptr;
}
- {
- const String index_string = components[0].trim_prefix(prefix);
- if (!index_string.is_valid_int()) {
- return nullptr;
- }
- *r_index = index_string.to_int();
+ const String index_string = components[0].trim_prefix(prefix);
+ if (!index_string.is_valid_int()) {
+ return nullptr;
+ }
+
+ int index = index_string.to_int();
+ if (index < 0 || index >= _call_array_length_getter()) {
+ return nullptr;
}
+ *r_index = index;
return property_list.getptr(components[1]);
}
@@ -66,6 +69,11 @@ Variant PropertyListHelper::_call_getter(const Property *p_property, int p_index
return p_property->getter->call(object, argptrs, 1, ce);
}
+int PropertyListHelper::_call_array_length_getter() const {
+ Callable::CallError ce;
+ return array_length_getter->call(object, nullptr, 0, ce);
+}
+
void PropertyListHelper::set_prefix(const String &p_prefix) {
prefix = p_prefix;
}
@@ -83,7 +91,13 @@ bool PropertyListHelper::is_initialized() const {
}
void PropertyListHelper::setup_for_instance(const PropertyListHelper &p_base, Object *p_object) {
+ DEV_ASSERT(!p_base.prefix.is_empty());
+ DEV_ASSERT(p_base.array_length_getter != nullptr);
+ DEV_ASSERT(!p_base.property_list.is_empty());
+ DEV_ASSERT(p_object != nullptr);
+
prefix = p_base.prefix;
+ array_length_getter = p_base.array_length_getter;
property_list = p_base.property_list;
object = p_object;
}
diff --git a/scene/property_list_helper.h b/scene/property_list_helper.h
index eac6b03d47..e19e7cd22e 100644
--- a/scene/property_list_helper.h
+++ b/scene/property_list_helper.h
@@ -43,15 +43,22 @@ class PropertyListHelper {
};
String prefix;
+ MethodBind *array_length_getter = nullptr;
HashMap<String, Property> property_list;
Object *object = nullptr;
const Property *_get_property(const String &p_property, int *r_index) const;
void _call_setter(const MethodBind *p_setter, int p_index, const Variant &p_value) const;
Variant _call_getter(const Property *p_property, int p_index) const;
+ int _call_array_length_getter() const;
public:
void set_prefix(const String &p_prefix);
+ template <typename G>
+ void set_array_length_getter(G p_array_length_getter) {
+ array_length_getter = create_method_bind(p_array_length_getter);
+ }
+
// Register property without setter/getter. Only use when you don't need PropertyListHelper for _set/_get logic.
void register_property(const PropertyInfo &p_info, const Variant &p_default);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 6fac096c93..aa8ff75c6a 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -155,7 +155,6 @@
#include "scene/resources/visual_shader_particle_nodes.h"
#include "scene/resources/visual_shader_sdf_nodes.h"
#include "scene/resources/world_2d.h"
-#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
// 2D
@@ -589,7 +588,7 @@ void register_scene_types() {
GDREGISTER_CLASS(CPUParticles3D);
GDREGISTER_CLASS(Marker3D);
GDREGISTER_CLASS(RootMotionView);
- GDREGISTER_ABSTRACT_CLASS(SkeletonModifier3D);
+ GDREGISTER_VIRTUAL_CLASS(SkeletonModifier3D);
OS::get_singleton()->yield(); // may take time to init
@@ -744,6 +743,7 @@ void register_scene_types() {
GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeVarying);
GDREGISTER_CLASS(VisualShaderNodeVaryingSetter);
GDREGISTER_CLASS(VisualShaderNodeVaryingGetter);
+ GDREGISTER_CLASS(VisualShaderNodeReroute);
GDREGISTER_CLASS(VisualShaderNodeSDFToScreenUV);
GDREGISTER_CLASS(VisualShaderNodeScreenUVToSDF);
diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp
index 6649cb9b82..6c3356a205 100644
--- a/scene/resources/2d/tile_set.cpp
+++ b/scene/resources/2d/tile_set.cpp
@@ -74,7 +74,7 @@ void TileMapPattern::_set_tile_data(const Vector<int> &p_data) {
uint16_t alternative_tile = decode_uint16(&local[10]);
set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile);
}
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector<int> TileMapPattern::_get_tile_data() const {
@@ -4969,7 +4969,7 @@ void TileSetAtlasSource::create_tile(const Vector2i p_atlas_coords, const Vector
tad.alternatives[0] = memnew(TileData);
tad.alternatives[0]->set_tile_set(tile_set);
tad.alternatives[0]->set_allow_transform(false);
- tad.alternatives[0]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
+ tad.alternatives[0]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
tad.alternatives[0]->notify_property_list_changed();
tad.alternatives_ids.push_back(0);
@@ -5353,7 +5353,7 @@ int TileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_coords, i
tiles[p_atlas_coords].alternatives[new_alternative_id] = memnew(TileData);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_tile_set(tile_set);
tiles[p_atlas_coords].alternatives[new_alternative_id]->set_allow_transform(true);
- tiles[p_atlas_coords].alternatives[new_alternative_id]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
+ tiles[p_atlas_coords].alternatives[new_alternative_id]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed));
tiles[p_atlas_coords].alternatives[new_alternative_id]->notify_property_list_changed();
tiles[p_atlas_coords].alternatives_ids.push_back(new_alternative_id);
tiles[p_atlas_coords].alternatives_ids.sort();
@@ -5938,7 +5938,7 @@ void TileData::notify_tile_data_properties_should_change() {
}
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::add_occlusion_layer(int p_to_pos) {
@@ -6139,7 +6139,7 @@ TileData *TileData::duplicate() {
void TileData::set_flip_h(bool p_flip_h) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_h, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_h = p_flip_h;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_flip_h() const {
return flip_h;
@@ -6148,7 +6148,7 @@ bool TileData::get_flip_h() const {
void TileData::set_flip_v(bool p_flip_v) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_v, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_v = p_flip_v;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_flip_v() const {
@@ -6158,7 +6158,7 @@ bool TileData::get_flip_v() const {
void TileData::set_transpose(bool p_transpose) {
ERR_FAIL_COND_MSG(!allow_transform && p_transpose, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
transpose = p_transpose;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::get_transpose() const {
return transpose;
@@ -6166,7 +6166,7 @@ bool TileData::get_transpose() const {
void TileData::set_texture_origin(Vector2i p_texture_origin) {
texture_origin = p_texture_origin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector2i TileData::get_texture_origin() const {
@@ -6175,7 +6175,7 @@ Vector2i TileData::get_texture_origin() const {
void TileData::set_material(Ref<Material> p_material) {
material = p_material;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<Material> TileData::get_material() const {
return material;
@@ -6183,7 +6183,7 @@ Ref<Material> TileData::get_material() const {
void TileData::set_modulate(Color p_modulate) {
modulate = p_modulate;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Color TileData::get_modulate() const {
return modulate;
@@ -6191,7 +6191,7 @@ Color TileData::get_modulate() const {
void TileData::set_z_index(int p_z_index) {
z_index = p_z_index;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_z_index() const {
return z_index;
@@ -6199,7 +6199,7 @@ int TileData::get_z_index() const {
void TileData::set_y_sort_origin(int p_y_sort_origin) {
y_sort_origin = p_y_sort_origin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_y_sort_origin() const {
return y_sort_origin;
@@ -6209,7 +6209,7 @@ void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_po
ERR_FAIL_INDEX(p_layer_id, occluders.size());
occluders.write[p_layer_id].occluder = p_occluder_polygon;
occluders.write[p_layer_id].transformed_occluders.clear();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
@@ -6242,7 +6242,7 @@ Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, boo
void TileData::set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].linear_velocity = p_velocity;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const {
@@ -6253,7 +6253,7 @@ Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const {
void TileData::set_constant_angular_velocity(int p_layer_id, real_t p_velocity) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].angular_velocity = p_velocity;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
real_t TileData::get_constant_angular_velocity(int p_layer_id) const {
@@ -6269,7 +6269,7 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count
}
physics.write[p_layer_id].polygons.resize(p_polygons_count);
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_collision_polygons_count(int p_layer_id) const {
@@ -6280,14 +6280,14 @@ int TileData::get_collision_polygons_count(int p_layer_id) const {
void TileData::add_collision_polygon(int p_layer_id) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData());
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::remove_collision_polygon(int p_layer_id, int p_polygon_index) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.remove_at(p_polygon_index);
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon) {
@@ -6314,7 +6314,7 @@ void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index,
}
polygon_shape_tile_data.transformed_shapes.clear();
polygon_shape_tile_data.polygon = p_polygon;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Vector<Vector2> TileData::get_collision_polygon_points(int p_layer_id, int p_polygon_index) const {
@@ -6327,7 +6327,7 @@ void TileData::set_collision_polygon_one_way(int p_layer_id, int p_polygon_index
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way = p_one_way;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
bool TileData::is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const {
@@ -6340,7 +6340,7 @@ void TileData::set_collision_polygon_one_way_margin(int p_layer_id, int p_polygo
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way_margin = p_one_way_margin;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
float TileData::get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const {
@@ -6378,7 +6378,7 @@ Ref<ConvexPolygonShape2D> TileData::get_collision_polygon_shape(int p_layer_id,
for (int i = 0; i < size; i++) {
Ref<ConvexPolygonShape2D> transformed_polygon;
transformed_polygon.instantiate();
- transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[shape_index]->get_points(), p_flip_h, p_flip_v, p_transpose));
+ transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[i]->get_points(), p_flip_h, p_flip_v, p_transpose));
shapes_data.transformed_shapes[key][i] = transformed_polygon;
}
return shapes_data.transformed_shapes[key][shape_index];
@@ -6402,7 +6402,7 @@ void TileData::set_terrain_set(int p_terrain_set) {
}
terrain_set = p_terrain_set;
notify_property_list_changed();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain_set() const {
@@ -6416,7 +6416,7 @@ void TileData::set_terrain(int p_terrain) {
ERR_FAIL_COND(p_terrain >= tile_set->get_terrains_count(terrain_set));
}
terrain = p_terrain;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain() const {
@@ -6432,7 +6432,7 @@ void TileData::set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int
ERR_FAIL_COND(!is_valid_terrain_peering_bit(p_peering_bit));
}
terrain_peering_bits[p_peering_bit] = p_terrain_index;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
int TileData::get_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const {
@@ -6464,7 +6464,7 @@ void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_n
ERR_FAIL_INDEX(p_layer_id, navigation.size());
navigation.write[p_layer_id].navigation_polygon = p_navigation_polygon;
navigation.write[p_layer_id].transformed_navigation_polygon.clear();
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
@@ -6512,7 +6512,7 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f
void TileData::set_probability(float p_probability) {
ERR_FAIL_COND(p_probability < 0.0);
probability = p_probability;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
float TileData::get_probability() const {
return probability;
@@ -6536,7 +6536,7 @@ Variant TileData::get_custom_data(String p_layer_name) const {
void TileData::set_custom_data_by_layer_id(int p_layer_id, Variant p_value) {
ERR_FAIL_INDEX(p_layer_id, custom_data.size());
custom_data.write[p_layer_id] = p_value;
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
diff --git a/scene/resources/3d/world_3d.cpp b/scene/resources/3d/world_3d.cpp
index 7948a8bfd5..b743b24262 100644
--- a/scene/resources/3d/world_3d.cpp
+++ b/scene/resources/3d/world_3d.cpp
@@ -35,7 +35,6 @@
#include "scene/3d/visible_on_screen_notifier_3d.h"
#include "scene/resources/camera_attributes.h"
#include "scene/resources/environment.h"
-#include "scene/scene_string_names.h"
#include "servers/navigation_server_3d.h"
void World3D::_register_camera(Camera3D *p_camera) {
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index d7b9528248..a3bfa987c6 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -33,7 +33,6 @@
#include "core/io/marshalls.h"
#include "core/math/geometry_3d.h"
-#include "scene/scene_string_names.h"
bool Animation::_set(const StringName &p_name, const Variant &p_value) {
String prop_name = p_name;
diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp
index 79d06c4d66..22666876ae 100644
--- a/scene/resources/animation_library.cpp
+++ b/scene/resources/animation_library.cpp
@@ -30,6 +30,8 @@
#include "animation_library.h"
+#include "scene/scene_string_names.h"
+
bool AnimationLibrary::is_valid_animation_name(const String &p_name) {
return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("["));
}
@@ -106,7 +108,7 @@ TypedArray<StringName> AnimationLibrary::_get_animation_list() const {
}
void AnimationLibrary::_animation_changed(const StringName &p_name) {
- emit_signal(SNAME("animation_changed"), p_name);
+ emit_signal(SceneStringName(animation_changed), p_name);
}
void AnimationLibrary::get_animation_list(List<StringName> *p_animations) const {
diff --git a/scene/resources/atlas_texture.cpp b/scene/resources/atlas_texture.cpp
index 6aed68849b..ef2f1eb135 100644
--- a/scene/resources/atlas_texture.cpp
+++ b/scene/resources/atlas_texture.cpp
@@ -30,8 +30,6 @@
#include "atlas_texture.h"
-#include "core/core_string_names.h"
-
int AtlasTexture::get_width() const {
if (region.size.width == 0) {
if (atlas.is_valid()) {
diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp
index 31c8e68ea5..76e99aca92 100644
--- a/scene/resources/canvas_item_material.cpp
+++ b/scene/resources/canvas_item_material.cpp
@@ -33,13 +33,11 @@
#include "core/version.h"
Mutex CanvasItemMaterial::material_mutex;
-SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr;
+SelfList<CanvasItemMaterial>::List CanvasItemMaterial::dirty_materials;
HashMap<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData, CanvasItemMaterial::MaterialKey> CanvasItemMaterial::shader_map;
CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr;
void CanvasItemMaterial::init_shaders() {
- dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
-
shader_names = memnew(ShaderNames);
shader_names->particles_anim_h_frames = "particles_anim_h_frames";
@@ -48,14 +46,13 @@ void CanvasItemMaterial::init_shaders() {
}
void CanvasItemMaterial::finish_shaders() {
- memdelete(dirty_materials);
+ dirty_materials.clear();
+
memdelete(shader_names);
- dirty_materials = nullptr;
+ shader_names = nullptr;
}
void CanvasItemMaterial::_update_shader() {
- dirty_materials->remove(&element);
-
MaterialKey mk = _compute_key();
if (mk.key == current_key.key) {
return; //no update required in the end
@@ -153,8 +150,9 @@ void CanvasItemMaterial::_update_shader() {
void CanvasItemMaterial::flush_changes() {
MutexLock lock(material_mutex);
- while (dirty_materials->first()) {
- dirty_materials->first()->self()->_update_shader();
+ while (dirty_materials.first()) {
+ dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -162,16 +160,10 @@ void CanvasItemMaterial::_queue_shader_change() {
MutexLock lock(material_mutex);
if (_is_initialized() && !element.in_list()) {
- dirty_materials->add(&element);
+ dirty_materials.add(&element);
}
}
-bool CanvasItemMaterial::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
blend_mode = p_blend_mode;
_queue_shader_change();
@@ -288,7 +280,7 @@ CanvasItemMaterial::CanvasItemMaterial() :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change), callable_mp(this, &CanvasItemMaterial::_update_shader));
}
CanvasItemMaterial::~CanvasItemMaterial() {
diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h
index 7dddd74a31..ef498c2ff6 100644
--- a/scene/resources/canvas_item_material.h
+++ b/scene/resources/canvas_item_material.h
@@ -98,12 +98,11 @@ private:
}
static Mutex material_mutex;
- static SelfList<CanvasItemMaterial>::List *dirty_materials;
+ static SelfList<CanvasItemMaterial>::List dirty_materials;
SelfList<CanvasItemMaterial> element;
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
BlendMode blend_mode = BLEND_MODE_MIX;
LightMode light_mode = LIGHT_MODE_NORMAL;
diff --git a/scene/resources/curve_texture.cpp b/scene/resources/curve_texture.cpp
index 488a527bbb..4ba5393110 100644
--- a/scene/resources/curve_texture.cpp
+++ b/scene/resources/curve_texture.cpp
@@ -30,8 +30,6 @@
#include "curve_texture.h"
-#include "core/core_string_names.h"
-
void CurveTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
diff --git a/scene/resources/gradient_texture.cpp b/scene/resources/gradient_texture.cpp
index 327a99c6ad..6ec9422d2d 100644
--- a/scene/resources/gradient_texture.cpp
+++ b/scene/resources/gradient_texture.cpp
@@ -30,7 +30,6 @@
#include "gradient_texture.h"
-#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
GradientTexture1D::GradientTexture1D() {
@@ -137,6 +136,7 @@ void GradientTexture1D::_update() {
texture = RS::get_singleton()->texture_2d_create(image);
}
}
+ RS::get_singleton()->texture_set_path(texture, get_path());
}
void GradientTexture1D::set_width(int p_width) {
@@ -276,6 +276,7 @@ void GradientTexture2D::_update() {
} else {
texture = RS::get_singleton()->texture_2d_create(image);
}
+ RS::get_singleton()->texture_set_path(texture, get_path());
}
float GradientTexture2D::_get_gradient_offset_at(int x, int y) const {
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 15b40e776c..8e49a8b56f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -35,7 +35,6 @@
#include "core/error/error_macros.h"
#include "core/version.h"
#include "scene/main/scene_tree.h"
-#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
@@ -82,24 +81,25 @@ void Material::_validate_property(PropertyInfo &p_property) const {
}
}
-void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) {
+void Material::_mark_ready() {
+ init_state = INIT_STATE_INITIALIZING;
+}
+
+void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader) {
// If this is happening as part of resource loading, it is not safe to queue the update
- // as an addition to the dirty list, unless the load is happening on the main thread.
- if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) {
+ // as an addition to the dirty list. It would be if the load is happening on the main thread,
+ // but even so we'd rather perform the update directly instead of using the dirty list.
+ if (ResourceLoader::is_within_load()) {
DEV_ASSERT(init_state != INIT_STATE_READY);
if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice.
- // Let's mark this material as being initialized.
init_state = INIT_STATE_INITIALIZING;
- // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these:
- // 1. Queue setting the init state to INIT_STATE_READY finally.
- callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred();
- // 2. Queue an individual update of this material.
- p_queue_shader_change_callable.call_deferred();
+ callable_mp(this, &Material::_mark_ready).call_deferred();
+ p_update_shader.call_deferred();
}
} else {
// Straightforward conditions.
init_state = INIT_STATE_READY;
- p_queue_shader_change_callable.callv(Array());
+ p_add_to_dirty_list.call();
}
}
@@ -603,8 +603,6 @@ void BaseMaterial3D::finish_shaders() {
}
void BaseMaterial3D::_update_shader() {
- dirty_materials.remove(&element);
-
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
@@ -824,7 +822,18 @@ uniform float distance_fade_max : hint_range(0.0, 4096.0, 0.01);
)";
}
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && flags[FLAG_UV1_USE_TRIPLANAR]) {
+ String msg = "MSDF is not supported on triplanar materials. Ignoring MSDF in favor of triplanar mapping.";
+ if (textures[TEXTURE_ALBEDO].is_valid()) {
+ WARN_PRINT(vformat("%s (albedo %s): " + msg, get_path(), textures[TEXTURE_ALBEDO]->get_path()));
+ } else if (!get_path().is_empty()) {
+ WARN_PRINT(vformat("%s: " + msg, get_path()));
+ } else {
+ WARN_PRINT(msg);
+ }
+ }
+
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
uniform float msdf_pixel_range : hint_range(1.0, 100.0, 1.0);
uniform float msdf_outline_size : hint_range(0.0, 250.0, 1.0);
@@ -1273,7 +1282,7 @@ void vertex() {)";
code += "}\n";
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
float msdf_median(float r, float g, float b, float a) {
return min(max(min(r, g), min(max(r, g), b)), a);
@@ -1416,7 +1425,7 @@ void fragment() {)";
}
}
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
{
// Albedo Texture MSDF: Enabled
@@ -1429,11 +1438,7 @@ void fragment() {)";
if (flags[FLAG_USE_POINT_SIZE]) {
code += " vec2 dest_size = vec2(1.0) / fwidth(POINT_COORD);\n";
} else {
- if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += " vec2 dest_size = vec2(1.0) / fwidth(uv1_triplanar_pos);\n";
- } else {
- code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n";
- }
+ code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n";
}
code += R"(
float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0);
@@ -1855,6 +1860,7 @@ void BaseMaterial3D::flush_changes() {
while (dirty_materials.first()) {
dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -1866,12 +1872,6 @@ void BaseMaterial3D::_queue_shader_change() {
}
}
-bool BaseMaterial3D::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
@@ -2824,7 +2824,7 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
RID BaseMaterial3D::get_shader_rid() const {
MutexLock lock(material_mutex);
- if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock
+ if (element.in_list()) {
((BaseMaterial3D *)this)->_update_shader();
}
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
@@ -3412,7 +3412,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader));
}
BaseMaterial3D::~BaseMaterial3D() {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index ecf79c581b..50a774e961 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -62,7 +62,8 @@ protected:
void _validate_property(PropertyInfo &p_property) const;
- void _mark_initialized(const Callable &p_queue_shader_change_callable);
+ void _mark_ready();
+ void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader);
bool _is_initialized() { return init_state == INIT_STATE_READY; }
GDVIRTUAL0RC(RID, _get_shader_rid)
@@ -466,7 +467,6 @@ private:
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
bool orm;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 407b12d72f..0c57c6b7ba 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
#include "core/io/missing_resource.h"
#include "core/io/resource_loader.h"
#include "core/templates/local_vector.h"
@@ -315,6 +314,16 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
ERR_FAIL_INDEX_V(nprops[j].value, prop_count, nullptr);
if (nprops[j].name & FLAG_PATH_PROPERTY_IS_NODE) {
+ if (!Engine::get_singleton()->is_editor_hint() && node->get_scene_instance_load_placeholder()) {
+ // We cannot know if the referenced nodes exist yet, so instead of deferring, we write the NodePaths directly.
+
+ uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1);
+ ERR_FAIL_UNSIGNED_INDEX_V(name_idx, (uint32_t)sname_count, nullptr);
+
+ node->set(snames[name_idx], props[nprops[j].value], &valid);
+ continue;
+ }
+
uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1);
ERR_FAIL_UNSIGNED_INDEX_V(name_idx, (uint32_t)sname_count, nullptr);
@@ -328,7 +337,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
- if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) {
+ if (snames[nprops[j].name] == CoreStringName(script)) {
//work around to avoid old script variables from disappearing, should be the proper fix to:
//https://github.com/godotengine/godot/issues/2958
diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp
index 0b65b33240..01d26a8bed 100644
--- a/scene/resources/particle_process_material.cpp
+++ b/scene/resources/particle_process_material.cpp
@@ -33,14 +33,12 @@
#include "core/version.h"
Mutex ParticleProcessMaterial::material_mutex;
-SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr;
+SelfList<ParticleProcessMaterial>::List ParticleProcessMaterial::dirty_materials;
HashMap<ParticleProcessMaterial::MaterialKey, ParticleProcessMaterial::ShaderData, ParticleProcessMaterial::MaterialKey> ParticleProcessMaterial::shader_map;
RBSet<String> ParticleProcessMaterial::min_max_properties;
ParticleProcessMaterial::ShaderNames *ParticleProcessMaterial::shader_names = nullptr;
void ParticleProcessMaterial::init_shaders() {
- dirty_materials = memnew(SelfList<ParticleProcessMaterial>::List);
-
shader_names = memnew(ShaderNames);
shader_names->direction = "direction";
@@ -140,15 +138,13 @@ void ParticleProcessMaterial::init_shaders() {
}
void ParticleProcessMaterial::finish_shaders() {
- memdelete(dirty_materials);
- dirty_materials = nullptr;
+ dirty_materials.clear();
memdelete(shader_names);
+ shader_names = nullptr;
}
void ParticleProcessMaterial::_update_shader() {
- dirty_materials->remove(&element);
-
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
@@ -634,7 +630,7 @@ void ParticleProcessMaterial::_update_shader() {
if (emission_shape == EMISSION_SHAPE_RING) {
code += " \n";
code += " float ring_spawn_angle = rand_from_seed(alt_seed) * 2.0 * pi;\n";
- code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n";
+ code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n";
code += " vec3 axis = emission_ring_axis == vec3(0.0) ? vec3(0.0, 0.0, 1.0) : normalize(emission_ring_axis);\n";
code += " vec3 ortho_axis = vec3(0.0);\n";
code += " if (abs(axis) == vec3(1.0, 0.0, 0.0)) {\n";
@@ -995,13 +991,15 @@ void ParticleProcessMaterial::_update_shader() {
code += " \n";
if (collision_mode == COLLISION_RIGID) {
code += " if (COLLIDED) {\n";
- code += " if (length(VELOCITY) > 3.0) {\n";
- code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n";
- code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n";
- code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n";
- code += " } else {\n";
- code += " VELOCITY = vec3(0.0);\n";
- code += " }\n";
+ code += " float collision_response = dot(COLLISION_NORMAL, VELOCITY);\n";
+ code += " float slide_to_bounce_trigger = step(2.0/clamp(collision_bounce + 1.0, 1.0, 2.0), abs(collision_response));\n";
+ code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n";
+ code += " // Remove all components of VELOCITY that is not tangent to COLLISION_NORMAL\n";
+ code += " VELOCITY -= COLLISION_NORMAL * collision_response;\n";
+ code += " // Apply friction only to VELOCITY across the surface (Effectively decouples friction and bounce behavior).\n";
+ code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n";
+ code += " // Add bounce velocity to VELOCITY\n";
+ code += " VELOCITY -= COLLISION_NORMAL * collision_response * (collision_bounce * slide_to_bounce_trigger);\n";
code += " }\n";
} else if (collision_mode == COLLISION_HIDE_ON_CONTACT) {
code += " if (COLLIDED) {\n";
@@ -1170,8 +1168,9 @@ void ParticleProcessMaterial::_update_shader() {
void ParticleProcessMaterial::flush_changes() {
MutexLock lock(material_mutex);
- while (dirty_materials->first()) {
- dirty_materials->first()->self()->_update_shader();
+ while (dirty_materials.first()) {
+ dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -1179,16 +1178,10 @@ void ParticleProcessMaterial::_queue_shader_change() {
MutexLock lock(material_mutex);
if (_is_initialized() && !element.in_list()) {
- dirty_materials->add(&element);
+ dirty_materials.add(&element);
}
}
-bool ParticleProcessMaterial::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
bool ParticleProcessMaterial::has_min_max_property(const String &p_name) {
return min_max_properties.has(p_name);
}
@@ -2330,7 +2323,7 @@ ParticleProcessMaterial::ParticleProcessMaterial() :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change), callable_mp(this, &ParticleProcessMaterial::_update_shader));
}
ParticleProcessMaterial::~ParticleProcessMaterial() {
diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h
index 94b2009654..25046b51cd 100644
--- a/scene/resources/particle_process_material.h
+++ b/scene/resources/particle_process_material.h
@@ -186,7 +186,7 @@ private:
}
static Mutex material_mutex;
- static SelfList<ParticleProcessMaterial>::List *dirty_materials;
+ static SelfList<ParticleProcessMaterial>::List dirty_materials;
struct ShaderNames {
StringName direction;
@@ -293,7 +293,6 @@ private:
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
Vector3 direction;
float spread = 0.0f;
diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp
index 918b5c0b41..002db30379 100644
--- a/scene/resources/portable_compressed_texture.cpp
+++ b/scene/resources/portable_compressed_texture.cpp
@@ -153,14 +153,14 @@ void PortableCompressedTexture2D::create_from_image(const Ref<Image> &p_image, C
for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
Vector<uint8_t> data;
if (p_compression_mode == COMPRESSION_MODE_LOSSY) {
- data = Image::webp_lossy_packer(p_image->get_image_from_mipmap(i), p_lossy_quality);
+ data = Image::webp_lossy_packer(i ? p_image->get_image_from_mipmap(i) : p_image, p_lossy_quality);
encode_uint16(DATA_FORMAT_WEBP, buffer.ptrw() + 2);
} else {
if (use_webp) {
- data = Image::webp_lossless_packer(p_image->get_image_from_mipmap(i));
+ data = Image::webp_lossless_packer(i ? p_image->get_image_from_mipmap(i) : p_image);
encode_uint16(DATA_FORMAT_WEBP, buffer.ptrw() + 2);
} else {
- data = Image::png_packer(p_image->get_image_from_mipmap(i));
+ data = Image::png_packer(i ? p_image->get_image_from_mipmap(i) : p_image);
encode_uint16(DATA_FORMAT_PNG, buffer.ptrw() + 2);
}
}
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 2e27ac9198..7c13e623c2 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -33,9 +33,7 @@
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "core/io/missing_resource.h"
-#include "core/io/resource_format_binary.h"
#include "core/object/script_language.h"
-#include "core/version.h"
// Version 2: Changed names for Basis, AABB, Vectors, etc.
// Version 3: New string ID for ext/subresources, breaks forward compat.
@@ -44,11 +42,6 @@
// For compat, save as version 3 if not using PackedVector4Array or no big PackedByteArray.
#define FORMAT_VERSION_COMPAT 3
-#define BINARY_FORMAT_VERSION 4
-
-#include "core/io/dir_access.h"
-#include "core/version.h"
-
#define _printerr() ERR_PRINT(String(res_path + ":" + itos(lines) + " - Parse Error: " + error_text).utf8().get_data());
///
@@ -1127,298 +1120,6 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
rp.userdata = this;
}
-static void bs_save_unicode_string(Ref<FileAccess> p_f, const String &p_string, bool p_bit_on_len = false) {
- CharString utf8 = p_string.utf8();
- if (p_bit_on_len) {
- p_f->store_32((utf8.length() + 1) | 0x80000000);
- } else {
- p_f->store_32(utf8.length() + 1);
- }
- p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
-}
-
-Error ResourceLoaderText::save_as_binary(const String &p_path) {
- if (error) {
- return error;
- }
-
- Ref<FileAccess> wf = FileAccess::open(p_path, FileAccess::WRITE);
- if (wf.is_null()) {
- return ERR_CANT_OPEN;
- }
-
- //save header compressed
- static const uint8_t header[4] = { 'R', 'S', 'R', 'C' };
- wf->store_buffer(header, 4);
-
- wf->store_32(0); //endianness, little endian
- wf->store_32(0); //64 bits file, false for now
- wf->store_32(VERSION_MAJOR);
- wf->store_32(VERSION_MINOR);
- static const int save_format_version = BINARY_FORMAT_VERSION;
- wf->store_32(save_format_version);
-
- bs_save_unicode_string(wf, is_scene ? "PackedScene" : resource_type);
- wf->store_64(0); //offset to import metadata, this is no longer used
-
- wf->store_32(ResourceFormatSaverBinaryInstance::FORMAT_FLAG_NAMED_SCENE_IDS | ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS);
-
- wf->store_64(res_uid);
-
- for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) {
- wf->store_32(0); // reserved
- }
-
- wf->store_32(0); //string table size, will not be in use
- uint64_t ext_res_count_pos = wf->get_position();
-
- wf->store_32(0); //zero ext resources, still parsing them
-
- //go with external resources
-
- DummyReadData dummy_read;
- VariantParser::ResourceParser rp_new;
- rp_new.ext_func = _parse_ext_resource_dummys;
- rp_new.sub_func = _parse_sub_resource_dummys;
- rp_new.userdata = &dummy_read;
-
- while (next_tag.name == "ext_resource") {
- if (!next_tag.fields.has("path")) {
- error = ERR_FILE_CORRUPT;
- error_text = "Missing 'path' in external resource tag";
- _printerr();
- return error;
- }
-
- if (!next_tag.fields.has("type")) {
- error = ERR_FILE_CORRUPT;
- error_text = "Missing 'type' in external resource tag";
- _printerr();
- return error;
- }
-
- if (!next_tag.fields.has("id")) {
- error = ERR_FILE_CORRUPT;
- error_text = "Missing 'id' in external resource tag";
- _printerr();
- return error;
- }
-
- String path = next_tag.fields["path"];
- String type = next_tag.fields["type"];
- String id = next_tag.fields["id"];
- ResourceUID::ID uid = ResourceUID::INVALID_ID;
- if (next_tag.fields.has("uid")) {
- String uidt = next_tag.fields["uid"];
- uid = ResourceUID::get_singleton()->text_to_id(uidt);
- }
-
- bs_save_unicode_string(wf, type);
- bs_save_unicode_string(wf, path);
- wf->store_64(uid);
-
- int lindex = dummy_read.external_resources.size();
- Ref<DummyResource> dr;
- dr.instantiate();
- dr->set_path("res://dummy" + itos(lindex)); //anything is good to detect it for saving as external
- dummy_read.external_resources[dr] = lindex;
- dummy_read.rev_external_resources[id] = dr;
-
- error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp_new);
-
- if (error) {
- _printerr();
- return error;
- }
- }
-
- // save external resource table
- wf->seek(ext_res_count_pos);
- wf->store_32(dummy_read.external_resources.size());
- wf->seek_end();
-
- //now, save resources to a separate file, for now
-
- uint64_t sub_res_count_pos = wf->get_position();
- wf->store_32(0); //zero sub resources, still parsing them
-
- String temp_file = p_path + ".temp";
- Vector<uint64_t> local_offsets;
- Vector<uint64_t> local_pointers_pos;
- {
- Ref<FileAccess> wf2 = FileAccess::open(temp_file, FileAccess::WRITE);
- if (wf2.is_null()) {
- return ERR_CANT_OPEN;
- }
-
- while (next_tag.name == "sub_resource" || next_tag.name == "resource") {
- String type;
- String id;
- bool main_res;
-
- if (next_tag.name == "sub_resource") {
- if (!next_tag.fields.has("type")) {
- error = ERR_FILE_CORRUPT;
- error_text = "Missing 'type' in external resource tag";
- _printerr();
- return error;
- }
-
- if (!next_tag.fields.has("id")) {
- error = ERR_FILE_CORRUPT;
- error_text = "Missing 'id' in external resource tag";
- _printerr();
- return error;
- }
-
- type = next_tag.fields["type"];
- id = next_tag.fields["id"];
- main_res = false;
-
- if (!dummy_read.resource_map.has(id)) {
- Ref<DummyResource> dr;
- dr.instantiate();
- dr->set_scene_unique_id(id);
- dummy_read.resource_map[id] = dr;
- uint32_t im_size = dummy_read.resource_index_map.size();
- dummy_read.resource_index_map.insert(dr, im_size);
- }
-
- } else {
- type = res_type;
- String uid_text = ResourceUID::get_singleton()->id_to_text(res_uid);
- id = type + "_" + uid_text.replace("uid://", "").replace("<invalid>", "0");
- main_res = true;
- }
-
- local_offsets.push_back(wf2->get_position());
-
- bs_save_unicode_string(wf, "local://" + id);
- local_pointers_pos.push_back(wf->get_position());
- wf->store_64(0); //temp local offset
-
- bs_save_unicode_string(wf2, type);
- uint64_t propcount_ofs = wf2->get_position();
- wf2->store_32(0);
-
- int prop_count = 0;
-
- while (true) {
- String assign;
- Variant value;
-
- error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp_new);
-
- if (error) {
- if (main_res && error == ERR_FILE_EOF) {
- next_tag.name = ""; //exit
- break;
- }
-
- _printerr();
- return error;
- }
-
- if (!assign.is_empty()) {
- HashMap<StringName, int> empty_string_map; //unused
- bs_save_unicode_string(wf2, assign, true);
- ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map);
- prop_count++;
-
- } else if (!next_tag.name.is_empty()) {
- error = OK;
- break;
- } else {
- error = ERR_FILE_CORRUPT;
- error_text = "Premature end of file while parsing [sub_resource]";
- _printerr();
- return error;
- }
- }
-
- wf2->seek(propcount_ofs);
- wf2->store_32(prop_count);
- wf2->seek_end();
- }
-
- if (next_tag.name == "node") {
- // This is a node, must save one more!
-
- if (!is_scene) {
- error_text += "found the 'node' tag on a resource file!";
- _printerr();
- error = ERR_FILE_CORRUPT;
- return error;
- }
-
- Ref<PackedScene> packed_scene = _parse_node_tag(rp_new);
-
- if (!packed_scene.is_valid()) {
- return error;
- }
-
- error = OK;
- //get it here
- List<PropertyInfo> props;
- packed_scene->get_property_list(&props);
-
- String id = "PackedScene_" + ResourceUID::get_singleton()->id_to_text(res_uid).replace("uid://", "").replace("<invalid>", "0");
- bs_save_unicode_string(wf, "local://" + id);
- local_pointers_pos.push_back(wf->get_position());
- wf->store_64(0); //temp local offset
-
- local_offsets.push_back(wf2->get_position());
- bs_save_unicode_string(wf2, "PackedScene");
- uint64_t propcount_ofs = wf2->get_position();
- wf2->store_32(0);
-
- int prop_count = 0;
-
- for (const PropertyInfo &E : props) {
- if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
- continue;
- }
-
- String name = E.name;
- Variant value = packed_scene->get(name);
-
- HashMap<StringName, int> empty_string_map; //unused
- bs_save_unicode_string(wf2, name, true);
- ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map);
- prop_count++;
- }
-
- wf2->seek(propcount_ofs);
- wf2->store_32(prop_count);
- wf2->seek_end();
- }
- }
-
- uint64_t offset_from = wf->get_position();
- wf->seek(sub_res_count_pos); //plus one because the saved one
- wf->store_32(local_offsets.size());
-
- for (int i = 0; i < local_offsets.size(); i++) {
- wf->seek(local_pointers_pos[i]);
- wf->store_64(local_offsets[i] + offset_from);
- }
-
- wf->seek_end();
-
- Vector<uint8_t> data = FileAccess::get_file_as_bytes(temp_file);
- wf->store_buffer(data.ptr(), data.size());
- {
- Ref<DirAccess> dar = DirAccess::open(temp_file.get_base_dir());
- ERR_FAIL_COND_V(dar.is_null(), FAILED);
-
- dar->remove(temp_file);
- }
-
- wf->store_buffer((const uint8_t *)"RSRC", 4); //magic at end
-
- return OK;
-}
-
Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) {
if (error) {
return error;
@@ -1835,29 +1536,6 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const
ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = nullptr;
-Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) {
- Error err;
- Ref<FileAccess> f = FileAccess::open(p_src_path, FileAccess::READ, &err);
-
- ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_OPEN, "Cannot open file '" + p_src_path + "'.");
-
- ResourceLoaderText loader;
- const String &path = p_src_path;
- loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
- loader.res_path = loader.local_path;
- loader.open(f);
- return loader.save_as_binary(p_dst_path);
-}
-
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
-/*****************************************************************************************************/
/*****************************************************************************************************/
String ResourceFormatSaverTextInstance::_write_resources(void *ud, const Ref<Resource> &p_resource) {
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index 41363fd975..b5542f77ba 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -87,11 +87,6 @@ class ResourceLoaderText {
Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str);
Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str);
- // for converter
- class DummyResource : public Resource {
- public:
- };
-
struct DummyReadData {
bool no_placeholders = false;
HashMap<Ref<Resource>, int> external_resources;
@@ -133,7 +128,6 @@ public:
Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map);
Error get_classes_used(HashSet<StringName> *r_classes);
- Error save_as_binary(const String &p_path);
ResourceLoaderText();
};
@@ -152,8 +146,6 @@ public:
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override;
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override;
- static Error convert_file_to_binary(const String &p_src_path, const String &p_dst_path);
-
ResourceFormatLoaderText() { singleton = this; }
};
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 0087a5e7f2..dfe5bd4a47 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -31,7 +31,6 @@
#include "shader.h"
#include "core/io/file_access.h"
-#include "scene/scene_string_names.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/shader_preprocessor.h"
#include "servers/rendering_server.h"
@@ -156,7 +155,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
DocData::PropertyDoc prop_doc;
prop_doc.name = "shader_parameter/" + pi.name;
#ifdef MODULE_REGEX_ENABLED
- const RegEx pattern("/\\*\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/\\s*uniform\\s+\\w+\\s+" + pi.name + "(?=[\\s:;=])");
+ const RegEx pattern("/\\*\\*\\s([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/\\s*uniform\\s+\\w+\\s+" + pi.name + "(?=[\\s:;=])");
Ref<RegExMatch> pattern_ref = pattern.search(code);
if (pattern_ref != nullptr) {
RegExMatch *match = pattern_ref.ptr();
@@ -174,7 +173,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
}
}
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint() && !class_doc.name.is_empty() && p_params) {
+ if (EditorHelp::get_doc_data() != nullptr && Engine::get_singleton()->is_editor_hint() && !class_doc.name.is_empty() && p_params) {
EditorHelp::get_doc_data()->add_doc(class_doc);
}
#endif
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
index 42ffa2d25a..6e43ea9b17 100644
--- a/scene/resources/sprite_frames.cpp
+++ b/scene/resources/sprite_frames.cpp
@@ -277,5 +277,5 @@ void SpriteFrames::_bind_methods() {
}
SpriteFrames::SpriteFrames() {
- add_animation(SceneStringNames::get_singleton()->_default);
+ add_animation(SceneStringName(default_));
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index a57af6886d..601e8c52a4 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1101,6 +1101,42 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
return result;
}
+bool VisualShader::_check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes) const {
+ const Graph *g = &graph[p_type];
+
+ // BFS to check whether connecting to the given subgraph (rooted at p_reroute_node) is valid.
+ List<int> queue;
+ queue.push_back(p_reroute_node);
+ if (r_visited_reroute_nodes != nullptr) {
+ r_visited_reroute_nodes->push_back(p_reroute_node);
+ }
+ while (!queue.is_empty()) {
+ int current_node_id = queue.front()->get();
+ VisualShader::Node current_node = g->nodes[current_node_id];
+ queue.pop_front();
+ for (const int &next_node_id : current_node.next_connected_nodes) {
+ Ref<VisualShaderNodeReroute> next_vsnode = g->nodes[next_node_id].node;
+ if (next_vsnode.is_valid()) {
+ queue.push_back(next_node_id);
+ if (r_visited_reroute_nodes != nullptr) {
+ r_visited_reroute_nodes->push_back(next_node_id);
+ }
+ continue;
+ }
+ // Check whether all ports connected with the reroute node are compatible.
+ for (const Connection &c : g->connections) {
+ VisualShaderNode::PortType to_port_type = g->nodes[next_node_id].node->get_input_port_type(c.to_port);
+ if (c.from_node == current_node_id &&
+ c.to_node == next_node_id &&
+ !is_port_types_compatible(p_target_port_type, to_port_type)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
const Graph *g = &graph[p_type];
@@ -1128,7 +1164,12 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
- if (!is_port_types_compatible(from_port_type, to_port_type)) {
+ Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node;
+ if (to_node_reroute.is_valid()) {
+ if (!_check_reroute_subgraph(p_type, from_port_type, p_to_node)) {
+ return false;
+ }
+ } else if (!is_port_types_compatible(from_port_type, to_port_type)) {
return false;
}
@@ -1141,7 +1182,6 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) {
return false;
}
-
return true;
}
@@ -1179,6 +1219,28 @@ void VisualShader::detach_node_from_frame(Type p_type, int p_node) {
g->nodes[p_node].node->set_frame(-1);
}
+String VisualShader::get_reroute_parameter_name(Type p_type, int p_reroute_node) const {
+ ERR_FAIL_INDEX_V(p_type, TYPE_MAX, "");
+ const Graph *g = &graph[p_type];
+
+ ERR_FAIL_COND_V(!g->nodes.has(p_reroute_node), "");
+
+ const VisualShader::Node *node = &g->nodes[p_reroute_node];
+ while (node->prev_connected_nodes.size() > 0) {
+ int connected_node_id = node->prev_connected_nodes[0];
+ node = &g->nodes[connected_node_id];
+ Ref<VisualShaderNodeParameter> parameter_node = node->node;
+ if (parameter_node.is_valid() && parameter_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) {
+ return parameter_node->get_parameter_name();
+ }
+ Ref<VisualShaderNodeInput> input_node = node->node;
+ if (input_node.is_valid() && input_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) {
+ return input_node->get_input_real_name();
+ }
+ }
+ return "";
+}
+
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
ERR_FAIL_INDEX(p_type, TYPE_MAX);
Graph *g = &graph[p_type];
@@ -1217,10 +1279,30 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER);
+ Ref<VisualShaderNodeReroute> from_node_reroute = g->nodes[p_from_node].node;
+ Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node;
+
+ // Allow connection with incompatible port types only if the reroute node isn't connected to anything.
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
+ bool port_types_are_compatible = is_port_types_compatible(from_port_type, to_port_type);
+
+ if (to_node_reroute.is_valid()) {
+ List<int> visited_reroute_nodes;
+ port_types_are_compatible = _check_reroute_subgraph(p_type, from_port_type, p_to_node, &visited_reroute_nodes);
+ if (port_types_are_compatible) {
+ // Set the port type of all reroute nodes.
+ for (const int &E : visited_reroute_nodes) {
+ Ref<VisualShaderNodeReroute> reroute_node = g->nodes[E].node;
+ reroute_node->_set_port_type(from_port_type);
+ }
+ }
+ } else if (from_node_reroute.is_valid() && !from_node_reroute->is_input_port_connected(0)) {
+ from_node_reroute->_set_port_type(to_port_type);
+ port_types_are_compatible = true;
+ }
- ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform.");
+ ERR_FAIL_COND_V_MSG(!port_types_are_compatible, ERR_INVALID_PARAMETER, "Incompatible port types.");
for (const Connection &E : g->connections) {
if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) {
@@ -1904,12 +1986,18 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB
if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr());
+ // FIXME: This needs to be refactored at some point.
if (ptr->has_method("get_input_real_name")) {
inputs[i] = ptr->call("get_input_real_name");
} else if (ptr->has_method("get_parameter_name")) {
inputs[i] = ptr->call("get_parameter_name");
} else {
- inputs[i] = "";
+ Ref<VisualShaderNodeReroute> reroute = graph[type].nodes[from_node].node;
+ if (reroute.is_valid()) {
+ inputs[i] = get_reroute_parameter_name(type, from_node);
+ } else {
+ inputs[i] = "";
+ }
}
} else if (in_type == out_type) {
inputs[i] = src_var;
@@ -2798,7 +2886,7 @@ void VisualShader::_update_shader() const {
}
}
if (previous_code != final_code) {
- const_cast<VisualShader *>(this)->emit_signal(SNAME("changed"));
+ const_cast<VisualShader *>(this)->emit_signal(CoreStringName(changed));
}
previous_code = final_code;
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index d32e2465b9..18cdc8342b 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -163,6 +163,8 @@ private:
void _input_type_changed(Type p_type, int p_id);
bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
+ bool _check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes = nullptr) const;
+
protected:
virtual void _update_shader() const override;
static void _bind_methods();
@@ -229,6 +231,8 @@ public: // internal methods
void attach_node_to_frame(Type p_type, int p_node, int p_frame);
void detach_node_from_frame(Type p_type, int p_node);
+ String get_reroute_parameter_name(Type p_type, int p_reroute_node) const;
+
void rebuild();
void get_node_connections(Type p_type, List<Connection> *r_connections) const;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index ccd730eef2..d5394c8af5 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -8150,3 +8150,82 @@ VisualShaderNodeRotationByAxis::VisualShaderNodeRotationByAxis() {
simple_decl = false;
}
+
+String VisualShaderNodeReroute::get_caption() const {
+ return "Reroute";
+}
+
+int VisualShaderNodeReroute::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_input_port_type(int p_port) const {
+ return input_port_type;
+}
+
+String VisualShaderNodeReroute::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeReroute::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_output_port_type(int p_port) const {
+ return input_port_type;
+}
+
+String VisualShaderNodeReroute::get_output_port_name(int p_port) const {
+ return String();
+}
+
+String VisualShaderNodeReroute::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+ for (int i = 0; i < get_output_port_count(); i++) {
+ if (input_port_type == PORT_TYPE_SAMPLER) {
+ continue;
+ }
+
+ String input = p_input_vars[0];
+ if (input.is_empty()) {
+ code += vformat(" %s;\n", p_output_vars[i]);
+ continue;
+ }
+ code += vformat(" %s = %s;\n", p_output_vars[i], input);
+ }
+ return code;
+}
+
+void VisualShaderNodeReroute::_set_port_type(PortType p_type) {
+ input_port_type = p_type;
+ switch (p_type) {
+ case PORT_TYPE_SCALAR:
+ set_input_port_default_value(0, 0.0);
+ break;
+ case PORT_TYPE_VECTOR_2D:
+ set_input_port_default_value(0, Vector2());
+ break;
+ case PORT_TYPE_VECTOR_3D:
+ set_input_port_default_value(0, Vector3());
+ break;
+ case PORT_TYPE_VECTOR_4D:
+ set_input_port_default_value(0, Vector4());
+ break;
+ case PORT_TYPE_TRANSFORM:
+ set_input_port_default_value(0, Transform3D());
+ break;
+ default:
+ break;
+ }
+}
+
+void VisualShaderNodeReroute::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_set_port_type", "port_type"), &VisualShaderNodeReroute::_set_port_type);
+ ClassDB::bind_method(D_METHOD("get_port_type"), &VisualShaderNodeReroute::get_port_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "port_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_port_type", "get_port_type");
+}
+
+VisualShaderNodeReroute::VisualShaderNodeReroute() {
+ set_input_port_default_value(0, 0.0);
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 0bd0c631b8..a23ae72def 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -3092,4 +3092,35 @@ public:
VisualShaderNodeRotationByAxis();
};
+class VisualShaderNodeReroute : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeReroute, VisualShaderNode);
+
+ PortType input_port_type = PORT_TYPE_SCALAR;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+ virtual bool has_output_port_preview(int p_port) const override { return false; }
+ virtual bool is_output_port_expandable(int p_port) const override { return false; }
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ virtual Category get_category() const override { return CATEGORY_SPECIAL; }
+
+ void _set_port_type(PortType p_type);
+ PortType get_port_type() const { return input_port_type; }
+
+ VisualShaderNodeReroute();
+};
+
#endif // VISUAL_SHADER_NODES_H
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index 5610b2f642..2ee27c95e1 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -33,20 +33,12 @@
SceneStringNames *SceneStringNames::singleton = nullptr;
SceneStringNames::SceneStringNames() {
- _estimate_cost = StaticCString::create("_estimate_cost");
- _compute_cost = StaticCString::create("_compute_cost");
-
resized = StaticCString::create("resized");
- dot = StaticCString::create(".");
- doubledot = StaticCString::create("..");
draw = StaticCString::create("draw");
- _draw = StaticCString::create("_draw");
hidden = StaticCString::create("hidden");
visibility_changed = StaticCString::create("visibility_changed");
input_event = StaticCString::create("input_event");
shader = StaticCString::create("shader");
- shader_unshaded = StaticCString::create("shader/unshaded");
- shading_mode = StaticCString::create("shader/shading_mode");
tree_entered = StaticCString::create("tree_entered");
tree_exiting = StaticCString::create("tree_exiting");
tree_exited = StaticCString::create("tree_exited");
@@ -86,103 +78,33 @@ SceneStringNames::SceneStringNames() {
area_shape_entered = StaticCString::create("area_shape_entered");
area_shape_exited = StaticCString::create("area_shape_exited");
- _body_inout = StaticCString::create("_body_inout");
- _area_inout = StaticCString::create("_area_inout");
-
- idle = StaticCString::create("idle");
- iteration = StaticCString::create("iteration");
update = StaticCString::create("update");
updated = StaticCString::create("updated");
- _physics_process = StaticCString::create("_physics_process");
- _process = StaticCString::create("_process");
-
- _enter_tree = StaticCString::create("_enter_tree");
- _exit_tree = StaticCString::create("_exit_tree");
- _enter_world = StaticCString::create("_enter_world");
- _exit_world = StaticCString::create("_exit_world");
_ready = StaticCString::create("_ready");
- _update_scroll = StaticCString::create("_update_scroll");
- _update_xform = StaticCString::create("_update_xform");
-
- _structured_text_parser = StaticCString::create("_structured_text_parser");
-
- _proxgroup_add = StaticCString::create("_proxgroup_add");
- _proxgroup_remove = StaticCString::create("_proxgroup_remove");
-
- grouped = StaticCString::create("grouped");
- ungrouped = StaticCString::create("ungrouped");
-
screen_entered = StaticCString::create("screen_entered");
screen_exited = StaticCString::create("screen_exited");
- viewport_entered = StaticCString::create("viewport_entered");
- viewport_exited = StaticCString::create("viewport_exited");
-
- camera_entered = StaticCString::create("camera_entered");
- camera_exited = StaticCString::create("camera_exited");
-
- _input = StaticCString::create("_input");
- _input_event = StaticCString::create("_input_event");
-
gui_input = StaticCString::create("gui_input");
- _gui_input = StaticCString::create("_gui_input");
-
- _unhandled_input = StaticCString::create("_unhandled_input");
- _unhandled_key_input = StaticCString::create("_unhandled_key_input");
-
- changed = StaticCString::create("changed");
- _shader_changed = StaticCString::create("_shader_changed");
_spatial_editor_group = StaticCString::create("_spatial_editor_group");
_request_gizmo = StaticCString::create("_request_gizmo");
- _set_subgizmo_selection = StaticCString::create("_set_subgizmo_selection");
- _clear_subgizmo_selection = StaticCString::create("_clear_subgizmo_selection");
offset = StaticCString::create("offset");
- unit_offset = StaticCString::create("unit_offset");
rotation_mode = StaticCString::create("rotation_mode");
rotate = StaticCString::create("rotate");
h_offset = StaticCString::create("h_offset");
v_offset = StaticCString::create("v_offset");
- transform_pos = StaticCString::create("position");
- transform_rot = StaticCString::create("rotation");
- transform_scale = StaticCString::create("scale");
-
- _update_remote = StaticCString::create("_update_remote");
- _update_pairs = StaticCString::create("_update_pairs");
-
- _get_minimum_size = StaticCString::create("_get_minimum_size");
-
area_entered = StaticCString::create("area_entered");
area_exited = StaticCString::create("area_exited");
- _has_point = StaticCString::create("_has_point");
-
line_separation = StaticCString::create("line_separation");
- _get_drag_data = StaticCString::create("_get_drag_data");
- _drop_data = StaticCString::create("_drop_data");
- _can_drop_data = StaticCString::create("_can_drop_data");
-
- baked_light_changed = StaticCString::create("baked_light_changed");
- _baked_light_changed = StaticCString::create("_baked_light_changed");
-
- _mouse_enter = StaticCString::create("_mouse_enter");
- _mouse_exit = StaticCString::create("_mouse_exit");
- _mouse_shape_enter = StaticCString::create("_mouse_shape_enter");
- _mouse_shape_exit = StaticCString::create("_mouse_shape_exit");
-
- _pressed = StaticCString::create("_pressed");
- _toggled = StaticCString::create("_toggled");
-
frame_changed = StaticCString::create("frame_changed");
texture_changed = StaticCString::create("texture_changed");
- playback_speed = StaticCString::create("playback/speed");
- playback_active = StaticCString::create("playback/active");
autoplay = StaticCString::create("autoplay");
blend_times = StaticCString::create("blend_times");
speed = StaticCString::create("speed");
@@ -196,13 +118,9 @@ SceneStringNames::SceneStringNames() {
// Audio bus name.
Master = StaticCString::create("Master");
- _default = StaticCString::create("default");
+ default_ = StaticCString::create("default");
- _window_group = StaticCString::create("_window_group");
- _window_input = StaticCString::create("_window_input");
window_input = StaticCString::create("window_input");
- _window_unhandled_input = StaticCString::create("_window_unhandled_input");
- _get_contents_minimum_size = StaticCString::create("_get_contents_minimum_size");
theme_changed = StaticCString::create("theme_changed");
parameters_base_path = "parameters/";
@@ -210,8 +128,5 @@ SceneStringNames::SceneStringNames() {
shader_overrides_group = StaticCString::create("_shader_overrides_group_");
shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_");
-#ifndef DISABLE_DEPRECATED
- use_in_baked_light = StaticCString::create("use_in_baked_light");
- use_dynamic_gi = StaticCString::create("use_dynamic_gi");
-#endif
+ pressed = StaticCString::create("pressed");
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index 60254e3006..7ed86cde46 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -51,23 +51,14 @@ class SceneStringNames {
public:
_FORCE_INLINE_ static SceneStringNames *get_singleton() { return singleton; }
- StringName _estimate_cost;
- StringName _compute_cost;
-
StringName resized;
- StringName dot;
- StringName doubledot;
StringName draw;
StringName hidden;
StringName visibility_changed;
StringName input_event;
- StringName _input_event;
StringName gui_input;
- StringName _gui_input;
StringName item_rect_changed;
StringName shader;
- StringName shader_unshaded;
- StringName shading_mode;
StringName tree_entered;
StringName tree_exiting;
StringName tree_exited;
@@ -75,8 +66,6 @@ public:
StringName size_flags_changed;
StringName minimum_size_changed;
StringName sleeping_state_changed;
- StringName idle;
- StringName iteration;
StringName update;
StringName updated;
@@ -111,94 +100,33 @@ public:
StringName area_shape_entered;
StringName area_shape_exited;
- StringName _body_inout;
- StringName _area_inout;
-
- StringName _physics_process;
- StringName _process;
- StringName _enter_world;
- StringName _exit_world;
- StringName _enter_tree;
- StringName _exit_tree;
- StringName _draw;
- StringName _input;
StringName _ready;
- StringName _unhandled_input;
- StringName _unhandled_key_input;
-
- StringName _pressed;
- StringName _toggled;
-
- StringName _update_scroll;
- StringName _update_xform;
-
- StringName _structured_text_parser;
-
- StringName _proxgroup_add;
- StringName _proxgroup_remove;
-
- StringName grouped;
- StringName ungrouped;
-
- StringName _has_point;
- StringName _get_drag_data;
- StringName _can_drop_data;
- StringName _drop_data;
StringName screen_entered;
StringName screen_exited;
- StringName viewport_entered;
- StringName viewport_exited;
- StringName camera_entered;
- StringName camera_exited;
-
- StringName changed;
- StringName _shader_changed;
StringName _spatial_editor_group;
StringName _request_gizmo;
- StringName _set_subgizmo_selection;
- StringName _clear_subgizmo_selection;
StringName offset;
- StringName unit_offset;
StringName rotation_mode;
StringName rotate;
StringName v_offset;
StringName h_offset;
- StringName transform_pos;
- StringName transform_rot;
- StringName transform_scale;
-
- StringName _update_remote;
- StringName _update_pairs;
-
StringName area_entered;
StringName area_exited;
- StringName _get_minimum_size;
-
- StringName baked_light_changed;
- StringName _baked_light_changed;
-
- StringName _mouse_enter;
- StringName _mouse_exit;
- StringName _mouse_shape_enter;
- StringName _mouse_shape_exit;
-
StringName frame_changed;
StringName texture_changed;
- StringName playback_speed;
- StringName playback_active;
StringName autoplay;
StringName blend_times;
StringName speed;
NodePath path_pp;
- StringName _default;
+ StringName default_; // "default", conflict with C++ keyword.
StringName node_configuration_warning_changed;
@@ -207,21 +135,15 @@ public:
StringName Master;
StringName parameters_base_path;
-
- StringName _window_group;
- StringName _window_input;
- StringName _window_unhandled_input;
StringName window_input;
- StringName _get_contents_minimum_size;
StringName theme_changed;
StringName shader_overrides_group;
StringName shader_overrides_group_active;
-#ifndef DISABLE_DEPRECATED
- StringName use_in_baked_light;
- StringName use_dynamic_gi;
-#endif
+ StringName pressed;
};
+#define SceneStringName(m_name) SceneStringNames::get_singleton()->m_name
+
#endif // SCENE_STRING_NAMES_H
diff --git a/scene/theme/SCsub b/scene/theme/SCsub
index 5f62ae4b05..2372d1820a 100644
--- a/scene/theme/SCsub
+++ b/scene/theme/SCsub
@@ -4,7 +4,6 @@ Import("env")
import default_theme_builders
-
env.add_source_files(env.scene_sources, "*.cpp")
SConscript("icons/SCsub")
diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp
index d1d8854b18..aa4d669238 100644
--- a/scene/theme/default_theme.cpp
+++ b/scene/theme/default_theme.cpp
@@ -39,6 +39,7 @@
#include "scene/resources/style_box_flat.h"
#include "scene/resources/style_box_line.h"
#include "scene/resources/theme.h"
+#include "scene/scene_string_names.h"
#include "scene/theme/theme_db.h"
#include "servers/text_server.h"
@@ -160,7 +161,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("normal", "Button", button_normal);
theme->set_stylebox("hover", "Button", button_hover);
- theme->set_stylebox("pressed", "Button", button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "Button", button_pressed);
theme->set_stylebox("disabled", "Button", button_disabled);
theme->set_stylebox("focus", "Button", focus);
@@ -189,7 +190,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// MenuBar
theme->set_stylebox("normal", "MenuBar", button_normal);
theme->set_stylebox("hover", "MenuBar", button_hover);
- theme->set_stylebox("pressed", "MenuBar", button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "MenuBar", button_pressed);
theme->set_stylebox("disabled", "MenuBar", button_disabled);
theme->set_font("font", "MenuBar", Ref<Font>());
@@ -232,7 +233,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("normal", "OptionButton", sb_optbutton_normal);
theme->set_stylebox("hover", "OptionButton", sb_optbutton_hover);
- theme->set_stylebox("pressed", "OptionButton", sb_optbutton_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "OptionButton", sb_optbutton_pressed);
theme->set_stylebox("disabled", "OptionButton", sb_optbutton_disabled);
Ref<StyleBox> sb_optbutton_normal_mirrored = make_flat_stylebox(style_normal_color, 2 * default_margin, default_margin, 2 * default_margin, default_margin);
@@ -266,7 +267,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// MenuButton
theme->set_stylebox("normal", "MenuButton", button_normal);
- theme->set_stylebox("pressed", "MenuButton", button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "MenuButton", button_pressed);
theme->set_stylebox("hover", "MenuButton", button_hover);
theme->set_stylebox("disabled", "MenuButton", button_disabled);
theme->set_stylebox("focus", "MenuButton", focus);
@@ -292,7 +293,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
cbx_focus->set_content_margin_all(Math::round(4 * scale));
theme->set_stylebox("normal", "CheckBox", cbx_empty);
- theme->set_stylebox("pressed", "CheckBox", cbx_empty);
+ theme->set_stylebox(SceneStringName(pressed), "CheckBox", cbx_empty);
theme->set_stylebox("disabled", "CheckBox", cbx_empty);
theme->set_stylebox("hover", "CheckBox", cbx_empty);
theme->set_stylebox("hover_pressed", "CheckBox", cbx_empty);
@@ -328,7 +329,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
cb_empty->set_content_margin_individual(Math::round(6 * scale), Math::round(4 * scale), Math::round(6 * scale), Math::round(4 * scale));
theme->set_stylebox("normal", "CheckButton", cb_empty);
- theme->set_stylebox("pressed", "CheckButton", cb_empty);
+ theme->set_stylebox(SceneStringName(pressed), "CheckButton", cb_empty);
theme->set_stylebox("disabled", "CheckButton", cb_empty);
theme->set_stylebox("hover", "CheckButton", cb_empty);
theme->set_stylebox("hover_pressed", "CheckButton", cb_empty);
@@ -373,12 +374,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("normal", "FlatButton", flat_button_normal);
theme->set_stylebox("hover", "FlatButton", flat_button_normal);
- theme->set_stylebox("pressed", "FlatButton", flat_button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "FlatButton", flat_button_pressed);
theme->set_stylebox("disabled", "FlatButton", flat_button_normal);
theme->set_stylebox("normal", "FlatMenuButton", flat_button_normal);
theme->set_stylebox("hover", "FlatMenuButton", flat_button_normal);
- theme->set_stylebox("pressed", "FlatMenuButton", flat_button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "FlatMenuButton", flat_button_pressed);
theme->set_stylebox("disabled", "FlatMenuButton", flat_button_normal);
// Label
@@ -864,7 +865,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("h_separation", "ItemList", Math::round(4 * scale));
theme->set_constant("v_separation", "ItemList", Math::round(4 * scale));
theme->set_constant("icon_margin", "ItemList", Math::round(4 * scale));
- theme->set_constant("line_separation", "ItemList", Math::round(2 * scale));
+ theme->set_constant(SceneStringName(line_separation), "ItemList", Math::round(2 * scale));
theme->set_font("font", "ItemList", Ref<Font>());
theme->set_font_size("font_size", "ItemList", -1);
@@ -1050,7 +1051,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("bg", "ColorPickerButton", icons["mini_checkerboard"]);
theme->set_stylebox("normal", "ColorPickerButton", button_normal);
- theme->set_stylebox("pressed", "ColorPickerButton", button_pressed);
+ theme->set_stylebox(SceneStringName(pressed), "ColorPickerButton", button_pressed);
theme->set_stylebox("hover", "ColorPickerButton", button_hover);
theme->set_stylebox("disabled", "ColorPickerButton", button_disabled);
theme->set_stylebox("focus", "ColorPickerButton", focus);
@@ -1125,7 +1126,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("shadow_offset_y", "RichTextLabel", Math::round(1 * scale));
theme->set_constant("shadow_outline_size", "RichTextLabel", Math::round(1 * scale));
- theme->set_constant("line_separation", "RichTextLabel", 0);
+ theme->set_constant(SceneStringName(line_separation), "RichTextLabel", 0);
theme->set_constant("table_h_separation", "RichTextLabel", Math::round(3 * scale));
theme->set_constant("table_v_separation", "RichTextLabel", Math::round(3 * scale));
diff --git a/scene/theme/icons/SCsub b/scene/theme/icons/SCsub
index 46133ccceb..1f3b7f6d17 100644
--- a/scene/theme/icons/SCsub
+++ b/scene/theme/icons/SCsub
@@ -4,7 +4,6 @@ Import("env")
import default_theme_icons_builders
-
env["BUILDERS"]["MakeDefaultThemeIconsBuilder"] = Builder(
action=env.Run(default_theme_icons_builders.make_default_theme_icons_action),
suffix=".h",
diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp
index 4c82e5ba5f..7249fd7ba8 100644
--- a/scene/theme/theme_db.cpp
+++ b/scene/theme/theme_db.cpp
@@ -225,7 +225,7 @@ ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_th
theme_contexts[p_node] = context;
_propagate_theme_context(p_node, context);
- p_node->connect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context).bind(p_node));
+ p_node->connect(SceneStringName(tree_exited), callable_mp(this, &ThemeDB::destroy_theme_context).bind(p_node));
return context;
}
@@ -233,7 +233,7 @@ ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_th
void ThemeDB::destroy_theme_context(Node *p_node) {
ERR_FAIL_COND(!theme_contexts.has(p_node));
- p_node->disconnect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context));
+ p_node->disconnect(SceneStringName(tree_exited), callable_mp(this, &ThemeDB::destroy_theme_context));
ThemeContext *context = theme_contexts[p_node];
@@ -472,7 +472,7 @@ ThemeDB::~ThemeDB() {
}
void ThemeContext::_emit_changed() {
- emit_signal(SNAME("changed"));
+ emit_signal(CoreStringName(changed));
}
void ThemeContext::set_themes(List<Ref<Theme>> &p_themes) {
diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp
index 8cdffe8c73..a25adddc09 100644
--- a/scene/theme/theme_owner.cpp
+++ b/scene/theme/theme_owner.cpp
@@ -69,18 +69,18 @@ bool ThemeOwner::has_owner_node() const {
void ThemeOwner::set_owner_context(ThemeContext *p_context, bool p_propagate) {
ThemeContext *default_context = ThemeDB::get_singleton()->get_default_theme_context();
- if (owner_context && owner_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) {
- owner_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
- } else if (default_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) {
- default_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ if (owner_context && owner_context->is_connected(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed))) {
+ owner_context->disconnect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed));
+ } else if (default_context->is_connected(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed))) {
+ default_context->disconnect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed));
}
owner_context = p_context;
if (owner_context) {
- owner_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ owner_context->connect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed));
} else {
- default_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed));
+ default_context->connect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed));
}
if (p_propagate) {