-Added configuration warning system for nodes
-Added a new "add" and "instance" buttons for scene tree -Added a vformat() function to ease translation work
This commit is contained in:
parent
3a26e14a2b
commit
c195c0df6b
63 changed files with 531 additions and 146 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -469,4 +469,6 @@ const Variant::ObjData& Variant::_get_obj() const {
|
|||
return *reinterpret_cast<const ObjData*>(&_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
|
||||
|
|
|
@ -452,6 +452,7 @@ void AnimatedSprite::set_sprite_frames(const Ref<SpriteFrames> &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() {
|
||||
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ public:
|
|||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
AnimatedSprite();
|
||||
};
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@ public:
|
|||
void set_color(const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
String CanvasModulate::get_configuration_warning() const;
|
||||
|
||||
CanvasModulate();
|
||||
~CanvasModulate();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
|
||||
int get_collision_object_shape_index() const { return _get_update_shape_index(); }
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
CollisionShape2D();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
||||
|
|
|
@ -104,6 +104,8 @@ public:
|
|||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
Light2D();
|
||||
~Light2D();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
void set_particles_path(NodePath p_path);
|
||||
NodePath get_particles_path() const;
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
ParticleAttractor2D();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -109,6 +109,8 @@ public:
|
|||
void set_cubic_interpolation(bool p_enable);
|
||||
bool get_cubic_interpolation() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
PathFollow2D();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ public:
|
|||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
ViewportSprite();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -90,6 +90,9 @@ public:
|
|||
|
||||
int get_collision_object_shape_index() const { return _get_update_shape_index(); }
|
||||
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
CollisionShape();
|
||||
~CollisionShape();
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
void set_environment(const Ref<Environment>& p_environment);
|
||||
Ref<Environment> get_environment() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
WorldEnvironment();
|
||||
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ public:
|
|||
void stop_voice(VoiceID p_voice);
|
||||
void stop_all();
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
SpatialSamplePlayer();
|
||||
~SpatialSamplePlayer();
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -188,6 +188,8 @@ public:
|
|||
ReverbRoomType get_default_reverb_room() const;
|
||||
float get_default_reverb() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
SamplePlayer();
|
||||
~SamplePlayer();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
void set_as_minsize();
|
||||
virtual void popup();
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
Popup();
|
||||
~Popup();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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<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() {
|
||||
|
||||
|
||||
|
|
|
@ -364,6 +364,8 @@ public:
|
|||
|
||||
Variant gui_get_drag_data() const;
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
Viewport();
|
||||
~Viewport();
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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]]);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -184,6 +184,8 @@ public:
|
|||
|
||||
StringName _default;
|
||||
|
||||
StringName node_configuration_warning_changed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> 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);
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 522 B |
BIN
tools/editor/icons/icon_node_warning.png
Normal file
BIN
tools/editor/icons/icon_node_warning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 701 B |
|
@ -612,26 +612,8 @@ void SceneTreeDock::_notification(int p_what) {
|
|||
canvas_item_plugin->get_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;i<TOOL_BUTTON_MAX;i++)
|
||||
tool_buttons[i]->set_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;i<TOOL_BUTTON_MAX;i++) {
|
||||
tool_buttons[i]->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vbc->add_constant_override("separation",4);
|
||||
}
|
||||
|
|
|
@ -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<Script> p_script);
|
||||
|
||||
void _delete_confirm();
|
||||
void _update_tool_buttons();
|
||||
|
||||
|
||||
void _node_prerenamed(Node* p_node, const String& p_new_name);
|
||||
|
||||
|
|
|
@ -207,6 +207,15 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
|
|||
_update_tree();
|
||||
emit_signal("node_changed");
|
||||
}
|
||||
} else if (p_id==BUTTON_WARNING) {
|
||||
|
||||
String config_err = n->get_configuration_warning();
|
||||
if (config_err==String())
|
||||
return;
|
||||
config_err=config_err.world_wrap(80);
|
||||
warning->set_text(config_err);
|
||||
warning->popup_centered_minsize();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,6 +285,12 @@ bool SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
|||
}
|
||||
}
|
||||
|
||||
String warning = p_node->get_configuration_warning();
|
||||
|
||||
if (warning!=String()) {
|
||||
item->add_button(0,get_icon("NodeWarning","EditorIcons"),BUTTON_WARNING);
|
||||
}
|
||||
|
||||
if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
|
||||
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
|
||||
item->set_tooltip(0,TTR("Inherits: ")+p_node->get_scene_inherited_state()->get_path()+"\nType: "+p_node->get_type());
|
||||
|
@ -558,6 +573,8 @@ void SceneTreeEditor::_notification(int p_what) {
|
|||
|
||||
get_tree()->connect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->connect("node_removed",this,"_node_removed");
|
||||
get_tree()->connect("node_configuration_warning_changed",this,"_warning_changed");
|
||||
|
||||
instance_menu->set_item_icon(3,get_icon("Load","EditorIcons"));
|
||||
tree->connect("item_collapsed",this,"_cell_collapsed");
|
||||
inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
|
@ -574,6 +591,7 @@ void SceneTreeEditor::_notification(int p_what) {
|
|||
get_tree()->disconnect("node_removed",this,"_node_removed");
|
||||
tree->disconnect("item_collapsed",this,"_cell_collapsed");
|
||||
clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option");
|
||||
get_tree()->disconnect("node_configuration_warning_changed",this,"_warning_changed");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -666,7 +684,7 @@ void SceneTreeEditor::_renamed() {
|
|||
String new_name=which->get_text(0);
|
||||
if (new_name.find(".") != -1 || new_name.find("/") != -1) {
|
||||
|
||||
error->set_text("Invalid node name, the following characters are not allowed:\n \".\", \"/\"");
|
||||
error->set_text(TTR("Invalid node name, the following characters are not allowed:\n \".\", \"/\""));
|
||||
error->popup_centered_minsize();
|
||||
new_name=n->get_name();
|
||||
}
|
||||
|
@ -949,6 +967,13 @@ void SceneTreeEditor::_rmb_select(const Vector2& p_pos) {
|
|||
}
|
||||
|
||||
|
||||
void SceneTreeEditor::_warning_changed(Node* p_for_node) {
|
||||
|
||||
//should use a timer
|
||||
update_timer->start();
|
||||
// print_line("WARNING CHANGED "+String(p_for_node->get_name()));
|
||||
|
||||
}
|
||||
|
||||
void SceneTreeEditor::_bind_methods() {
|
||||
|
||||
|
@ -965,6 +990,7 @@ void SceneTreeEditor::_bind_methods() {
|
|||
ObjectTypeDB::bind_method("_cell_collapsed",&SceneTreeEditor::_cell_collapsed);
|
||||
ObjectTypeDB::bind_method("_subscene_option",&SceneTreeEditor::_subscene_option);
|
||||
ObjectTypeDB::bind_method("_rmb_select",&SceneTreeEditor::_rmb_select);
|
||||
ObjectTypeDB::bind_method("_warning_changed",&SceneTreeEditor::_warning_changed);
|
||||
|
||||
ObjectTypeDB::bind_method("_node_script_changed",&SceneTreeEditor::_node_script_changed);
|
||||
ObjectTypeDB::bind_method("_node_visibility_changed",&SceneTreeEditor::_node_visibility_changed);
|
||||
|
@ -973,6 +999,7 @@ void SceneTreeEditor::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &SceneTreeEditor::can_drop_data_fw);
|
||||
ObjectTypeDB::bind_method(_MD("drop_data_fw"), &SceneTreeEditor::drop_data_fw);
|
||||
|
||||
|
||||
ADD_SIGNAL( MethodInfo("node_selected") );
|
||||
ADD_SIGNAL( MethodInfo("node_renamed") );
|
||||
ADD_SIGNAL( MethodInfo("node_prerename") );
|
||||
|
@ -1034,6 +1061,11 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
|
|||
error = memnew( AcceptDialog );
|
||||
add_child(error);
|
||||
|
||||
warning = memnew( AcceptDialog );
|
||||
add_child(warning);
|
||||
warning->set_title("Node Configuration Warning!");
|
||||
|
||||
|
||||
show_enabled_subscene=false;
|
||||
|
||||
last_hash=0;
|
||||
|
@ -1062,6 +1094,11 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
|
|||
clear_inherit_confirm->get_ok()->set_text(TTR("Clear!"));
|
||||
add_child(clear_inherit_confirm);
|
||||
|
||||
update_timer = memnew(Timer);
|
||||
update_timer->connect("timeout",this,"_update_tree");
|
||||
update_timer->set_one_shot(true);
|
||||
update_timer->set_wait_time(0.5);
|
||||
add_child(update_timer);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ class SceneTreeEditor : public Control {
|
|||
BUTTON_SCRIPT=2,
|
||||
BUTTON_LOCK=3,
|
||||
BUTTON_GROUP=4,
|
||||
BUTTON_WARNING=5
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -69,6 +70,7 @@ class SceneTreeEditor : public Control {
|
|||
String filter;
|
||||
|
||||
AcceptDialog *error;
|
||||
AcceptDialog *warning;
|
||||
ConfirmationDialog *clear_inherit_confirm;
|
||||
|
||||
int blocked;
|
||||
|
@ -124,6 +126,10 @@ class SceneTreeEditor : public Control {
|
|||
|
||||
void _rmb_select(const Vector2& p_pos);
|
||||
|
||||
void _warning_changed(Node* p_for_node);
|
||||
|
||||
Timer* update_timer;
|
||||
|
||||
public:
|
||||
|
||||
void set_filter(const String& p_filter);
|
||||
|
|
Loading…
Reference in a new issue