diff options
Diffstat (limited to 'scene')
56 files changed, 635 insertions, 43 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index f482f775c4..c062a6d1fc 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -233,8 +233,6 @@ void SpriteFrames::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_animation_loop","anim","loop"),&SpriteFrames::set_animation_loop); ObjectTypeDB::bind_method(_MD("get_animation_loop","anim"),&SpriteFrames::get_animation_loop); - ObjectTypeDB::bind_method(_MD("add_frame","frame","atpos"),&SpriteFrames::add_frame,DEFVAL(-1)); - ObjectTypeDB::bind_method(_MD("add_frame","anim","frame","atpos"),&SpriteFrames::add_frame,DEFVAL(-1)); ObjectTypeDB::bind_method(_MD("get_frame_count","anim"),&SpriteFrames::get_frame_count); ObjectTypeDB::bind_method(_MD("get_frame","anim","idx"),&SpriteFrames::get_frame); @@ -454,6 +452,7 @@ void AnimatedSprite::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { _change_notify(); _reset_timeout(); update(); + update_configuration_warning(); } @@ -488,6 +487,8 @@ void AnimatedSprite::set_frame(int p_frame) { _change_notify("frame"); emit_signal(SceneStringNames::get_singleton()->frame_changed); + + } int AnimatedSprite::get_frame() const { @@ -648,6 +649,15 @@ StringName AnimatedSprite::get_animation() const{ return animation; } +String AnimatedSprite::get_configuration_warning() const { + + 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."); + } + + return String(); +} + void AnimatedSprite::_bind_methods() { diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index bbf9c7aafb..968cd9aa30 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -176,7 +176,7 @@ public: virtual Rect2 get_item_rect() const; - + virtual String get_configuration_warning() const; AnimatedSprite(); }; diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 77203a7110..cc0db2da77 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -5,19 +5,30 @@ void CanvasModulate::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_CANVAS) { - if (is_visible()) + if (is_visible()) { VS::get_singleton()->canvas_set_modulate(get_canvas(),color); + add_to_group("_canvas_modulate_"+itos(get_canvas().get_id())); + } + + + } else if (p_what==NOTIFICATION_EXIT_CANVAS) { - if (is_visible()) + if (is_visible()) { VS::get_singleton()->canvas_set_modulate(get_canvas(),Color(1,1,1,1)); + remove_from_group("_canvas_modulate_"+itos(get_canvas().get_id())); + } } else if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { if (is_visible()) { VS::get_singleton()->canvas_set_modulate(get_canvas(),color); + add_to_group("_canvas_modulate_"+itos(get_canvas().get_id())); } else { VS::get_singleton()->canvas_set_modulate(get_canvas(),Color(1,1,1,1)); + remove_from_group("_canvas_modulate_"+itos(get_canvas().get_id())); } + + update_configuration_warning(); } } @@ -42,6 +53,20 @@ Color CanvasModulate::get_color() const { return color; } +String CanvasModulate::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree()) + return String(); + + 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 one created will work, while the rest will be ignored."); + } + + return String(); +} CanvasModulate::CanvasModulate() { diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index a6894f29c2..0445db27af 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -16,6 +16,8 @@ public: void set_color(const Color& p_color); Color get_color() const; + String get_configuration_warning() const; + CanvasModulate(); ~CanvasModulate(); }; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 2a40a6207d..544f0e2088 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -297,6 +297,20 @@ Vector2 CollisionPolygon2D::_get_shape_range() const { return Vector2(shape_from,shape_to); } +String CollisionPolygon2D::get_configuration_warning() const { + + if (!get_parent()->cast_to<CollisionObject2D>()) { + 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 (polygon.empty()) { + return TTR("An empty CollisionPolygon2D has no effect on collision."); + + } + + return String(); +} + void CollisionPolygon2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon2D::_add_to_collision_object); diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index b2bd4d189d..9c0e4e0c01 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -85,6 +85,8 @@ public: int get_collision_object_first_shape() const { return shape_from; } int get_collision_object_last_shape() const { return shape_to; } + virtual String get_configuration_warning() const; + CollisionPolygon2D(); }; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 405310450b..c737cf0faf 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -201,6 +201,19 @@ int CollisionShape2D::_get_update_shape_index() const{ return update_shape_index; } +String CollisionShape2D::get_configuration_warning() const { + + if (!get_parent()->cast_to<CollisionObject2D>()) { + 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 (!shape.is_valid()) { + return TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!"); + } + + return String(); +} + void CollisionShape2D::_bind_methods() { diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index b14dad73ba..6f3f17d412 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -63,6 +63,8 @@ public: int get_collision_object_shape_index() const { return _get_update_shape_index(); } + virtual String get_configuration_warning() const; + CollisionShape2D(); }; diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 9715afeaa4..b79c07360b 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -61,6 +61,8 @@ void Light2D::set_texture( const Ref<Texture>& p_texture) { VS::get_singleton()->canvas_light_set_texture(canvas_light,texture->get_rid()); else VS::get_singleton()->canvas_light_set_texture(canvas_light,RID()); + + update_configuration_warning(); } Ref<Texture> Light2D::get_texture() const { @@ -282,6 +284,16 @@ void Light2D::_notification(int p_what) { } +String Light2D::get_configuration_warning() const { + + if (!texture.is_valid()) { + return TTR("A texture with the shape of the light must be supplied to the 'texture' property."); + } + + return String(); +} + + void Light2D::_bind_methods() { diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index ca437769e7..a8b0ef3b23 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -104,6 +104,8 @@ public: virtual Rect2 get_item_rect() const; + String get_configuration_warning() const; + Light2D(); ~Light2D(); }; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index d98bed0ea3..ce617b1737 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -45,6 +45,8 @@ RID OccluderPolygon2D::get_rid() const { return occ_polygon; } + + void OccluderPolygon2D::_bind_methods() { @@ -178,6 +180,20 @@ int LightOccluder2D::get_occluder_light_mask() const{ return mask; } + +String LightOccluder2D::get_configuration_warning() const { + + if (!occluder_polygon.is_valid()) { + return 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!"); + } + + return String(); +} + void LightOccluder2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_occluder_polygon","polygon:OccluderPolygon2D"),&LightOccluder2D::set_occluder_polygon); diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 0343e3697e..ccc2a1cd9c 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -66,6 +66,8 @@ public: void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; + String get_configuration_warning() const; + LightOccluder2D(); ~LightOccluder2D(); }; diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 376aeb2d85..8c0d9cf35f 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -413,6 +413,7 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg } //update_gizmo(); _change_notify("navpoly"); + update_configuration_warning(); } @@ -427,6 +428,28 @@ void NavigationPolygonInstance::_navpoly_changed() { update(); } + +String NavigationPolygonInstance::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree()) + return String(); + + 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."); + } + const Node2D *c=this; + while(c) { + + if (c->cast_to<Navigation2D>()) { + return String(); + } + + c=c->get_parent()->cast_to<Node2D>(); + } + + return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); +} + void NavigationPolygonInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly:NavigationPolygon"),&NavigationPolygonInstance::set_navigation_polygon); diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index 01307a170b..07fee571f0 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -77,6 +77,8 @@ public: void set_navigation_polygon(const Ref<NavigationPolygon>& p_navpoly); Ref<NavigationPolygon> get_navigation_polygon() const; + String get_configuration_warning() const; + NavigationPolygonInstance(); }; diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 7a898e43c9..bf559deb09 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -118,6 +118,16 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2& p_offset,float p_sca } + +String ParallaxLayer::get_configuration_warning() const { + + if (!get_parent() || !get_parent()->cast_to<ParallaxBackground>()) { + return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."); + } + + return String(); +} + void ParallaxLayer::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_motion_scale","scale"),&ParallaxLayer::set_motion_scale); diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index 6c24a9b9f7..c2d345da47 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -56,6 +56,7 @@ public: void set_base_offset_and_scale(const Point2& p_offsetf,float p_scale); + virtual String get_configuration_warning() const; ParallaxLayer(); }; diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index ffea060e82..29dad630d6 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -198,13 +198,21 @@ void ParticleAttractor2D::set_particles_path(NodePath p_path) { path=p_path; _update_owner(); + update_configuration_warning(); } NodePath ParticleAttractor2D::get_particles_path() const { return path; } +String ParticleAttractor2D::get_configuration_warning() const { + if (!has_node(path) || !get_node(path) || !get_node(path)->cast_to<Particles2D>()) { + return TTR("Path property must point to a valid Particles2D node to work."); + } + + return String(); +} ParticleAttractor2D::ParticleAttractor2D() { diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 06dcda7165..b1ae1f5bc1 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -75,6 +75,8 @@ public: void set_particles_path(NodePath p_path); NodePath get_particles_path() const; + virtual String get_configuration_warning() const; + ParticleAttractor2D(); }; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index bd7415aa04..dee67a829f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -237,6 +237,19 @@ void PathFollow2D::_get_property_list( List<PropertyInfo> *p_list) const{ } +String PathFollow2D::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree()) + return String(); + + if (!get_parent() || !get_parent()->cast_to<Path2D>()) { + return TTR("PathFolow2D only works when set as a child of a Path2D node."); + } + + return String(); + +} + void PathFollow2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_offset","offset"),&PathFollow2D::set_offset); diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 486a8ac9ac..84725e7123 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -109,6 +109,8 @@ public: void set_cubic_interpolation(bool p_enable); bool get_cubic_interpolation() const; + String get_configuration_warning() const; + PathFollow2D(); }; diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 6dcd980822..4de648a1db 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -97,6 +97,8 @@ void RemoteTransform2D::set_remote_node(const NodePath& p_remote_node) { remote_node=p_remote_node; if (is_inside_tree()) _update_cache(); + + update_configuration_warning(); } NodePath RemoteTransform2D::get_remote_node() const{ @@ -105,6 +107,15 @@ NodePath RemoteTransform2D::get_remote_node() const{ } +String RemoteTransform2D::get_configuration_warning() const { + + if (!has_node(remote_node) || !get_node(remote_node) || !get_node(remote_node)->cast_to<Node2D>()) { + return TTR("Path property must point to a valid Node2D node to work."); + } + + return String(); +} + void RemoteTransform2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_remote_node","path"),&RemoteTransform2D::set_remote_node); diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index 4a5f5f72ea..0ea1438f0a 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -48,5 +48,7 @@ public: void set_remote_node(const NodePath& p_remote_node); NodePath get_remote_node() const; + virtual String get_configuration_warning() const; + RemoteTransform2D(); }; diff --git a/scene/2d/sample_player_2d.cpp b/scene/2d/sample_player_2d.cpp index bf09130238..4d719b532b 100644 --- a/scene/2d/sample_player_2d.cpp +++ b/scene/2d/sample_player_2d.cpp @@ -103,6 +103,7 @@ void SamplePlayer2D::set_sample_library(const Ref<SampleLibrary>& p_library) { library=p_library; _change_notify(); + update_configuration_warning(); } Ref<SampleLibrary> SamplePlayer2D::get_sample_library() const { @@ -207,6 +208,14 @@ float SamplePlayer2D::get_random_pitch_scale() const { return random_pitch_scale; } +String SamplePlayer2D::get_configuration_warning() const { + + if (library.is_null()) { + return TTR("A SampleLibrary resource must be created or set in the 'samples' property in order for SamplePlayer to play sound."); + } + + return String(); +} void SamplePlayer2D::_bind_methods() { diff --git a/scene/2d/sample_player_2d.h b/scene/2d/sample_player_2d.h index eddf84f77b..5ab7f024d3 100644 --- a/scene/2d/sample_player_2d.h +++ b/scene/2d/sample_player_2d.h @@ -83,6 +83,8 @@ public: void set_random_pitch_scale(float p_scale); float get_random_pitch_scale() const; + String get_configuration_warning() const; + SamplePlayer2D(); ~SamplePlayer2D(); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index b2902b2867..aebb9a4c28 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -529,6 +529,25 @@ Rect2 ViewportSprite::get_item_rect() const { return Rect2(ofs,s); } +String ViewportSprite::get_configuration_warning() const { + + if (!has_node(viewport_path) || !get_node(viewport_path) || !get_node(viewport_path)->cast_to<Viewport>()) { + return TTR("Path property must point to a valid Viewport node to work. Such Viewport must be set to 'render target' mode."); + } else { + + Node *n = get_node(viewport_path); + if (n) { + Viewport *vp = n->cast_to<Viewport>(); + if (!vp->is_set_as_render_target()) { + + return TTR("The Viewport set in the path property must be set as 'render taget' in order for this sprite to work"); + } + } + } + + return String(); + +} void ViewportSprite::_bind_methods() { diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index cbcaec9aeb..f789538b1d 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -142,6 +142,8 @@ public: virtual Rect2 get_item_rect() const; + virtual String get_configuration_warning() const; + ViewportSprite(); }; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 426e86fa13..12524a2192 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -346,6 +346,16 @@ void VisibilityEnabler2D::_node_removed(Node* p_node) { } +String VisibilityEnabler2D::get_configuration_warning() const { +#ifdef TOOLS_ENABLED + if (is_inside_tree() && get_parent() && (get_parent()->get_filename()==String() && get_parent()!=get_tree()->get_edited_scene_root())) { + return TTR("VisibilityEnable2D works best when used with the edited scene root directly as parent."); + } +#endif + return String(); +} + + void VisibilityEnabler2D::_bind_methods(){ ObjectTypeDB::bind_method(_MD("set_enabler","enabler","enabled"),&VisibilityEnabler2D::set_enabler); diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index 647a5b6e91..354ccf4345 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -103,6 +103,8 @@ public: void set_enabler(Enabler p_enabler,bool p_enable); bool is_enabler_enabled(Enabler p_enabler) const; + String get_configuration_warning() const; + VisibilityEnabler2D(); }; diff --git a/scene/3d/body_shape.cpp b/scene/3d/body_shape.cpp index 3a47371de3..e62ab394af 100644 --- a/scene/3d/body_shape.cpp +++ b/scene/3d/body_shape.cpp @@ -398,6 +398,19 @@ int CollisionShape::_get_update_shape_index() const{ return update_shape_index; } +String CollisionShape::get_configuration_warning() const { + + if (!get_parent()->cast_to<CollisionObject>()) { + 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 (!shape.is_valid()) { + return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!"); + } + + return String(); +} + void CollisionShape::_bind_methods() { diff --git a/scene/3d/body_shape.h b/scene/3d/body_shape.h index dd005c0edd..a3289bf26a 100644 --- a/scene/3d/body_shape.h +++ b/scene/3d/body_shape.h @@ -90,6 +90,9 @@ public: int get_collision_object_shape_index() const { return _get_update_shape_index(); } + + String get_configuration_warning() const; + CollisionShape(); ~CollisionShape(); }; diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index 3b14e1d767..e05f29714b 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -231,6 +231,19 @@ float CollisionPolygon::get_depth() const { return depth; } +String CollisionPolygon::get_configuration_warning() const { + + if (!get_parent()->cast_to<CollisionObject>()) { + 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 (polygon.empty()) { + return TTR("An empty CollisionPolygon has no effect on collision."); + + } + + return String(); +} void CollisionPolygon::_bind_methods() { diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h index 9b9afea34f..3d190a02b3 100644 --- a/scene/3d/collision_polygon.h +++ b/scene/3d/collision_polygon.h @@ -55,6 +55,8 @@ public: int get_collision_object_first_shape() const { return shape_from; } int get_collision_object_last_shape() const { return shape_to; } + String get_configuration_warning() const; + CollisionPolygon(); }; diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index a238a8ff22..3adf282f13 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -329,6 +329,7 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh>& p_na nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this); } update_gizmo(); + update_configuration_warning(); } @@ -337,6 +338,27 @@ Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const{ return navmesh; } +String NavigationMeshInstance::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree()) + return String(); + + if (!navmesh.is_valid()) { + return TTR("A NavigationMesh resource must be set or created for this node to work."); + } + const Spatial *c=this; + while(c) { + + if (c->cast_to<Navigation>()) + return String(); + + c=c->get_parent()->cast_to<Spatial>(); + } + + return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); +} + + void NavigationMeshInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_navigation_mesh","navmesh"),&NavigationMeshInstance::set_navigation_mesh); diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h index 1e53b2127a..cb3b5d95f6 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -78,6 +78,8 @@ public: void set_navigation_mesh(const Ref<NavigationMesh>& p_navmesh); Ref<NavigationMesh> get_navigation_mesh() const; + String get_configuration_warning() const; + NavigationMeshInstance(); }; diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/scenario_fx.cpp index 2e22ab36d3..f01c2263fb 100644 --- a/scene/3d/scenario_fx.cpp +++ b/scene/3d/scenario_fx.cpp @@ -40,12 +40,17 @@ void WorldEnvironment::_notification(int p_what) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } get_world()->set_environment(environment); + add_to_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); + } } else if (p_what==NOTIFICATION_EXIT_WORLD) { - if (environment.is_valid() && get_world()->get_environment()==environment) + if (environment.is_valid() && get_world()->get_environment()==environment) { get_world()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); + + } } } @@ -53,6 +58,7 @@ void WorldEnvironment::set_environment(const Ref<Environment>& p_environment) { if (is_inside_world() && environment.is_valid() && get_world()->get_environment()==environment) { get_world()->set_environment(Ref<Environment>()); + remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); //clean up } @@ -63,7 +69,11 @@ void WorldEnvironment::set_environment(const Ref<Environment>& p_environment) { WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); } get_world()->set_environment(environment); + add_to_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); + } + + update_configuration_warning(); } Ref<Environment> WorldEnvironment::get_environment() const { @@ -71,6 +81,21 @@ Ref<Environment> WorldEnvironment::get_environment() const { return environment; } +String WorldEnvironment::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree() || !environment.is_valid()) + return String(); + + List<Node*> nodes; + get_tree()->get_nodes_in_group("_world_environment_"+itos(get_world()->get_scenario().get_id()),&nodes); + + if (nodes.size()>1) { + return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); + } + + return String(); +} + void WorldEnvironment::_bind_methods() { diff --git a/scene/3d/scenario_fx.h b/scene/3d/scenario_fx.h index a3c13e03a1..a73c455918 100644 --- a/scene/3d/scenario_fx.h +++ b/scene/3d/scenario_fx.h @@ -51,6 +51,8 @@ public: void set_environment(const Ref<Environment>& p_environment); Ref<Environment> get_environment() const; + String get_configuration_warning() const; + WorldEnvironment(); }; diff --git a/scene/3d/spatial_sample_player.cpp b/scene/3d/spatial_sample_player.cpp index 7114fd4b77..0df921f208 100644 --- a/scene/3d/spatial_sample_player.cpp +++ b/scene/3d/spatial_sample_player.cpp @@ -104,6 +104,7 @@ void SpatialSamplePlayer::set_sample_library(const Ref<SampleLibrary>& p_library library=p_library; _change_notify(); + update_configuration_warning(); } Ref<SampleLibrary> SpatialSamplePlayer::get_sample_library() const { @@ -190,6 +191,16 @@ void SpatialSamplePlayer::stop_all() { } } +String SpatialSamplePlayer::get_configuration_warning() const { + + if (library.is_null()) { + return TTR("A SampleLibrary resource must be created or set in the 'samples' property in order for SpatialSamplePlayer to play sound."); + } + + return String(); +} + + void SpatialSamplePlayer::_bind_methods() { diff --git a/scene/3d/spatial_sample_player.h b/scene/3d/spatial_sample_player.h index 037cdc906a..257f6d0dc3 100644 --- a/scene/3d/spatial_sample_player.h +++ b/scene/3d/spatial_sample_player.h @@ -78,6 +78,7 @@ public: void stop_voice(VoiceID p_voice); void stop_all(); + String get_configuration_warning() const; SpatialSamplePlayer(); ~SpatialSamplePlayer(); diff --git a/scene/audio/sample_player.cpp b/scene/audio/sample_player.cpp index d7605ed1a9..b4a237c60f 100644 --- a/scene/audio/sample_player.cpp +++ b/scene/audio/sample_player.cpp @@ -600,6 +600,14 @@ float SamplePlayer::get_default_reverb() const { return _default.reverb_send; } +String SamplePlayer::get_configuration_warning() const { + + if (library.is_null()) { + return TTR("A SampleLibrary resource must be created or set in the 'samples' property in order for SamplePlayer to play sound."); + } + + return String(); +} void SamplePlayer::_bind_methods() { diff --git a/scene/audio/sample_player.h b/scene/audio/sample_player.h index 1821c671dc..833fac3868 100644 --- a/scene/audio/sample_player.h +++ b/scene/audio/sample_player.h @@ -188,6 +188,8 @@ public: ReverbRoomType get_default_reverb_room() const; float get_default_reverb() const; + String get_configuration_warning() const; + SamplePlayer(); ~SamplePlayer(); }; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index e8097c79a4..09c6a77b42 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -87,10 +87,11 @@ void Label::_notification(int p_what) { Color font_color_shadow = get_color("font_color_shadow"); bool use_outlinde = get_constant("shadow_as_outline"); Point2 shadow_ofs(get_constant("shadow_offset_x"),get_constant("shadow_offset_y")); + int line_spacing = get_constant("line_spacing"); VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(),font.is_valid() && font->is_distance_field_hint()); - int font_h = font->get_height(); + int font_h = font->get_height()+line_spacing; int lines_visible = size.y/font_h; int space_w=font->get_char_size(' ').width; int chars_total=0; @@ -372,6 +373,7 @@ void Label::regenerate_word_cache() { int line_width=0; int space_count=0; int space_width=font->get_char_size(' ').width; + int line_spacing = get_constant("line_spacing"); line_count=1; total_char_cache=0; @@ -486,9 +488,9 @@ void Label::regenerate_word_cache() { if (!autowrap) { minsize.width=width; if (max_lines_visible > 0 && line_count > max_lines_visible) { - minsize.height=font->get_height()*max_lines_visible; + minsize.height=(font->get_height()+line_spacing)*max_lines_visible; } else { - minsize.height=font->get_height()*line_count; + minsize.height=(font->get_height()+line_spacing)*line_count; } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 21dee62b38..14dac454bd 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -41,7 +41,15 @@ void LineEdit::_input_event(InputEvent p_event) { const InputEventMouseButton &b = p_event.mouse_button; - if (b.button_index!=1) + if (b.pressed && b.button_index==BUTTON_RIGHT) { + menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); + menu->set_size(Vector2(1,1)); + menu->popup(); + grab_focus(); + return; + } + + if (b.button_index!=BUTTON_LEFT) break; if (b.pressed) { @@ -143,24 +151,10 @@ void LineEdit::_input_event(InputEvent p_event) { if( k.mod.command && editable) { - int old_cursor_pos = cursor_pos; - text = undo_text; - - Ref<Font> font = get_font("font"); - - cached_width = 0; - for (int i = 0; i<text.length(); i++) - cached_width += font->get_char_size(text[i]).width; + undo(); - if(old_cursor_pos > text.length()) { - set_cursor_pos(text.length()); - } else { - set_cursor_pos(old_cursor_pos); - } } - emit_signal("text_changed",text); - _change_notify("text"); } break; @@ -559,6 +553,28 @@ void LineEdit::paste_text() { } +void LineEdit::undo() { + + int old_cursor_pos = cursor_pos; + text = undo_text; + + Ref<Font> font = get_font("font"); + + cached_width = 0; + for (int i = 0; i<text.length(); i++) + cached_width += font->get_char_size(text[i]).width; + + if(old_cursor_pos > text.length()) { + set_cursor_pos(text.length()); + } else { + set_cursor_pos(old_cursor_pos); + } + + emit_signal("text_changed",text); + _change_notify("text"); + +} + void LineEdit::shift_selection_check_pre(bool p_shift) { if (!selection.old_shift && p_shift) { @@ -669,6 +685,8 @@ void LineEdit::set_text(String p_text) { void LineEdit::clear() { clear_internal(); + emit_signal("text_changed",text); + _change_notify("text"); } String LineEdit::get_text() const { @@ -932,6 +950,39 @@ bool LineEdit::is_text_field() const { return true; } +void LineEdit::menu_option(int p_option) { + + switch(p_option) { + case MENU_CUT: { + cut_text(); + } break; + case MENU_COPY: { + + copy_text(); + } break; + case MENU_PASTE: { + + paste_text(); + } break; + case MENU_CLEAR: { + clear(); + } break; + case MENU_SELECT_ALL: { + select_all(); + } break; + case MENU_UNDO: { + + undo(); + } break; + + } + +} + +PopupMenu *LineEdit::get_menu() const { + return menu; +} + void LineEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align); @@ -952,6 +1003,8 @@ void LineEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_secret","enabled"),&LineEdit::set_secret); ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret); ObjectTypeDB::bind_method(_MD("select","from","to"),&LineEdit::select,DEFVAL(0),DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("menu_option","option"),&LineEdit::menu_option); + ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&LineEdit::get_menu); ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) ); ADD_SIGNAL( MethodInfo("text_entered", PropertyInfo( Variant::STRING, "text" )) ); @@ -961,11 +1014,21 @@ void LineEdit::_bind_methods() { BIND_CONSTANT(ALIGN_RIGHT); BIND_CONSTANT(ALIGN_FILL); - ADD_PROPERTY( PropertyInfo( Variant::STRING, "text" ), _SCS("set_text"),_SCS("get_text") ); + BIND_CONSTANT( MENU_CUT ); + BIND_CONSTANT( MENU_COPY ); + BIND_CONSTANT( MENU_PASTE ); + BIND_CONSTANT( MENU_CLEAR ); + BIND_CONSTANT( MENU_SELECT_ALL ); + BIND_CONSTANT( MENU_UNDO ); + BIND_CONSTANT( MENU_MAX ); + + ADD_PROPERTYNZ( PropertyInfo( Variant::STRING, "text" ), _SCS("set_text"),_SCS("get_text") ); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), _SCS("set_align"), _SCS("get_align")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") ); + ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") ); + ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") ); + ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") ); + + } LineEdit::LineEdit() { @@ -984,6 +1047,20 @@ LineEdit::LineEdit() { set_stop_mouse(true); + menu = memnew( PopupMenu ); + add_child(menu); + menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X); + menu->add_item(TTR("Copy"),MENU_COPY,KEY_MASK_CMD|KEY_C); + menu->add_item(TTR("Paste"),MENU_PASTE,KEY_MASK_CMD|KEY_V); + menu->add_separator(); + menu->add_item(TTR("Select All"),MENU_SELECT_ALL,KEY_MASK_CMD|KEY_A); + menu->add_item(TTR("Clear"),MENU_CLEAR); + menu->add_separator(); + menu->add_item(TTR("Undo"),MENU_UNDO,KEY_MASK_CMD|KEY_Z); + menu->connect("item_pressed",this,"menu_option"); + + + } LineEdit::~LineEdit() { diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 207c6b115b..586a54e950 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -30,6 +30,8 @@ #define LINE_EDIT_H #include "scene/gui/control.h" +#include "scene/gui/popup_menu.h" + /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -45,6 +47,18 @@ public: ALIGN_RIGHT, ALIGN_FILL }; + + enum MenuItems { + MENU_CUT, + MENU_COPY, + MENU_PASTE, + MENU_CLEAR, + MENU_SELECT_ALL, + MENU_UNDO, + MENU_MAX + + }; + private: Align align; @@ -54,6 +68,8 @@ private: String undo_text; String text; + PopupMenu *menu; + int cursor_pos; int window_pos; int max_length; // 0 for no maximum @@ -85,14 +101,12 @@ private: void clear_internal(); void changed_internal(); - void copy_text(); - void cut_text(); - void paste_text(); void _input_event(InputEvent p_event); void _notification(int p_what); + protected: static void _bind_methods(); public: @@ -103,6 +117,8 @@ public: virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; virtual void drop_data(const Point2& p_point,const Variant& p_data); + void menu_option(int p_option); + PopupMenu *get_menu() const; void select_all(); @@ -116,6 +132,10 @@ public: void append_at_cursor(String p_text); void clear(); + void copy_text(); + void cut_text(); + void paste_text(); + void undo(); void set_editable(bool p_editable); bool is_editable() const; @@ -127,7 +147,7 @@ public: virtual Size2 get_minimum_size() const; - virtual bool is_text_field() const; + virtual bool is_text_field() const; LineEdit(); ~LineEdit(); diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 0d9a76937c..8d02d0e4e5 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -44,6 +44,8 @@ void Popup::_notification(int p_what) { notification(NOTIFICATION_POPUP_HIDE); emit_signal("popup_hide"); } + + update_configuration_warning(); } if (p_what==NOTIFICATION_ENTER_TREE) { @@ -282,6 +284,14 @@ Popup::Popup() { hide(); } +String Popup::get_configuration_warning() const { + + if (is_visible()) { + return TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine though, but they will hide upon running."); + } + + return String(); +} Popup::~Popup() { diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 8afcdc01db..dccaf2ae69 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -65,6 +65,7 @@ public: void set_as_minsize(); virtual void popup(); + virtual String get_configuration_warning() const; Popup(); ~Popup(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8df0c6d254..03024daff5 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -56,6 +56,10 @@ static bool _is_number(CharType c) { return (c >= '0' && c <= '9'); } +static bool _is_hex_symbol(CharType c) { + return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); +} + static bool _is_pair_right_symbol(CharType c) { return c == '"' || @@ -673,6 +677,7 @@ void TextEdit::_notification(int p_what) { bool in_word = false; bool in_function_name = false; bool in_member_variable = false; + bool is_hex_notation = false; Color keyword_color; // check if line contains highlighted word @@ -731,20 +736,31 @@ void TextEdit::_notification(int p_what) { in_region=-1; //reset regions that end at end of line } + // allow ABCDEF in hex notation + if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) { + is_number = true; + } else { + is_hex_notation = false; + } + + // check for dot or 'x' for hex notation in floating point number + if ((str[j] == '.' || str[j] == 'x') && !in_word && prev_is_number && !is_number) { + is_number = true; + is_symbol = false; + + if (str[j] == 'x' && str[j-1] == '0') { + is_hex_notation = true; + } + } + if (!in_word && _is_char(str[j])) { in_word = true; } - if (in_keyword || in_word) { + if ((in_keyword || in_word) && !is_hex_notation) { is_number = false; } - // check for dot in floating point number - if (str[j] == '.' && !in_word && prev_is_number) { - is_number = true; - is_symbol = false; - } - if (is_symbol && str[j] != '.' && in_word) { in_word = false; } @@ -1518,6 +1534,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { update(); } + + if (mb.button_index==BUTTON_RIGHT) { + + menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); + menu->set_size(Vector2(1,1)); + menu->popup(); + grab_focus(); + + } } else { if (mb.button_index==BUTTON_LEFT) @@ -4146,6 +4171,38 @@ bool TextEdit::is_text_field() const { return true; } + +void TextEdit::menu_option(int p_option) { + + switch( p_option ) { + case MENU_CUT: { + + cut(); + } break; + case MENU_COPY: { + copy(); + } break; + case MENU_PASTE: { + + paste(); + } break; + case MENU_CLEAR: { + clear(); + } break; + case MENU_SELECT_ALL: { + select_all(); + } break; + case MENU_UNDO: { + undo(); + } break; + + }; +} + +PopupMenu *TextEdit::get_menu() const { + return menu; +} + void TextEdit::_bind_methods() { @@ -4215,6 +4272,8 @@ void TextEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_symbol_color","color"),&TextEdit::set_symbol_color); ObjectTypeDB::bind_method(_MD("set_custom_bg_color","color"),&TextEdit::set_custom_bg_color); ObjectTypeDB::bind_method(_MD("clear_colors"),&TextEdit::clear_colors); + ObjectTypeDB::bind_method(_MD("menu_option"),&TextEdit::menu_option); + ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&TextEdit::get_menu); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret/caret_blink"), _SCS("cursor_set_blink_enabled"), _SCS("cursor_get_blink_enabled"));; ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret/caret_blink_speed",PROPERTY_HINT_RANGE,"0.1,10,0.1"), _SCS("cursor_set_blink_speed"),_SCS("cursor_get_blink_speed") ); @@ -4223,6 +4282,15 @@ void TextEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("text_changed")); ADD_SIGNAL(MethodInfo("request_completion")); + BIND_CONSTANT( MENU_CUT ); + BIND_CONSTANT( MENU_COPY ); + BIND_CONSTANT( MENU_PASTE ); + BIND_CONSTANT( MENU_CLEAR ); + BIND_CONSTANT( MENU_SELECT_ALL ); + BIND_CONSTANT( MENU_UNDO ); + BIND_CONSTANT( MENU_MAX ); + + } TextEdit::TextEdit() { @@ -4327,6 +4395,20 @@ TextEdit::TextEdit() { brace_matching_enabled=false; auto_indent=false; insert_mode = false; + + menu = memnew( PopupMenu ); + add_child(menu); + menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X); + menu->add_item(TTR("Copy"),MENU_COPY,KEY_MASK_CMD|KEY_C); + menu->add_item(TTR("Paste"),MENU_PASTE,KEY_MASK_CMD|KEY_V); + menu->add_separator(); + menu->add_item(TTR("Select All"),MENU_SELECT_ALL,KEY_MASK_CMD|KEY_A); + menu->add_item(TTR("Clear"),MENU_CLEAR); + menu->add_separator(); + menu->add_item(TTR("Undo"),MENU_UNDO,KEY_MASK_CMD|KEY_Z); + menu->connect("item_pressed",this,"menu_option"); + + } TextEdit::~TextEdit() diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index ea4f148e91..dbe6293240 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -31,6 +31,7 @@ #include "scene/gui/control.h" #include "scene/gui/scroll_bar.h" +#include "scene/gui/popup_menu.h" #include "scene/main/timer.h" @@ -290,6 +291,8 @@ class TextEdit : public Control { DVector<int> _search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const; + PopupMenu *menu; + void _clear(); void _cancel_completion(); void _cancel_code_hint(); @@ -317,6 +320,17 @@ protected: public: + enum MenuItems { + MENU_CUT, + MENU_COPY, + MENU_PASTE, + MENU_CLEAR, + MENU_SELECT_ALL, + MENU_UNDO, + MENU_MAX + + }; + enum SearchFlags { SEARCH_MATCH_CASE=1, @@ -433,6 +447,8 @@ public: uint32_t get_saved_version() const; void tag_saved_version(); + void menu_option(int p_option); + void set_show_line_numbers(bool p_show); void set_tooltip_request_func(Object *p_obj, const StringName& p_function, const Variant& p_udata); @@ -442,6 +458,8 @@ public: void set_code_hint(const String& p_hint); void query_code_comple(); + PopupMenu *get_menu() const; + String get_text_for_completion(); virtual bool is_text_field() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index da14fa1111..f261693841 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -749,6 +749,16 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name) { } +void Node::add_child_below_node(Node *p_node, Node *p_child, bool p_legible_unique_name) { + add_child(p_child, p_legible_unique_name); + + if (is_a_parent_of(p_node)) { + move_child(p_child, p_node->get_position_in_parent() + 1); + } else { + WARN_PRINTS("Cannot move under node " + p_node->get_name() + " as " + p_child->get_name() + " does not share a parent") + } +} + void Node::_propagate_validate_owner() { @@ -2010,8 +2020,27 @@ void Node::clear_internal_tree_resource_paths() { } +String Node::get_configuration_warning() const { + + return String(); +} + +void Node::update_configuration_warning() { + +#ifdef TOOLS_ENABLED + if (!is_inside_tree()) + return; + if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root()==this || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) { + get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed,this); + } +#endif + +} + void Node::_bind_methods() { + ObjectTypeDB::bind_method(_MD("_add_child_below_node","node:Node","child_node:Node","legible_unique_name"),&Node::add_child_below_node,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name); ObjectTypeDB::bind_method(_MD("get_name"),&Node::get_name); ObjectTypeDB::bind_method(_MD("add_child","node:Node","legible_unique_name"),&Node::add_child,DEFVAL(false)); @@ -2076,6 +2105,10 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport); ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete); + + + + #ifdef TOOLS_ENABLED ObjectTypeDB::bind_method(_MD("_set_import_path","import_path"),&Node::set_import_path); ObjectTypeDB::bind_method(_MD("_get_import_path"),&Node::get_import_path); diff --git a/scene/main/node.h b/scene/main/node.h index 83086bb0cf..a4683e602f 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -190,6 +190,7 @@ public: void set_name(const String& p_name); void add_child(Node *p_child,bool p_legible_unique_name=false); + void add_child_below_node(Node *p_node, Node *p_child, bool p_legible_unique_name=false); void remove_child(Node *p_child); int get_child_count() const; @@ -316,6 +317,10 @@ public: _FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; } + virtual String get_configuration_warning() const; + + void update_configuration_warning(); + /* CANVAS */ Node(); diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index cc103b5115..b83ad7381e 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -1660,6 +1660,7 @@ void SceneTree::_bind_methods() { ADD_SIGNAL( MethodInfo("tree_changed") ); ADD_SIGNAL( MethodInfo("node_removed",PropertyInfo( Variant::OBJECT, "node") ) ); ADD_SIGNAL( MethodInfo("screen_resized") ); + ADD_SIGNAL( MethodInfo("node_configuration_warning_changed",PropertyInfo( Variant::OBJECT, "node")) ); ADD_SIGNAL( MethodInfo("idle_frame")); ADD_SIGNAL( MethodInfo("fixed_frame")); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 265ee53e58..2a057fc424 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1157,6 +1157,8 @@ void Viewport::set_as_render_target(bool p_enable){ render_target_texture->set_flags(render_target_texture->flags); render_target_texture->emit_changed(); + + update_configuration_warning(); } bool Viewport::is_set_as_render_target() const{ @@ -1839,6 +1841,8 @@ void Viewport::_gui_input_event(InputEvent p_event) { if (gui.mouse_over) gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT); + + _gui_cancel_tooltip(); if (over) over->notification(Control::NOTIFICATION_MOUSE_ENTER); @@ -1847,8 +1851,6 @@ void Viewport::_gui_input_event(InputEvent p_event) { gui.mouse_over=over; - _gui_cancel_tooltip(); - if (gui.drag_preview) { gui.drag_preview->set_pos(mpos); } @@ -2399,6 +2401,18 @@ bool Viewport::is_input_disabled() const { Variant Viewport::gui_get_drag_data() const { return gui.drag_data; } + + +String Viewport::get_configuration_warning() const { + + if (get_parent() && !get_parent()->cast_to<Control>() && !render_target) { + + return TTR("This viewport is not set as render target. If you intend for it to display it's 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 it's internal texture to some node for display."); + } + + return String(); +} + void Viewport::_bind_methods() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 6107cf570f..6ae9e421eb 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -364,6 +364,8 @@ public: Variant gui_get_drag_data() const; + virtual String get_configuration_warning() const; + Viewport(); ~Viewport(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 9feadf91cf..0c4d8ae841 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -417,6 +417,7 @@ void make_default_theme() { t->set_constant("shadow_offset_x","Label", 1 ); t->set_constant("shadow_offset_y","Label", 1 ); t->set_constant("shadow_as_outline","Label", 0 ); + t->set_constant("line_spacing","Label", 3 ); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index ef04c68e8e..5df22ba8cc 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -1493,7 +1493,7 @@ int SceneState::get_connection_flags(int p_idx) const{ Array SceneState::get_connection_binds(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx,connections.size(),-1); + ERR_FAIL_INDEX_V(p_idx,connections.size(),Array()); Array binds; for(int i=0;i<connections[p_idx].binds.size();i++) { binds.push_back(variants[connections[p_idx].binds[i]]); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index af28feb63d..7e8dd41ed9 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -171,6 +171,8 @@ SceneStringNames::SceneStringNames() { blend_times=StaticCString::create("blend_times"); speed=StaticCString::create("speed"); + node_configuration_warning_changed = StaticCString::create("node_configuration_warning_changed"); + path_pp=NodePath(".."); _default=StaticCString::create("default"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index da5e45172b..7143bd539f 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -184,6 +184,8 @@ public: StringName _default; + StringName node_configuration_warning_changed; + }; |