From c195c0df6b36debc870216dd42e49fbda70fa861 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 17 May 2016 18:27:15 -0300 Subject: [PATCH] -Added configuration warning system for nodes -Added a new "add" and "instance" buttons for scene tree -Added a vformat() function to ease translation work --- core/ustring.cpp | 22 ++- core/ustring.h | 11 ++ core/variant.cpp | 44 ++++++ core/variant.h | 2 + scene/2d/animated_sprite.cpp | 12 ++ scene/2d/animated_sprite.h | 2 +- scene/2d/canvas_modulate.cpp | 29 +++- scene/2d/canvas_modulate.h | 2 + scene/2d/collision_polygon_2d.cpp | 14 ++ scene/2d/collision_polygon_2d.h | 2 + scene/2d/collision_shape_2d.cpp | 13 ++ scene/2d/collision_shape_2d.h | 2 + scene/2d/light_2d.cpp | 12 ++ scene/2d/light_2d.h | 2 + scene/2d/light_occluder_2d.cpp | 16 ++ scene/2d/light_occluder_2d.h | 2 + scene/2d/navigation_polygon.cpp | 23 +++ scene/2d/navigation_polygon.h | 2 + scene/2d/parallax_layer.cpp | 10 ++ scene/2d/parallax_layer.h | 1 + scene/2d/particles_2d.cpp | 8 + scene/2d/particles_2d.h | 2 + scene/2d/path_2d.cpp | 13 ++ scene/2d/path_2d.h | 2 + scene/2d/remote_transform_2d.cpp | 11 ++ scene/2d/remote_transform_2d.h | 2 + scene/2d/sample_player_2d.cpp | 9 ++ scene/2d/sample_player_2d.h | 2 + scene/2d/sprite.cpp | 19 +++ scene/2d/sprite.h | 2 + scene/2d/visibility_notifier_2d.cpp | 10 ++ scene/2d/visibility_notifier_2d.h | 2 + scene/3d/body_shape.cpp | 13 ++ scene/3d/body_shape.h | 3 + scene/3d/collision_polygon.cpp | 13 ++ scene/3d/collision_polygon.h | 2 + scene/3d/navigation_mesh.cpp | 22 +++ scene/3d/navigation_mesh.h | 2 + scene/3d/scenario_fx.cpp | 27 +++- scene/3d/scenario_fx.h | 2 + scene/3d/spatial_sample_player.cpp | 11 ++ scene/3d/spatial_sample_player.h | 1 + scene/audio/sample_player.cpp | 8 + scene/audio/sample_player.h | 2 + scene/gui/label.cpp | 8 +- scene/gui/popup.cpp | 10 ++ scene/gui/popup.h | 1 + scene/main/node.cpp | 21 +++ scene/main/node.h | 4 + scene/main/scene_main_loop.cpp | 1 + scene/main/viewport.cpp | 14 ++ scene/main/viewport.h | 2 + .../resources/default_theme/default_theme.cpp | 1 + scene/resources/packed_scene.cpp | 2 +- scene/scene_string_names.cpp | 2 + scene/scene_string_names.h | 2 + tools/editor/editor_settings.cpp | 2 +- tools/editor/icons/icon_instance.png | Bin 446 -> 522 bytes tools/editor/icons/icon_node_warning.png | Bin 0 -> 701 bytes tools/editor/scene_tree_dock.cpp | 145 ++---------------- tools/editor/scene_tree_dock.h | 6 +- tools/editor/scene_tree_editor.cpp | 39 ++++- tools/editor/scene_tree_editor.h | 6 + 63 files changed, 531 insertions(+), 146 deletions(-) create mode 100644 tools/editor/icons/icon_node_warning.png diff --git a/core/ustring.cpp b/core/ustring.cpp index 1f0eadc03fa..c2520a7a86d 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3963,11 +3963,31 @@ String String::sprintf(const Array& values, bool* error) const { #include "translation.h" +#ifdef TOOLS_ENABLED String TTR(const String& p_text) { if (TranslationServer::get_singleton()) { - return TranslationServer::get_singleton()->translate(p_text); + return TranslationServer::get_singleton()->tool_translate(p_text); } return p_text; } + +#endif + +String RTR(const String& p_text) { + + + + if (TranslationServer::get_singleton()) { + String rtr = TranslationServer::get_singleton()->tool_translate(p_text); + if (rtr==String() || rtr==p_text) { + return TranslationServer::get_singleton()->translate(p_text); + } else { + return rtr; + } + } + + return p_text; +} + diff --git a/core/ustring.h b/core/ustring.h index 78c041fb92b..e03f74f5064 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -257,6 +257,17 @@ struct NoCaseComparator { /* end of namespace */ //tool translate +#ifdef TOOLS_ENABLED + String TTR(const String&); +#else + +#define TTR(m_val) (String()) + +#endif + +//tool or regular translate +String RTR(const String&); + #endif diff --git a/core/variant.cpp b/core/variant.cpp index ea5a378ad04..38f5e69cc02 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -3048,3 +3048,47 @@ String Variant::get_call_error_text(Object* p_base, const StringName& p_method,c } return "'"+class_name+"::"+String(p_method)+"': "+err_text; } + + +String vformat(const String& p_text, const Variant& p1,const Variant& p2,const Variant& p3,const Variant& p4,const Variant& p5) { + + Array args; + if (p1.get_type()!=Variant::NIL) { + + args.push_back(p1); + + if (p2.get_type()!=Variant::NIL) { + + args.push_back(p2); + + if (p3.get_type()!=Variant::NIL) { + + args.push_back(p3); + + if (p4.get_type()!=Variant::NIL) { + + args.push_back(p4); + + if (p5.get_type()!=Variant::NIL) { + + args.push_back(p5); + + } + + } + + + } + + } + + } + + bool error=false; + String fmt = p_text.sprintf(args,&error); + + ERR_FAIL_COND_V(error,String()); + + return fmt; + +} diff --git a/core/variant.h b/core/variant.h index ed33de66602..b95223ecfbc 100644 --- a/core/variant.h +++ b/core/variant.h @@ -469,4 +469,6 @@ const Variant::ObjData& Variant::_get_obj() const { return *reinterpret_cast(&_data._mem[0]); } + +String vformat(const String& p_text, const Variant& p1=Variant(),const Variant& p2=Variant(),const Variant& p3=Variant(),const Variant& p4=Variant(),const Variant& p5=Variant()); #endif diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 1d2f912784a..c062a6d1fc8 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -452,6 +452,7 @@ void AnimatedSprite::set_sprite_frames(const Ref &p_frames) { _change_notify(); _reset_timeout(); update(); + update_configuration_warning(); } @@ -486,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 { @@ -646,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 bbf9c7aafb6..968cd9aa30f 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 77203a71104..cc0db2da779 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 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 a6894f29c2d..73f920d5c7d 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 CanvasModulate::get_configuration_warning() const; + CanvasModulate(); ~CanvasModulate(); }; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 2a40a6207df..544f0e2088d 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()) { + 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 b2bd4d189dd..9c0e4e0c015 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 405310450bf..c737cf0faf7 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()) { + 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 b14dad73ba5..6f3f17d412f 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 9715afeaa4f..b79c07360b8 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -61,6 +61,8 @@ void Light2D::set_texture( const Ref& 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 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 ca437769e7a..a8b0ef3b23a 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 d98bed0ea35..ce617b1737f 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 0343e3697e5..ccc2a1cd9c9 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 376aeb2d850..8c0d9cf35f4 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -413,6 +413,7 @@ void NavigationPolygonInstance::set_navigation_polygon(const Refcast_to()) { + return String(); + } + + c=c->get_parent()->cast_to(); + } + + 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 01307a170bb..07fee571f02 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -77,6 +77,8 @@ public: void set_navigation_polygon(const Ref& p_navpoly); Ref 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 7a898e43c9a..bf559deb09a 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()) { + 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 6c24a9b9f75..c2d345da479 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 ffea060e82b..29dad630d63 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()) { + 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 06dcda71654..b1ae1f5bc15 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 bd7415aa041..dee67a829fd 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -237,6 +237,19 @@ void PathFollow2D::_get_property_list( List *p_list) const{ } +String PathFollow2D::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree()) + return String(); + + if (!get_parent() || !get_parent()->cast_to()) { + 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 486a8ac9ac8..84725e71231 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 6dcd980822a..4de648a1dba 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()) { + 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 4a5f5f72ea1..0ea1438f0a6 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 bf091302381..4d719b532b5 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& p_library) { library=p_library; _change_notify(); + update_configuration_warning(); } Ref 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 eddf84f77b5..5ab7f024d37 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 b2902b28672..aebb9a4c289 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()) { + 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(); + 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 cbcaec9aeb9..f789538b1d5 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 426e86fa13a..2a5108c627c 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 { + + 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."); + } + + 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 647a5b6e910..354ccf43456 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 3a47371de38..e62ab394af0 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()) { + 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 dd005c0edd3..a3289bf26a0 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 3b14e1d7670..e05f29714b7 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()) { + 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 9b9afea34f0..3d190a02b3a 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 a238a8ff22d..3adf282f13b 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -329,6 +329,7 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref& p_na nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this); } update_gizmo(); + update_configuration_warning(); } @@ -337,6 +338,27 @@ Ref 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()) + return String(); + + c=c->get_parent()->cast_to(); + } + + 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 1e53b2127a9..cb3b5d95f69 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -78,6 +78,8 @@ public: void set_navigation_mesh(const Ref& p_navmesh); Ref 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 2e22ab36d36..f01c2263fbb 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()); + remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); + + } } } @@ -53,6 +58,7 @@ void WorldEnvironment::set_environment(const Ref& p_environment) { if (is_inside_world() && environment.is_valid() && get_world()->get_environment()==environment) { get_world()->set_environment(Ref()); + remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id())); //clean up } @@ -63,7 +69,11 @@ void WorldEnvironment::set_environment(const Ref& 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 WorldEnvironment::get_environment() const { @@ -71,6 +81,21 @@ Ref WorldEnvironment::get_environment() const { return environment; } +String WorldEnvironment::get_configuration_warning() const { + + if (!is_visible() || !is_inside_tree() || !environment.is_valid()) + return String(); + + List 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 a3c13e03a1d..a73c455918e 100644 --- a/scene/3d/scenario_fx.h +++ b/scene/3d/scenario_fx.h @@ -51,6 +51,8 @@ public: void set_environment(const Ref& p_environment); Ref 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 7114fd4b776..0df921f2087 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& p_library library=p_library; _change_notify(); + update_configuration_warning(); } Ref 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 037cdc906a5..257f6d0dc3a 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 d7605ed1a95..b4a237c60f9 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 1821c671dc0..833fac38688 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 e8097c79a45..09c6a77b42e 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/popup.cpp b/scene/gui/popup.cpp index 0d9a76937c5..8d02d0e4e54 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 8afcdc01db3..dccaf2ae693 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/main/node.cpp b/scene/main/node.cpp index e85b3698c85..f2616938416 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2020,6 +2020,23 @@ 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)); @@ -2088,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 4756909e236..a4683e602fb 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -317,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 cc103b51152..b83ad7381ef 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 265ee53e587..c9f61beba76 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{ @@ -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() && !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 6107cf570f3..6ae9e421eb6 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 9feadf91cf0..0c4d8ae8418 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 ef04c68e8ee..5df22ba8cc0 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 p_extra_config) { set("scenetree_editor/duplicate_node_name_num_separator",0); hints["scenetree_editor/duplicate_node_name_num_separator"]=PropertyInfo(Variant::INT,"scenetree_editor/duplicate_node_name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"); - set("scenetree_editor/display_old_action_buttons",false); + //set("scenetree_editor/display_old_action_buttons",false); set("gridmap_editor/pick_distance", 5000.0); diff --git a/tools/editor/icons/icon_instance.png b/tools/editor/icons/icon_instance.png index 82d8d41812e45c8ccf83577b28f3d48849d737a8..6ad9f38e53604cc8e94f43b58677ab919954d2d4 100644 GIT binary patch delta 470 zcmV;{0V)2z1BwKYBo78+OGiWi{{Zd)GFXhz*^xjVf8YfX6#)SGBVKX<0013nR9JLF zZ*6U5Zgc_CX>@2HM@dakWG-a~0004QNkl6bA6$ z|N68cC{SFSOowV~Pzi;EbO}p{wg@W-rzUGKbaQl&99)z@MTjyX8j6ONhKQ)Zrb6&R z5C{sAe@Kbtb2(2Q&*#GfmwPze^PO|P@7ye(&pW2oA;T{AiosMRAuI8(V-tTdUiu~- zqw-BG;U_*}2(wY3a1=ld3b=&@d_)&IFpU9BLRNu;6f-v93+iz?Vm0`W_c(`Zschz4 z$?PX0X$-f~7|G3O!XK=qGQ$4FBlv~8IFBbmf8bd>M++WewFpp%GluVY8kKr+2ahm^ zw`ju+JS&%R8lz~%2Ry(C2Jt33*~FDla}pPDs@ldTyub#A(HFbkj>jS86n3fstm7hn;}vG` zJQ`=v6NIV;kYNSg_#8ZJgoN+PKGh-1h5iXYg1Afg8jF-lziuVl2j~%1GD+}VhX4Qo M07*qoM6N<$g2@EL+5i9m delta 420 zcmV;V0bBlx1ik~1B!2;OQb$4nuFf3k00006VoOIv02%=G01}g>^e+Ga010qNS#tmY z3ljhU3ljkVnw%H_000McNliru+6oR56(%nP?u-Bc0X|7YK~y-)eUm*-!$1&)zgg^< zV^9Pk4iE|i;s{)Vnud;o5>e7~2{-~GLJ=1Lp_~Fxz<>KF)_-d#r-utj~e*tb|?3WMC++6RUSQE@YEZ_<|J`mo6AMn0@TGWDJbR-z~efauq zDq848*N=6cP_VEia5Rng?QLm80b*yNjj6fDV#)9$V;ya?ecmiGjQs=H8=q#qgND`s O0000WFU8GbZ8()Nlj2>E@cM*00JRNL_t(I%XO1IXcR#d z$A52j_i`8S5-uhxA_)--UAychR%sM0>_ren5mJb@DS~2Q5KBQz3sDd&!Ah{T6WPL$ ztoV@+zY9f3FuBXk?LLdlUM?4W!!U2&$AA9s%?xx&wh*C7lcb7_q824ekahzS}K6*Vr}yC zQsc_Cw^Rv@Vaol+ibHoAvZRrzerPwWwbw9?wi2P{0Bk4{nX9{y1^J@iy|i zOE8^S0L_-3Mz~Pz_pM`Cs+2uTORsrGCjcbe?uU^uMw1A)4tm0MJYnB}-v%G-_XWTh znbjmJl6xx+VNfr1p&nZ0dPaY__ijI z#20?AnhKnu93NpuLn(cDvbaSWaS=ej@2 z%J(LPKsdNRaIa*CJd`lLEFG_~0+gLowuT6(pcs_A5gxDx`~pget_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); } - static const char* button_names[TOOL_BUTTON_MAX]={ - "New", - "Add", - "Replace", - "Connect", - "Groups", - "Script", - "MoveUp", - "MoveDown", - "Duplicate", - "Reparent", - "CreateNewSceneFrom", - "MultiNodeEdit", - "Remove", - }; - - - - for(int i=0;iset_icon(get_icon(button_names[i],"EditorIcons")); + button_add->set_icon(get_icon("Add","EditorIcons")); + button_instance->set_icon(get_icon("Instance","EditorIcons")); filter_icon->set_texture(get_icon("Zoom","EditorIcons")); @@ -1246,35 +1228,13 @@ void SceneTreeDock::_delete_confirm() { } editor_data->get_undo_redo().commit_action(); - _update_tool_buttons(); - -} - -void SceneTreeDock::_update_tool_buttons() { - - Node *sel = scene_tree->get_selected(); - bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene); - disable = disable || (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0); - bool disable_root = disable || sel->get_parent()==scene_root; - bool disable_edit = !sel; - - tool_buttons[TOOL_INSTANCE]->set_disabled(disable_edit); - tool_buttons[TOOL_REPLACE]->set_disabled(disable); - tool_buttons[TOOL_CONNECT]->set_disabled(disable_edit); - tool_buttons[TOOL_GROUP]->set_disabled(disable_edit); - tool_buttons[TOOL_SCRIPT]->set_disabled(disable_edit); - tool_buttons[TOOL_MOVE_UP]->set_disabled(disable_root); - tool_buttons[TOOL_MOVE_DOWN]->set_disabled(disable_root); - tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root); - tool_buttons[TOOL_REPARENT]->set_disabled(disable_root); - tool_buttons[TOOL_ERASE]->set_disabled(disable); - tool_buttons[TOOL_NEW_SCENE_FROM]->set_disabled(disable_root); - tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2); } + + void SceneTreeDock::_selection_changed() { if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size()>1) { @@ -1415,7 +1375,7 @@ void SceneTreeDock::_create() { memdelete(n); - _update_tool_buttons(); + } @@ -1430,7 +1390,7 @@ void SceneTreeDock::set_edited_scene(Node* p_scene) { void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected ) { scene_tree->set_selected(p_node,p_emit_selected); - _update_tool_buttons(); + } void SceneTreeDock::import_subscene() { @@ -1803,50 +1763,23 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec VBoxContainer *vbc = this; - HBoxContainer *hbc_top = memnew( HBoxContainer ); - vbc->add_child(hbc_top); - + HBoxContainer *filter_hbc = memnew( HBoxContainer ); ToolButton *tb; tb = memnew( ToolButton ); tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW, false)); tb->set_tooltip("Add/Create a New Node\n("+keycode_get_string(KEY_MASK_CMD|KEY_A)+")"); - hbc_top->add_child(tb); - tool_buttons[TOOL_NEW]=tb; + filter_hbc->add_child(tb); + button_add=tb; tb = memnew( ToolButton ); tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false)); - tb->set_tooltip(TTR("Instance a scene file as a Node.")); - hbc_top->add_child(tb); - tool_buttons[TOOL_INSTANCE]=tb; + tb->set_tooltip(TTR("Instance a scene file as a Node. Creates an inherited scene if no root node exists.")); + filter_hbc->add_child(tb); + button_instance=tb; - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_REPLACE, false)); - tb->set_tooltip(TTR("Replace a Node by Another Node Type")); - hbc_top->add_child(tb); - tool_buttons[TOOL_REPLACE]=tb; - hbc_top->add_spacer(); - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_CONNECT, false)); - tb->set_tooltip(TTR("Edit the Node Connections")); - hbc_top->add_child(tb); - tool_buttons[TOOL_CONNECT]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_GROUP, false)); - tb->set_tooltip(TTR("Edit the Node Groups")); - hbc_top->add_child(tb); - tool_buttons[TOOL_GROUP]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_SCRIPT, false)); - tb->set_tooltip(TTR("Edit/Create the Node Script")); - hbc_top->add_child(tb); - tool_buttons[TOOL_SCRIPT]=tb; - - HBoxContainer *filter_hbc = memnew( HBoxContainer ); vbc->add_child(filter_hbc); filter = memnew( LineEdit ); filter->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1875,54 +1808,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec scene_tree->set_editor_selection(editor_selection); - HBoxContainer *hbc_bottom = memnew( HBoxContainer ); - vbc->add_child(hbc_bottom); - hbc_bottom->add_constant_override("separation", 0); - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MOVE_UP, false)); - tb->set_tooltip("Move Node Up\n("+keycode_get_string(KEY_MASK_CMD|KEY_UP)+")"); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_MOVE_UP]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MOVE_DOWN, false)); - tb->set_tooltip("Move Node Down\n("+keycode_get_string(KEY_MASK_CMD|KEY_DOWN)+")"); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_MOVE_DOWN]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_DUPLICATE, false)); - tb->set_tooltip("Duplicate Selected Node(s)\n("+keycode_get_string(KEY_MASK_CMD|KEY_D)+")"); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_DUPLICATE]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_REPARENT, false)); - tb->set_tooltip(TTR("Reparent Selected Node(s)")); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_REPARENT]=tb; - - hbc_bottom->add_spacer(); - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW_SCENE_FROM, false)); - tb->set_tooltip(TTR("Create New Scene From Node(s)")); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_NEW_SCENE_FROM]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MULTI_EDIT, false)); - tb->set_tooltip(TTR("Multi-Edit Selected Nodes")); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_MULTI_EDIT]=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_ERASE, false)); - tb->set_tooltip(TTR("Erase Selected Node(s)")); - hbc_bottom->add_child(tb); - tool_buttons[TOOL_ERASE]=tb; - create_dialog = memnew( CreateDialog ); create_dialog->set_base_type("Node"); add_child(create_dialog); @@ -1971,12 +1856,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec menu->connect("item_pressed",this,"_tool_selected"); first_enter=true; - if (!EditorSettings::get_singleton()->get("scenetree_editor/display_old_action_buttons")) { - for(int i=0;ihide(); - } - } - vbc->add_constant_override("separation",4); } diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index d917cae64fa..0894dc8ffaf 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -74,7 +74,9 @@ class SceneTreeDock : public VBoxContainer { int current_option; CreateDialog *create_dialog; - ToolButton *tool_buttons[TOOL_BUTTON_MAX]; + ToolButton *button_add; + ToolButton *button_instance; + SceneTreeEditor *scene_tree; HBoxContainer *tool_hbc; @@ -121,7 +123,7 @@ class SceneTreeDock : public VBoxContainer { void _script_created(Ref