Refactor node naming APIs used by editor
Make 'name_num_separator' a project setting Make all node operations separator-aware
This commit is contained in:
parent
88a32c11f1
commit
9b2e2935d0
4 changed files with 81 additions and 128 deletions
|
@ -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;
|
||||
p_child->data.name=_generate_serial_child_name(p_child);
|
||||
|
||||
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=attempted;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
//this approach to autoset node names is fast but not as readable
|
||||
|
@ -1373,6 +1301,54 @@ 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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int num=nums.to_int();
|
||||
if (num<1)
|
||||
num=1;
|
||||
|
||||
String nnsep=_get_name_num_separator();
|
||||
name = name.substr(0,name.length()-nums.length()).strip_edges();
|
||||
if ( name.substr(name.length()-nnsep.length(),nnsep.length()) == nnsep) {
|
||||
name = name.substr(0,name.length()-nnsep.length());
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
String attempt = (name + (num > 1 ? 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 {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
|
||||
//add a child node quickly, without name validation
|
||||
|
||||
|
@ -2811,6 +2787,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 +2959,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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -565,8 +565,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
set("text_editor/restore_scripts_on_load",true);
|
||||
|
||||
|
||||
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/start_create_dialog_fully_expanded",false);
|
||||
set("scenetree_editor/draw_relationship_lines",false);
|
||||
|
|
|
@ -227,7 +227,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node*
|
|||
editor_data->get_undo_redo().add_do_reference(instanced_scene);
|
||||
editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene);
|
||||
|
||||
String new_name = parent->validate_child_name(instanced_scene->get_name());
|
||||
String new_name = parent->validate_child_name(instanced_scene);
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_files[i],new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));
|
||||
|
@ -257,17 +257,6 @@ bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_pat
|
|||
}
|
||||
|
||||
|
||||
static String _get_name_num_separator() {
|
||||
switch(EditorSettings::get_singleton()->get("scenetree_editor/duplicate_node_name_num_separator").operator int()) {
|
||||
case 0: return "";
|
||||
case 1: return " ";
|
||||
case 2: return "_";
|
||||
case 3: return "-";
|
||||
}
|
||||
return " ";
|
||||
}
|
||||
|
||||
|
||||
void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
||||
|
||||
current_option=p_tool;
|
||||
|
@ -474,37 +463,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
if (selection.size()==1)
|
||||
dupsingle=dup;
|
||||
|
||||
String name = node->get_name();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int num=nums.to_int();
|
||||
if (num<1)
|
||||
num=1;
|
||||
else
|
||||
num++;
|
||||
|
||||
String nnsep = _get_name_num_separator();
|
||||
name = name.substr(0,name.length()-nums.length()).strip_edges();
|
||||
if ( name.substr(name.length()-nnsep.length(),nnsep.length()) == nnsep) {
|
||||
name = name.substr(0,name.length()-nnsep.length());
|
||||
}
|
||||
String attempt = (name + nnsep + itos(num)).strip_edges();
|
||||
|
||||
while(parent->has_node(attempt)) {
|
||||
num++;
|
||||
attempt = (name + nnsep + itos(num)).strip_edges();
|
||||
}
|
||||
|
||||
dup->set_name(attempt);
|
||||
dup->set_name(parent->validate_child_name(dup));
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(parent,"_add_child_below_node",node, dup);
|
||||
for (List<Node*>::Element *F=owned.front();F;F=F->next()) {
|
||||
|
@ -522,8 +481,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),attempt);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+attempt));
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),dup->get_name());
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+dup->get_name()));
|
||||
|
||||
//parent->add_child(dup);
|
||||
//reselect.push_back(dup);
|
||||
|
@ -1142,7 +1101,7 @@ void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vec
|
|||
editor_data->get_undo_redo().add_do_method(new_parent,"move_child",node,p_position_in_parent+inc);
|
||||
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
String new_name = new_parent->validate_child_name(node->get_name());
|
||||
String new_name = new_parent->validate_child_name(node);
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index());
|
||||
|
||||
|
@ -1363,7 +1322,7 @@ void SceneTreeDock::_create() {
|
|||
editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child);
|
||||
|
||||
|
||||
String new_name = parent->validate_child_name(child->get_type());
|
||||
String new_name = parent->validate_child_name(child);
|
||||
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
|
||||
editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_type(),new_name);
|
||||
editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));
|
||||
|
|
Loading…
Reference in a new issue