Make all get_configuration_warning() overrides retrieve warnings from parent

This commit is contained in:
ArrowInAKnee 2020-03-22 11:31:09 +03:00
parent c2a4ce9380
commit e48430b1d4
28 changed files with 249 additions and 90 deletions

View File

@ -667,11 +667,15 @@ StringName AnimatedSprite::get_animation() const {
String AnimatedSprite::get_configuration_warning() const { String AnimatedSprite::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (frames.is_null()) { 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() { void AnimatedSprite::_bind_methods() {

View File

@ -81,17 +81,21 @@ Color CanvasModulate::get_color() const {
String CanvasModulate::get_configuration_warning() const { String CanvasModulate::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!is_visible_in_tree() || !is_inside_tree()) if (!is_visible_in_tree() || !is_inside_tree())
return String(); return warning;
List<Node *> nodes; List<Node *> nodes;
get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes); get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes);
if (nodes.size() > 1) { 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() { CanvasModulate::CanvasModulate() {

View File

@ -247,15 +247,22 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
String CollisionPolygon2D::get_configuration_warning() const { String CollisionPolygon2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<CollisionObject2D>(get_parent())) { if (!Object::cast_to<CollisionObject2D>(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()) { 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) { void CollisionPolygon2D::set_disabled(bool p_disabled) {

View File

@ -180,18 +180,29 @@ bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double
String CollisionShape2D::get_configuration_warning() const { String CollisionShape2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<CollisionObject2D>(get_parent())) { if (!Object::cast_to<CollisionObject2D>(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()) { 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<ConvexPolygonShape2D> convex = shape; Ref<ConvexPolygonShape2D> convex = shape;
Ref<ConcavePolygonShape2D> concave = shape; Ref<ConcavePolygonShape2D> concave = shape;
if (convex.is_valid() || concave.is_valid()) { 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";
} }
return String(); warning += TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead.");
}
return warning;
} }
void CollisionShape2D::set_disabled(bool p_disabled) { void CollisionShape2D::set_disabled(bool p_disabled) {

View File

@ -267,7 +267,7 @@ bool CPUParticles2D::get_fractional_delta() const {
String CPUParticles2D::get_configuration_warning() const { String CPUParticles2D::get_configuration_warning() const {
String warnings; String warnings = Node2D::get_configuration_warning();
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(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 || 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()) { get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) {
if (warnings != String()) if (warnings != String())
warnings += "\n"; warnings += "\n\n";
warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
} }
} }

View File

@ -352,11 +352,15 @@ void Light2D::_notification(int p_what) {
String Light2D::get_configuration_warning() const { String Light2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!texture.is_valid()) { 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) { void Light2D::set_shadow_smooth(float p_amount) {

View File

@ -268,15 +268,22 @@ int LightOccluder2D::get_occluder_light_mask() const {
String LightOccluder2D::get_configuration_warning() const { String LightOccluder2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!occluder_polygon.is_valid()) { 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) { 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() { void LightOccluder2D::_bind_methods() {

View File

@ -504,20 +504,29 @@ String NavigationPolygonInstance::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) if (!is_visible_in_tree() || !is_inside_tree())
return String(); return String();
String warning = Node2D::get_configuration_warning();
if (!navpoly.is_valid()) { 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; const Node2D *c = this;
while (c) { while (c) {
if (Object::cast_to<Navigation2D>(c)) { if (Object::cast_to<Navigation2D>(c)) {
return String(); return warning;
} }
c = Object::cast_to<Node2D>(c->get_parent()); c = Object::cast_to<Node2D>(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() { void NavigationPolygonInstance::_bind_methods() {

View File

@ -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 ParallaxLayer::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<ParallaxBackground>(get_parent())) { if (!Object::cast_to<ParallaxBackground>(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() { void ParallaxLayer::_bind_methods() {

View File

@ -227,17 +227,19 @@ bool Particles2D::get_fractional_delta() const {
} }
String Particles2D::get_configuration_warning() 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) { 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 (process_material.is_null()) {
if (warnings != String()) if (warning != String())
warnings += "\n"; warning += "\n\n";
warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted."); warning += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted.");
} else { } else {
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
@ -247,14 +249,14 @@ String Particles2D::get_configuration_warning() const {
if (process && if (process &&
(process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || (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())) { process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String()) if (warning != String())
warnings += "\n"; warning += "\n\n";
warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); warning += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
} }
} }
} }
return warnings; return warning;
} }
Rect2 Particles2D::capture_rect() const { Rect2 Particles2D::capture_rect() const {

View File

@ -275,11 +275,15 @@ String PathFollow2D::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) if (!is_visible_in_tree() || !is_inside_tree())
return String(); return String();
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<Path2D>(get_parent())) { if (!Object::cast_to<Path2D>(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() { void PathFollow2D::_bind_methods() {

View File

@ -186,11 +186,15 @@ void RemoteTransform2D::force_update_cache() {
String RemoteTransform2D::get_configuration_warning() const { String RemoteTransform2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) { if (!has_node(remote_node) || !Object::cast_to<Node2D>(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() { void RemoteTransform2D::_bind_methods() {

View File

@ -330,12 +330,16 @@ void VisibilityEnabler2D::_node_removed(Node *p_node) {
} }
String VisibilityEnabler2D::get_configuration_warning() const { String VisibilityEnabler2D::get_configuration_warning() const {
String warning = VisibilityNotifier2D::get_configuration_warning();
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) { 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 #endif
return String(); return warning;
} }
void VisibilityEnabler2D::_bind_methods() { void VisibilityEnabler2D::_bind_methods() {

View File

@ -58,13 +58,17 @@ String ARVRCamera::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree()) if (!is_visible() || !is_inside_tree())
return String(); return String();
String warning = Camera::get_configuration_warning();
// must be child node of ARVROrigin! // must be child node of ARVROrigin!
ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
if (origin == NULL) { 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 { 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()) if (!is_visible() || !is_inside_tree())
return String(); return String();
String warning = Spatial::get_configuration_warning();
// must be child node of ARVROrigin! // must be child node of ARVROrigin!
ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
if (origin == NULL) { 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) { 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() { ARVRController::ARVRController() {
@ -494,17 +505,24 @@ String ARVRAnchor::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree()) if (!is_visible() || !is_inside_tree())
return String(); return String();
String warning = Spatial::get_configuration_warning();
// must be child node of ARVROrigin! // must be child node of ARVROrigin!
ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent());
if (origin == NULL) { 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) { 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 { Plane ARVRAnchor::get_plane() const {
@ -535,10 +553,15 @@ String ARVROrigin::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree()) if (!is_visible() || !is_inside_tree())
return String(); return String();
if (tracked_camera == NULL) String warning = Spatial::get_configuration_warning();
return TTR("ARVROrigin requires an ARVRCamera child node."); 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() { void ARVROrigin::_bind_methods() {

View File

@ -164,15 +164,22 @@ bool CollisionPolygon::is_disabled() const {
String CollisionPolygon::get_configuration_warning() const { String CollisionPolygon::get_configuration_warning() const {
String warning = Spatial::get_configuration_warning();
if (!Object::cast_to<CollisionObject>(get_parent())) { if (!Object::cast_to<CollisionObject>(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()) { 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 { bool CollisionPolygon::_is_editable_3d_polygon() const {

View File

@ -115,27 +115,40 @@ void CollisionShape::resource_changed(RES res) {
String CollisionShape::get_configuration_warning() const { String CollisionShape::get_configuration_warning() const {
String warning = Spatial::get_configuration_warning();
if (!Object::cast_to<CollisionObject>(get_parent())) { if (!Object::cast_to<CollisionObject>(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()) { 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")) { 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<RigidBody>(get_parent())) { if (Object::cast_to<RigidBody>(get_parent())) {
if (Object::cast_to<ConcavePolygonShape>(*shape)) { if (Object::cast_to<ConcavePolygonShape>(*shape)) {
if (Object::cast_to<RigidBody>(get_parent())->get_mode() != RigidBody::MODE_STATIC) { if (Object::cast_to<RigidBody>(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() { void CollisionShape::_bind_methods() {

View File

@ -201,7 +201,7 @@ bool CPUParticles::get_fractional_delta() const {
String CPUParticles::get_configuration_warning() const { String CPUParticles::get_configuration_warning() const {
String warnings; String warnings = GeometryInstance::get_configuration_warning();
bool mesh_found = false; bool mesh_found = false;
bool anim_material_found = false; bool anim_material_found = false;

View File

@ -490,11 +490,14 @@ PoolVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const {
} }
String GIProbe::get_configuration_warning() 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) { 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";
} }
return String(); warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
}
return warning;
} }
void GIProbe::_bind_methods() { void GIProbe::_bind_methods() {

View File

@ -697,19 +697,28 @@ String NavigationMeshInstance::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) if (!is_visible_in_tree() || !is_inside_tree())
return String(); return String();
String warning = Spatial::get_configuration_warning();
if (!navmesh.is_valid()) { 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; const Spatial *c = this;
while (c) { while (c) {
if (Object::cast_to<Navigation>(c)) if (Object::cast_to<Navigation>(c))
return String(); return warning;
c = Object::cast_to<Spatial>(c->get_parent()); c = Object::cast_to<Spatial>(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() { void NavigationMeshInstance::_bind_methods() {

View File

@ -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."); 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 meshes_found = false;
bool anim_material_found = false; bool anim_material_found = false;
@ -267,7 +267,7 @@ String Particles::get_configuration_warning() const {
if (!meshes_found) { if (!meshes_found) {
if (warnings != String()) if (warnings != String())
warnings += "\n"; warnings += "\n\n";
warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes."); warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes.");
} }

View File

@ -264,16 +264,23 @@ String PathFollow::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) if (!is_visible_in_tree() || !is_inside_tree())
return String(); return String();
String warning = Spatial::get_configuration_warning();
if (!Object::cast_to<Path>(get_parent())) { if (!Object::cast_to<Path>(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 { } else {
Path *path = Object::cast_to<Path>(get_parent()); Path *path = Object::cast_to<Path>(get_parent());
if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { 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() { void PathFollow::_bind_methods() {

View File

@ -180,11 +180,15 @@ void RemoteTransform::force_update_cache() {
String RemoteTransform::get_configuration_warning() const { String RemoteTransform::get_configuration_warning() const {
String warning = Spatial::get_configuration_warning();
if (!has_node(remote_node) || !Object::cast_to<Spatial>(get_node(remote_node))) { if (!has_node(remote_node) || !Object::cast_to<Spatial>(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() { void RemoteTransform::_bind_methods() {

View File

@ -1205,11 +1205,15 @@ StringName AnimatedSprite3D::get_animation() const {
String AnimatedSprite3D::get_configuration_warning() const { String AnimatedSprite3D::get_configuration_warning() const {
String warning = SpriteBase3D::get_configuration_warning();
if (frames.is_null()) { 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() { void AnimatedSprite3D::_bind_methods() {

View File

@ -104,11 +104,15 @@ void VehicleWheel::_notification(int p_what) {
} }
String VehicleWheel::get_configuration_warning() const { String VehicleWheel::get_configuration_warning() const {
String warning = Spatial::get_configuration_warning();
if (!Object::cast_to<VehicleBody>(get_parent())) { if (!Object::cast_to<VehicleBody>(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) { void VehicleWheel::_update(PhysicsDirectBodyState *s) {

View File

@ -79,8 +79,13 @@ Ref<Environment> WorldEnvironment::get_environment() const {
String WorldEnvironment::get_configuration_warning() const { String WorldEnvironment::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!environment.is_valid()) { 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()) 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); get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes);
if (nodes.size() > 1) { 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. // 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 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() { void WorldEnvironment::_bind_methods() {

View File

@ -234,11 +234,15 @@ Popup::Popup() {
String Popup::get_configuration_warning() const { String Popup::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
if (is_visible_in_tree()) { 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() { Popup::~Popup() {

View File

@ -537,6 +537,8 @@ void ScrollContainer::set_follow_focus(bool p_follow) {
String ScrollContainer::get_configuration_warning() const { String ScrollContainer::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
int found = 0; int found = 0;
for (int i = 0; i < get_child_count(); i++) { for (int i = 0; i < get_child_count(); i++) {
@ -552,10 +554,14 @@ String ScrollContainer::get_configuration_warning() const {
found++; found++;
} }
if (found != 1) 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."); if (warning != String()) {
else warning += "\n\n";
return ""; }
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() { HScrollBar *ScrollContainer::get_h_scrollbar() {

View File

@ -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."); 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) { 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() { void Viewport::gui_reset_canvas_sort_index() {