Merge pull request #38743 from arrowinaknee/node-config-warnings

Update all get_configuration_warning() to retrieve warnings from the parent
This commit is contained in:
Rémi Verschelde 2020-10-01 14:03:29 +02:00 committed by GitHub
commit 12091b39d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 284 additions and 114 deletions

View File

@ -251,7 +251,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
if (can_rename) { //should be can edit..
String warning = p_node->get_configuration_warning();
if (warning != String()) {
if (!warning.empty()) {
item->add_button(0, get_theme_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning());
}

View File

@ -660,11 +660,16 @@ StringName AnimatedSprite2D::get_animation() const {
}
String AnimatedSprite2D::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.empty()) {
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 AnimatedSprite2D::set_specular_color(const Color &p_color) {

View File

@ -78,14 +78,19 @@ String CanvasModulate::get_configuration_warning() const {
return String();
}
String warning = Node2D::get_configuration_warning();
List<Node *> 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.empty()) {
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() {

View File

@ -230,15 +230,23 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
#endif
String CollisionPolygon2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
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.empty()) {
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.empty()) {
warning += "\n\n";
}
warning += TTR("An empty CollisionPolygon2D has no effect on collision.");
}
return String();
return warning;
}
void CollisionPolygon2D::set_disabled(bool p_disabled) {

View File

@ -254,7 +254,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<CanvasItemMaterial>(get_material().ptr());

View File

@ -222,7 +222,7 @@ String GPUParticles2D::get_configuration_warning() const {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles2D\" option for this purpose.");
}
String warnings;
String warnings = Node2D::get_configuration_warning();
if (process_material.is_null()) {
if (warnings != String()) {

View File

@ -310,11 +310,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.empty())
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) {

View File

@ -246,15 +246,23 @@ 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.empty()) {
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.empty()) {
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() {

View File

@ -271,11 +271,16 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
}
String NavigationAgent2D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node2D>(get_parent())) {
return TTR("The NavigationAgent2D can be used only under a Node2D node");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationAgent2D can be used only under a Node2D node");
}
return String();
return warning;
}
void NavigationAgent2D::update_navigation() {

View File

@ -106,11 +106,16 @@ Node *NavigationObstacle2D::get_navigation_node() const {
}
String NavigationObstacle2D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node2D>(get_parent())) {
return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object.");
}
return String();
return warning;
}
void NavigationObstacle2D::update_agent_shape() {

View File

@ -500,19 +500,26 @@ String NavigationRegion2D::get_configuration_warning() const {
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.empty()) {
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<Navigation2D>(c)) {
return String();
return warning;
}
c = Object::cast_to<Node2D>(c->get_parent());
}
return TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
if (!warning.empty()) {
warning += "\n\n";
}
return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
}
void NavigationRegion2D::_bind_methods() {

View File

@ -136,11 +136,16 @@ 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<ParallaxBackground>(get_parent())) {
return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node.");
if (!warning.empty()) {
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() {

View File

@ -254,11 +254,16 @@ String PathFollow2D::get_configuration_warning() const {
return String();
}
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<Path2D>(get_parent())) {
return TTR("PathFollow2D only works when set as a child of a Path2D node.");
if (!warning.empty()) {
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() {

View File

@ -748,7 +748,7 @@ String RigidBody2D::get_configuration_warning() const {
String warning = CollisionObject2D::get_configuration_warning();
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");

View File

@ -186,11 +186,16 @@ 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<Node2D>(get_node(remote_node))) {
return TTR("Path property must point to a valid Node2D node to work.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Path property must point to a valid Node2D node to work.");
}
return String();
return warning;
}
void RemoteTransform2D::_bind_methods() {

View File

@ -136,7 +136,7 @@ int Bone2D::get_index_in_skeleton() const {
String Bone2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!skeleton) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
if (parent_bone) {
@ -147,7 +147,7 @@ String Bone2D::get_configuration_warning() const {
}
if (rest == Transform2D(0, 0, 0, 0, 0, 0)) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("This bone lacks a proper REST pose. Go to the Skeleton2D node and set one.");

View File

@ -313,12 +313,17 @@ 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.empty()) {
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() {

View File

@ -156,15 +156,23 @@ bool CollisionPolygon3D::is_disabled() const {
}
String CollisionPolygon3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
return TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
if (polygon.empty()) {
return TTR("An empty CollisionPolygon3D has no effect on collision.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("An empty CollisionPolygon3D has no effect on collision.");
}
return String();
return warning;
}
bool CollisionPolygon3D::_is_editable_3d_polygon() const {

View File

@ -124,23 +124,34 @@ void CollisionShape3D::resource_changed(RES res) {
}
String CollisionShape3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
return TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
if (!shape.is_valid()) {
return TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.");
}
if (Object::cast_to<RigidBody3D>(get_parent())) {
if (Object::cast_to<ConcavePolygonShape3D>(*shape)) {
if (Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) {
return TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.");
}
}
}
return String();
return warning;
}
void CollisionShape3D::_bind_methods() {

View File

@ -189,7 +189,7 @@ bool CPUParticles3D::get_fractional_delta() const {
}
String CPUParticles3D::get_configuration_warning() const {
String warnings;
String warnings = GeometryInstance3D::get_configuration_warning();
bool mesh_found = false;
bool anim_material_found = false;

View File

@ -514,10 +514,15 @@ Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const {
}
String GIProbe::get_configuration_warning() const {
String warning = VisualInstance3D::get_configuration_warning();
if (RenderingServer::get_singleton()->is_low_end()) {
return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
if (!warning.empty()) {
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() {

View File

@ -232,7 +232,7 @@ String GPUParticles3D::get_configuration_warning() const {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose.");
}
String warnings;
String warnings = GeometryInstance3D::get_configuration_warning();
bool meshes_found = false;
bool anim_material_found = false;

View File

@ -448,7 +448,7 @@ String OmniLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (!has_shadow() && get_projector().is_valid()) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");
@ -482,15 +482,14 @@ String SpotLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.");
}
if (!has_shadow() && get_projector().is_valid()) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");

View File

@ -287,11 +287,16 @@ void NavigationAgent3D::_avoidance_done(Vector3 p_new_velocity) {
}
String NavigationAgent3D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node3D>(get_parent())) {
return TTR("The NavigationAgent3D can be used only under a spatial node.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationAgent3D can be used only under a spatial node.");
}
return String();
return warning;
}
void NavigationAgent3D::update_navigation() {

View File

@ -113,11 +113,16 @@ Node *NavigationObstacle3D::get_navigation_node() const {
}
String NavigationObstacle3D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node3D>(get_parent())) {
return TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
}
return String();
return warning;
}
void NavigationObstacle3D::update_agent_shape() {

View File

@ -189,19 +189,26 @@ String NavigationRegion3D::get_configuration_warning() const {
return String();
}
String warning = Node3D::get_configuration_warning();
if (!navmesh.is_valid()) {
return TTR("A NavigationMesh resource must be set or created for this node to work.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
}
const Node3D *c = this;
while (c) {
if (Object::cast_to<Navigation3D>(c)) {
return String();
}
if (Object::cast_to<Navigation3D>(c))
return warning;
c = Object::cast_to<Node3D>(c->get_parent());
}
return TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
if (!warning.empty()) {
warning += "\n\n";
}
return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
}
void NavigationRegion3D::_bind_methods() {

View File

@ -250,16 +250,24 @@ String PathFollow3D::get_configuration_warning() const {
return String();
}
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<Path3D>(get_parent())) {
return TTR("PathFollow3D only works when set as a child of a Path3D node.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("PathFollow3D only works when set as a child of a Path3D node.");
} else {
Path3D *path = Object::cast_to<Path3D>(get_parent());
if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) {
return TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.");
}
}
return String();
return warning;
}
void PathFollow3D::_bind_methods() {

View File

@ -737,7 +737,7 @@ String RigidBody3D::get_configuration_warning() const {
String warning = CollisionObject3D::get_configuration_warning();
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");

View File

@ -180,11 +180,16 @@ void RemoteTransform3D::force_update_cache() {
}
String RemoteTransform3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) {
return TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
}
return String();
return warning;
}
void RemoteTransform3D::_bind_methods() {

View File

@ -1074,11 +1074,16 @@ 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.empty()) {
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() {

View File

@ -103,11 +103,16 @@ void VehicleWheel3D::_notification(int p_what) {
}
String VehicleWheel3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<VehicleBody3D>(get_parent())) {
return TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.");
}
return String();
return warning;
}
void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {

View File

@ -110,22 +110,30 @@ Ref<CameraEffects> WorldEnvironment::get_camera_effects() 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.empty()) {
warning += "\n\n";
}
warning += TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
}
if (!is_inside_tree()) {
return String();
return warning;
}
List<Node *> nodes;
get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->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.empty()) {
warning += "\n\n";
}
warning += TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
}
return String();
return warning;
}
void WorldEnvironment::_bind_methods() {

View File

@ -60,13 +60,18 @@ String XRCamera3D::get_configuration_warning() const {
return String();
}
String warning = Camera3D::get_configuration_warning();
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
return TTR("XRCamera3D must have an XROrigin3D node as its parent.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("XRCamera3D must have an XROrigin3D node as its parent.");
};
return String();
return warning;
};
Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const {
@ -362,17 +367,25 @@ String XRController3D::get_configuration_warning() const {
return String();
}
String warning = Node3D::get_configuration_warning();
// must be child node of XROrigin!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
return TTR("XRController3D must have an XROrigin3D node as its parent.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("XRController3D must have an XROrigin3D 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.empty()) {
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;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -479,17 +492,25 @@ String XRAnchor3D::get_configuration_warning() const {
return String();
}
String warning = Node3D::get_configuration_warning();
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
return TTR("XRAnchor3D must have an XROrigin3D node as its parent.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("XRAnchor3D must have an XROrigin3D 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.empty()) {
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 XRAnchor3D::get_plane() const {
@ -512,11 +533,16 @@ String XROrigin3D::get_configuration_warning() const {
return String();
}
String warning = Node3D::get_configuration_warning();
if (tracked_camera == nullptr) {
return TTR("XROrigin3D requires an XRCamera3D child node.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("XROrigin3D requires an XRCamera3D child node.");
}
return String();
return warning;
};
void XROrigin3D::_bind_methods() {

View File

@ -1288,39 +1288,31 @@ String AnimationTree::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!root.is_valid()) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("No root AnimationNode for the graph is set.");
}
if (!has_node(animation_player)) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Path to an AnimationPlayer node containing animations is not set.");
return warning;
}
} else {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
if (!player) {
if (warning != String()) {
warning += "\n\n";
if (!player) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node.");
} else if (!player->has_node(player->get_root())) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The AnimationPlayer root node is not a valid node.");
}
warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node.");
return warning;
}
if (!player->has_node(player->get_root())) {
if (warning != String()) {
warning += "\n\n";
}
warning += TTR("The AnimationPlayer root node is not a valid node.");
return warning;
}
return warning;

View File

@ -168,7 +168,7 @@ String Container::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
if (get_class() == "Container" && get_script().is_null()) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead.");

View File

@ -2560,7 +2560,7 @@ String Control::get_configuration_warning() const {
String warning = CanvasItem::get_configuration_warning();
if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".");

View File

@ -34,7 +34,7 @@ String Range::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
if (shared->exp_ratio && shared->min <= 0) {
if (warning != String()) {
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0.");

View File

@ -520,6 +520,8 @@ void ScrollContainer::set_follow_focus(bool p_follow) {
}
String ScrollContainer::get_configuration_warning() const {
String warning = Container::get_configuration_warning();
int found = 0;
for (int i = 0; i < get_child_count(); i++) {
@ -538,10 +540,12 @@ String ScrollContainer::get_configuration_warning() const {
}
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 (!warning.empty()) {
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() {

View File

@ -261,11 +261,16 @@ void ShaderGlobalsOverride::_notification(int p_what) {
}
String ShaderGlobalsOverride::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!active) {
return TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene.");
if (!warning.empty()) {
warning += "\n\n";
}
warning += TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene.");
}
return String();
return warning;
}
void ShaderGlobalsOverride::_bind_methods() {

View File

@ -3093,10 +3093,15 @@ 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.empty()) {
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() {