summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite.cpp14
-rw-r--r--scene/2d/animated_sprite.h2
-rw-r--r--scene/2d/canvas_modulate.cpp29
-rw-r--r--scene/2d/canvas_modulate.h2
-rw-r--r--scene/2d/collision_polygon_2d.cpp14
-rw-r--r--scene/2d/collision_polygon_2d.h2
-rw-r--r--scene/2d/collision_shape_2d.cpp13
-rw-r--r--scene/2d/collision_shape_2d.h2
-rw-r--r--scene/2d/light_2d.cpp12
-rw-r--r--scene/2d/light_2d.h2
-rw-r--r--scene/2d/light_occluder_2d.cpp16
-rw-r--r--scene/2d/light_occluder_2d.h2
-rw-r--r--scene/2d/navigation_polygon.cpp23
-rw-r--r--scene/2d/navigation_polygon.h2
-rw-r--r--scene/2d/parallax_layer.cpp10
-rw-r--r--scene/2d/parallax_layer.h1
-rw-r--r--scene/2d/particles_2d.cpp8
-rw-r--r--scene/2d/particles_2d.h2
-rw-r--r--scene/2d/path_2d.cpp13
-rw-r--r--scene/2d/path_2d.h2
-rw-r--r--scene/2d/remote_transform_2d.cpp11
-rw-r--r--scene/2d/remote_transform_2d.h2
-rw-r--r--scene/2d/sample_player_2d.cpp9
-rw-r--r--scene/2d/sample_player_2d.h2
-rw-r--r--scene/2d/sprite.cpp19
-rw-r--r--scene/2d/sprite.h2
-rw-r--r--scene/2d/visibility_notifier_2d.cpp10
-rw-r--r--scene/2d/visibility_notifier_2d.h2
-rw-r--r--scene/3d/body_shape.cpp13
-rw-r--r--scene/3d/body_shape.h3
-rw-r--r--scene/3d/collision_polygon.cpp13
-rw-r--r--scene/3d/collision_polygon.h2
-rw-r--r--scene/3d/navigation_mesh.cpp22
-rw-r--r--scene/3d/navigation_mesh.h2
-rw-r--r--scene/3d/scenario_fx.cpp27
-rw-r--r--scene/3d/scenario_fx.h2
-rw-r--r--scene/3d/spatial_sample_player.cpp11
-rw-r--r--scene/3d/spatial_sample_player.h1
-rw-r--r--scene/audio/sample_player.cpp8
-rw-r--r--scene/audio/sample_player.h2
-rw-r--r--scene/gui/label.cpp8
-rw-r--r--scene/gui/line_edit.cpp117
-rw-r--r--scene/gui/line_edit.h28
-rw-r--r--scene/gui/popup.cpp10
-rw-r--r--scene/gui/popup.h1
-rw-r--r--scene/gui/text_edit.cpp96
-rw-r--r--scene/gui/text_edit.h18
-rw-r--r--scene/main/node.cpp33
-rw-r--r--scene/main/node.h5
-rw-r--r--scene/main/scene_main_loop.cpp1
-rw-r--r--scene/main/viewport.cpp18
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp1
-rw-r--r--scene/resources/packed_scene.cpp2
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h2
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;
+
};