diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 917ced5feb..c12a9d6579 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -667,11 +667,15 @@ StringName AnimatedSprite::get_animation() const { String AnimatedSprite::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (frames.is_null()) { - return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames."); } - return String(); + return warning; } void AnimatedSprite::_bind_methods() { diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 25db434918..b8793ed1a5 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -81,17 +81,21 @@ Color CanvasModulate::get_color() const { String CanvasModulate::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!is_visible_in_tree() || !is_inside_tree()) - return String(); + return warning; List nodes; get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes); if (nodes.size() > 1) { - return TTR("Only one visible CanvasModulate is allowed per scene (or set of instanced scenes). The first created one will work, while the rest will be ignored."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Only one visible CanvasModulate is allowed per scene (or set of instanced scenes). The first created one will work, while the rest will be ignored."); } - return String(); + return warning; } CanvasModulate::CanvasModulate() { diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index ee92423908..4e9f1a8d65 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -247,15 +247,22 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl String CollisionPolygon2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); } if (polygon.empty()) { - return TTR("An empty CollisionPolygon2D has no effect on collision."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("An empty CollisionPolygon2D has no effect on collision."); } - return String(); + return warning; } void CollisionPolygon2D::set_disabled(bool p_disabled) { diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index bf3b360dab..afa368fe9b 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -180,18 +180,29 @@ bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double String CollisionShape2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); } if (!shape.is_valid()) { - return TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!"); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!"); } + Ref convex = shape; Ref concave = shape; if (convex.is_valid() || concave.is_valid()) { - return TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead."); } - return String(); + return warning; } void CollisionShape2D::set_disabled(bool p_disabled) { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 32e84cd626..b633bec14a 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -267,7 +267,7 @@ bool CPUParticles2D::get_fractional_delta() const { String CPUParticles2D::get_configuration_warning() const { - String warnings; + String warnings = Node2D::get_configuration_warning(); CanvasItemMaterial *mat = Object::cast_to(get_material().ptr()); @@ -275,7 +275,7 @@ String CPUParticles2D::get_configuration_warning() const { if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) { if (warnings != String()) - warnings += "\n"; + warnings += "\n\n"; warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); } } diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 1bffaf8084..0c286db81d 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -352,11 +352,15 @@ void Light2D::_notification(int p_what) { String Light2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!texture.is_valid()) { - return TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); } - return String(); + return warning; } void Light2D::set_shadow_smooth(float p_amount) { diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 0e8e8f6679..099086e4cd 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -268,15 +268,22 @@ int LightOccluder2D::get_occluder_light_mask() const { String LightOccluder2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!occluder_polygon.is_valid()) { - return TTR("An occluder polygon must be set (or drawn) for this occluder to take effect."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("An occluder polygon must be set (or drawn) for this occluder to take effect."); } if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) { - return TTR("The occluder polygon for this occluder is empty. Please draw a polygon."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("The occluder polygon for this occluder is empty. Please draw a polygon."); } - return String(); + return warning; } void LightOccluder2D::_bind_methods() { diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index ea79f89dd9..b1c8dac77c 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -504,20 +504,29 @@ String NavigationPolygonInstance::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); + String warning = Node2D::get_configuration_warning(); if (!navpoly.is_valid()) { - return TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); } const Node2D *c = this; while (c) { if (Object::cast_to(c)) { - return String(); + return warning; } c = Object::cast_to(c->get_parent()); } - return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + + return warning; } void NavigationPolygonInstance::_bind_methods() { diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 5aea1025ef..27b4cffa47 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -143,12 +143,15 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_sc } String ParallaxLayer::get_configuration_warning() const { - + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); } - return String(); + return warning; } void ParallaxLayer::_bind_methods() { diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 746feeaa82..9613e8830c 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -227,17 +227,19 @@ bool Particles2D::get_fractional_delta() const { } String Particles2D::get_configuration_warning() const { - + String warning = Node2D::get_configuration_warning(); if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { - return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); + return warning; } - String warnings; - if (process_material.is_null()) { - if (warnings != String()) - warnings += "\n"; - warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); + if (warning != String()) + warning += "\n\n"; + warning += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); } else { CanvasItemMaterial *mat = Object::cast_to(get_material().ptr()); @@ -247,14 +249,14 @@ String Particles2D::get_configuration_warning() const { if (process && (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { - if (warnings != String()) - warnings += "\n"; - warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); + if (warning != String()) + warning += "\n\n"; + warning += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); } } } - return warnings; + return warning; } Rect2 Particles2D::capture_rect() const { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index e777ea2e7d..727adfcaaf 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -275,11 +275,15 @@ String PathFollow2D::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); + String warning = Node2D::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("PathFollow2D only works when set as a child of a Path2D node."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("PathFollow2D only works when set as a child of a Path2D node."); } - return String(); + return warning; } void PathFollow2D::_bind_methods() { diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 53072f942d..3c90f1e1ba 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -186,11 +186,15 @@ void RemoteTransform2D::force_update_cache() { String RemoteTransform2D::get_configuration_warning() const { + String warning = Node2D::get_configuration_warning(); if (!has_node(remote_node) || !Object::cast_to(get_node(remote_node))) { - return TTR("Path property must point to a valid Node2D node to work."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Path property must point to a valid Node2D node to work."); } - return String(); + return warning; } void RemoteTransform2D::_bind_methods() { diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 49c08e895a..afecb05f3a 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -330,12 +330,16 @@ void VisibilityEnabler2D::_node_removed(Node *p_node) { } String VisibilityEnabler2D::get_configuration_warning() const { + String warning = VisibilityNotifier2D::get_configuration_warning(); #ifdef TOOLS_ENABLED if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) { - return TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent."); } #endif - return String(); + return warning; } void VisibilityEnabler2D::_bind_methods() { diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 8d1556ef1c..b5e693547a 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -58,13 +58,17 @@ String ARVRCamera::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); + String warning = Camera::get_configuration_warning(); // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to(get_parent()); if (origin == NULL) { - return TTR("ARVRCamera must have an ARVROrigin node as its parent."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ARVRCamera must have an ARVROrigin node as its parent."); }; - return String(); + return warning; }; Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { @@ -367,17 +371,24 @@ String ARVRController::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); + String warning = Spatial::get_configuration_warning(); // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to(get_parent()); if (origin == NULL) { - return TTR("ARVRController must have an ARVROrigin node as its parent."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ARVRController must have an ARVROrigin node as its parent."); }; if (controller_id == 0) { - return TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller."); }; - return String(); + return warning; }; ARVRController::ARVRController() { @@ -494,17 +505,24 @@ String ARVRAnchor::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); + String warning = Spatial::get_configuration_warning(); // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to(get_parent()); if (origin == NULL) { - return TTR("ARVRAnchor must have an ARVROrigin node as its parent."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ARVRAnchor must have an ARVROrigin node as its parent."); }; if (anchor_id == 0) { - return TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor."); }; - return String(); + return warning; }; Plane ARVRAnchor::get_plane() const { @@ -535,10 +553,15 @@ String ARVROrigin::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - if (tracked_camera == NULL) - return TTR("ARVROrigin requires an ARVRCamera child node."); + String warning = Spatial::get_configuration_warning(); + if (tracked_camera == NULL) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ARVROrigin requires an ARVRCamera child node."); + } - return String(); + return warning; }; void ARVROrigin::_bind_methods() { diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index cc07072962..2adefe9451 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -164,15 +164,22 @@ bool CollisionPolygon::is_disabled() const { String CollisionPolygon::get_configuration_warning() const { + String warning = Spatial::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("CollisionPolygon only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("CollisionPolygon only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape."); } if (polygon.empty()) { - return TTR("An empty CollisionPolygon has no effect on collision."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("An empty CollisionPolygon has no effect on collision."); } - return String(); + return warning; } bool CollisionPolygon::_is_editable_3d_polygon() const { diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index caa0c5047a..4735910fc3 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -115,27 +115,40 @@ void CollisionShape::resource_changed(RES res) { String CollisionShape::get_configuration_warning() const { + String warning = Spatial::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("CollisionShape only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("CollisionShape only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape."); } if (!shape.is_valid()) { - return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it."); } if (shape->is_class("PlaneShape")) { - return TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); } if (Object::cast_to(get_parent())) { if (Object::cast_to(*shape)) { if (Object::cast_to(get_parent())->get_mode() != RigidBody::MODE_STATIC) { - return TTR("ConcavePolygonShape doesn't support RigidBody in another mode than static."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ConcavePolygonShape doesn't support RigidBody in another mode than static."); } } } - return String(); + return warning; } void CollisionShape::_bind_methods() { diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 8943699c51..eb3fc9ee57 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -201,7 +201,7 @@ bool CPUParticles::get_fractional_delta() const { String CPUParticles::get_configuration_warning() const { - String warnings; + String warnings = GeometryInstance::get_configuration_warning(); bool mesh_found = false; bool anim_material_found = false; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 99bc78f5d2..d020d19803 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -490,11 +490,14 @@ PoolVector GIProbe::get_faces(uint32_t p_usage_flags) const { } String GIProbe::get_configuration_warning() const { - + String warning = VisualInstance::get_configuration_warning(); if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { - return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead."); } - return String(); + return warning; } void GIProbe::_bind_methods() { diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index aaba91125e..43de1b0a73 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -697,19 +697,28 @@ String NavigationMeshInstance::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); + String warning = Spatial::get_configuration_warning(); if (!navmesh.is_valid()) { - return TTR("A NavigationMesh resource must be set or created for this node to work."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A NavigationMesh resource must be set or created for this node to work."); + return warning; } const Spatial *c = this; while (c) { if (Object::cast_to(c)) - return String(); + return warning; c = Object::cast_to(c->get_parent()); } - return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); + return warning; } void NavigationMeshInstance::_bind_methods() { diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index add563d991..9eeb815872 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -244,7 +244,7 @@ String Particles::get_configuration_warning() const { return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles node instead. You can use the \"Convert to CPUParticles\" option for this purpose."); } - String warnings; + String warnings = GeometryInstance::get_configuration_warning(); bool meshes_found = false; bool anim_material_found = false; @@ -267,7 +267,7 @@ String Particles::get_configuration_warning() const { if (!meshes_found) { if (warnings != String()) - warnings += "\n"; + warnings += "\n\n"; warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes."); } diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 019a245fa2..149630002f 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -264,16 +264,23 @@ String PathFollow::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); + String warning = Spatial::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("PathFollow only works when set as a child of a Path node."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("PathFollow only works when set as a child of a Path node."); } else { Path *path = Object::cast_to(get_parent()); if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { - return TTR("PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path's Curve resource."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path's Curve resource."); } } - return String(); + return warning; } void PathFollow::_bind_methods() { diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index 983af7a9ec..604a6000cf 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -180,11 +180,15 @@ void RemoteTransform::force_update_cache() { String RemoteTransform::get_configuration_warning() const { + String warning = Spatial::get_configuration_warning(); if (!has_node(remote_node) || !Object::cast_to(get_node(remote_node))) { - return TTR("The \"Remote Path\" property must point to a valid Spatial or Spatial-derived node to work."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("The \"Remote Path\" property must point to a valid Spatial or Spatial-derived node to work."); } - return String(); + return warning; } void RemoteTransform::_bind_methods() { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 8a99680ebc..77bbd91bc5 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -1224,11 +1224,15 @@ StringName AnimatedSprite3D::get_animation() const { String AnimatedSprite3D::get_configuration_warning() const { + String warning = SpriteBase3D::get_configuration_warning(); if (frames.is_null()) { - return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."); } - return String(); + return warning; } void AnimatedSprite3D::_bind_methods() { diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 4cea324438..9c55b2a6b1 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -104,11 +104,15 @@ void VehicleWheel::_notification(int p_what) { } String VehicleWheel::get_configuration_warning() const { + String warning = Spatial::get_configuration_warning(); if (!Object::cast_to(get_parent())) { - return TTR("VehicleWheel serves to provide a wheel system to a VehicleBody. Please use it as a child of a VehicleBody."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("VehicleWheel serves to provide a wheel system to a VehicleBody. Please use it as a child of a VehicleBody."); } - return String(); + return warning; } void VehicleWheel::_update(PhysicsDirectBodyState *s) { diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index c8d7382e81..02d4f2801a 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -79,8 +79,13 @@ Ref WorldEnvironment::get_environment() const { String WorldEnvironment::get_configuration_warning() const { + String warning = Node::get_configuration_warning(); if (!environment.is_valid()) { - return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect."); + return warning; } if (/*!is_visible_in_tree() ||*/ !is_inside_tree()) @@ -90,7 +95,10 @@ String WorldEnvironment::get_configuration_warning() const { get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes); if (nodes.size() > 1) { - return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); } // Commenting this warning for now, I think it makes no sense. If anyone can figure out what its supposed to do, feedback welcome. Else it should be deprecated. @@ -98,7 +106,7 @@ String WorldEnvironment::get_configuration_warning() const { // return TTR("This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set this environment's Background Mode to Canvas (for 2D scenes)."); //} - return String(); + return warning; } void WorldEnvironment::_bind_methods() { diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 64ef4a01f6..e941749e30 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -234,11 +234,15 @@ Popup::Popup() { String Popup::get_configuration_warning() const { + String warning = Control::get_configuration_warning(); if (is_visible_in_tree()) { - return TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine, but they will hide upon running."); + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine, but they will hide upon running."); } - return String(); + return warning; } Popup::~Popup() { diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 509e6d19f6..5edda1cb27 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -537,6 +537,8 @@ void ScrollContainer::set_follow_focus(bool p_follow) { String ScrollContainer::get_configuration_warning() const { + String warning = Control::get_configuration_warning(); + int found = 0; for (int i = 0; i < get_child_count(); i++) { @@ -552,10 +554,14 @@ String ScrollContainer::get_configuration_warning() const { found++; } - if (found != 1) - return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually."); - else - return ""; + if (found != 1) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually."); + } + + return warning; } HScrollBar *ScrollContainer::get_h_scrollbar() { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index e4f1e97615..459d43a73f 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2986,10 +2986,14 @@ String Viewport::get_configuration_warning() const { return TTR("This viewport is not set as render target. If you intend for it to display its contents directly to the screen, make it a child of a Control so it can obtain a size. Otherwise, make it a RenderTarget and assign its internal texture to some node for display."); }*/ + String warning = Node::get_configuration_warning(); + if (size.x == 0 || size.y == 0) { - return TTR("Viewport size must be greater than 0 to render anything."); + if (warning != String()) + warning += "\n\n"; + warning += TTR("Viewport size must be greater than 0 to render anything."); } - return String(); + return warning; } void Viewport::gui_reset_canvas_sort_index() {