summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/node.cpp158
-rw-r--r--scene/main/node.h9
-rw-r--r--scene/main/viewport.cpp3
3 files changed, 91 insertions, 79 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 1892240426..6e33dcb4c9 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1249,51 +1249,12 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) {
}
+#ifdef TOOLS_ENABLED
+String Node::validate_child_name(Node* p_child) {
-String Node::validate_child_name(const String& p_name) const {
-
- //this approach to autoset node names is human readable but very slow
- //it's turned on while running in the editor
-
- String basename = p_name;
-
- if (basename==String()) {
-
- return String();
- }
-
- int val=1;
-
- for(;;) {
-
- String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
-
- bool found=false;
-
- for (int i=0;i<data.children.size();i++) {
-
- //if (data.children[i]==p_child)
- // continue;
- if (data.children[i]->get_name() == attempted) {
- found=true;
- break;
- }
-
- }
-
- if (found) {
-
- val++;
- continue;
- }
-
- return attempted;
- break;
- }
-
- return basename;
-
+ return _generate_serial_child_name(p_child);
}
+#endif
void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
@@ -1304,41 +1265,8 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
//this approach to autoset node names is human readable but very slow
//it's turned on while running in the editor
- String basename = p_child->data.name;
-
- if (basename=="") {
-
- basename = p_child->get_type();
- }
-
- int val=1;
-
- for(;;) {
-
- String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
-
- bool found=false;
-
- for (int i=0;i<data.children.size();i++) {
-
- if (data.children[i]==p_child)
- continue;
- if (data.children[i]->get_name() == attempted) {
- found=true;
- break;
- }
-
- }
-
- if (found) {
-
- val++;
- continue;
- }
+ p_child->data.name=_generate_serial_child_name(p_child);
- p_child->data.name=attempted;
- break;
- }
} else {
//this approach to autoset node names is fast but not as readable
@@ -1373,6 +1301,67 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
}
}
+String Node::_generate_serial_child_name(Node *p_child) {
+
+ String name = p_child->data.name;
+
+ if (name=="") {
+
+ name = p_child->get_type();
+ }
+
+ // Extract trailing number
+ String nums;
+ for(int i=name.length()-1;i>=0;i--) {
+ CharType n=name[i];
+ if (n>='0' && n<='9') {
+ nums=String::chr(name[i])+nums;
+ } else {
+ break;
+ }
+ }
+
+ String nnsep=_get_name_num_separator();
+ int num=0;
+ bool explicit_zero=false;
+ if (nums.length()>0 && name.substr(name.length()-nnsep.length()-nums.length(),nnsep.length()) == nnsep) {
+ // Base name + Separator + Number
+ num=nums.to_int();
+ name=name.substr(0,name.length()-nnsep.length()-nums.length()); // Keep base name
+ if (num==0) {
+ explicit_zero=true;
+ }
+ }
+
+ for(;;) {
+ String attempt = (name + (num > 0 || explicit_zero ? nnsep + itos(num) : "")).strip_edges();
+ bool found=false;
+ for(int i=0;i<data.children.size();i++) {
+ if (data.children[i]==p_child)
+ continue;
+ if (data.children[i]->data.name==attempt) {
+ found=true;
+ break;
+ }
+ }
+ if (!found) {
+ return attempt;
+ } else {
+ if (num==0) {
+ if (explicit_zero) {
+ // Name ended in separator + 0; user expects to get to separator + 1
+ num=1;
+ } else {
+ // Name was undecorated so skip to 2 for a more natural result
+ num=2;
+ }
+ } else {
+ num++;
+ }
+ }
+ }
+}
+
void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
//add a child node quickly, without name validation
@@ -2811,6 +2800,10 @@ bool Node::is_displayed_folded() const {
void Node::_bind_methods() {
+ _GLOBAL_DEF("node/name_num_separator",0);
+ Globals::get_singleton()->set_custom_property_info("node/name_num_separator",PropertyInfo(Variant::INT,"node/name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
+
+
ObjectTypeDB::bind_method(_MD("_add_child_below_node","node:Node","child_node:Node","legible_unique_name"),&Node::add_child_below_node,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name);
@@ -2979,6 +2972,17 @@ void Node::_bind_methods() {
}
+String Node::_get_name_num_separator() {
+ switch(Globals::get_singleton()->get("node/name_num_separator").operator int()) {
+ case 0: return "";
+ case 1: return " ";
+ case 2: return "_";
+ case 3: return "-";
+ }
+ return " ";
+}
+
+
Node::Node() {
data.pos=-1;
diff --git a/scene/main/node.h b/scene/main/node.h
index 3568da2ab0..f18dc81195 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -29,6 +29,7 @@
#ifndef NODE_H
#define NODE_H
+#include "globals.h"
#include "object.h"
#include "path_db.h"
#include "map.h"
@@ -150,7 +151,8 @@ private:
void _replace_connections_target(Node* p_new_target);
- void _validate_child_name(Node *p_name, bool p_force_human_readable=false);
+ void _validate_child_name(Node *p_child, bool p_force_human_readable=false);
+ String _generate_serial_child_name(Node *p_child);
void _propagate_reverse_notification(int p_notification);
void _propagate_deferred_notification(int p_notification, bool p_reverse);
@@ -193,6 +195,7 @@ protected:
void _propagate_replace_owner(Node *p_owner,Node* p_by_owner);
static void _bind_methods();
+ static String _get_name_num_separator();
friend class SceneState;
@@ -335,7 +338,9 @@ public:
static void print_stray_nodes();
- String validate_child_name(const String& p_name) const;
+#ifdef TOOLS_ENABLED
+ String validate_child_name(Node* p_child);
+#endif
void queue_delete();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index b22d1fcdf4..0c243bd473 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1715,6 +1715,9 @@ Control* Viewport::_gui_find_control_at_pos(CanvasItem* p_node,const Point2& p_g
}
Matrix32 matrix = p_xform * p_node->get_transform();
+ // matrix.basis_determinant() == 0.0f implies that node does not exist on scene
+ if(matrix.basis_determinant() == 0.0f)
+ return NULL;
if (!c || !c->clips_input() || c->has_point(matrix.affine_inverse().xform(p_global))) {