Skip to content

Commit 9d00a77

Browse files
committed
Allow prefixing with '%' to set a node as unique in the Scene Tree Dock
1 parent 8c6dbff commit 9d00a77

File tree

1 file changed

+61
-4
lines changed

1 file changed

+61
-4
lines changed

editor/gui/scene_tree_editor.cpp

+61-4
Original file line numberDiff line numberDiff line change
@@ -1439,9 +1439,32 @@ void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *
14391439
item = _find(tree->get_root(), p_node->get_path());
14401440
}
14411441
ERR_FAIL_NULL(item);
1442-
String new_name = p_name.validate_node_name();
1442+
bool check_for_unique_name_token = !p_name.is_empty() && p_name[0] == '%';
1443+
String substr_name = p_name;
14431444

1444-
if (new_name != p_name) {
1445+
if (check_for_unique_name_token) {
1446+
substr_name = p_name.substr(1);
1447+
1448+
// No need to do anything else with this if already unique.
1449+
if (p_node->is_unique_name_in_owner()) {
1450+
check_for_unique_name_token = false;
1451+
// Do not set scene root as unique.
1452+
} else if (get_tree()->get_edited_scene_root() == p_node) {
1453+
check_for_unique_name_token = false;
1454+
String text = TTR("Root nodes cannot be accessed as unique names in their own scene. Instantiate in another scene and set as unique name there.");
1455+
if (error->is_visible()) {
1456+
error->set_text(error->get_text() + "\n\n" + text);
1457+
} else {
1458+
error->set_text(text);
1459+
error->popup_centered();
1460+
}
1461+
}
1462+
}
1463+
1464+
String new_name = substr_name.validate_node_name();
1465+
1466+
// If p_name only has "%" at the beginning and no other invalid characters, do not error.
1467+
if (new_name != substr_name) {
14451468
String text = TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::get_invalid_node_name_characters();
14461469
if (error->is_visible()) {
14471470
if (!error->get_meta("invalid_character", false)) {
@@ -1482,12 +1505,16 @@ void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *
14821505
new_name = p_node->get_parent()->prevalidate_child_name(p_node, new_name);
14831506
if (new_name == p_node->get_name()) {
14841507
item->set_text(0, new_name);
1485-
return;
1508+
// If setting name as unique, check for existing unique node below first.
1509+
if (!check_for_unique_name_token) {
1510+
return;
1511+
}
14861512
}
14871513

14881514
// We previously made sure name is not the same as current name
14891515
// so that it won't complain about already used unique name when not changing name.
1490-
if (p_node->is_unique_name_in_owner() && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name)) {
1516+
if ((check_for_unique_name_token || p_node->is_unique_name_in_owner()) && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name)) {
1517+
check_for_unique_name_token = false;
14911518
String text = vformat(TTR("A node with the unique name %s already exists in this scene."), new_name);
14921519
if (error->is_visible()) {
14931520
if (!error->get_meta("same_unique_name", false)) {
@@ -1501,17 +1528,43 @@ void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *
15011528
error->popup_centered();
15021529
}
15031530
item->set_text(0, p_node->get_name());
1531+
if (p_node->is_unique_name_in_owner()) {
1532+
return;
1533+
}
1534+
}
1535+
1536+
// If same name and check_for_unique_name_token is still true, now set as unique.
1537+
// This is separate from final action so "Rename Node" is not added to undo history.
1538+
if (new_name == p_node->get_name()) {
1539+
if (check_for_unique_name_token) {
1540+
if (!is_scene_tree_dock) {
1541+
p_node->set_unique_name_in_owner(true);
1542+
} else {
1543+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
1544+
undo_redo->create_action(TTR("Enable Scene Unique Name(s)"));
1545+
undo_redo->add_undo_method(p_node, "set_unique_name_in_owner", false);
1546+
undo_redo->add_do_method(p_node, "set_unique_name_in_owner", true);
1547+
undo_redo->commit_action();
1548+
}
1549+
}
15041550
return;
15051551
}
15061552

15071553
if (!is_scene_tree_dock) {
15081554
p_node->set_name(new_name);
1555+
if (check_for_unique_name_token) {
1556+
p_node->set_unique_name_in_owner(true);
1557+
}
15091558
item->set_metadata(0, p_node->get_path());
15101559
emit_signal(SNAME("node_renamed"));
15111560
} else {
15121561
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
15131562
undo_redo->create_action(TTR("Rename Node"), UndoRedo::MERGE_DISABLE, p_node);
15141563

1564+
if (check_for_unique_name_token) {
1565+
undo_redo->add_undo_method(p_node, "set_unique_name_in_owner", false);
1566+
}
1567+
15151568
emit_signal(SNAME("node_prerename"), p_node, new_name);
15161569

15171570
undo_redo->add_undo_method(p_node, "set_name", p_node->get_name());
@@ -1523,6 +1576,10 @@ void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem *
15231576
undo_redo->add_do_method(item, "set_metadata", 0, p_node->get_path());
15241577
undo_redo->add_do_method(item, "set_text", 0, new_name);
15251578

1579+
if (check_for_unique_name_token) {
1580+
undo_redo->add_do_method(p_node, "set_unique_name_in_owner", true);
1581+
}
1582+
15261583
undo_redo->commit_action();
15271584
}
15281585
}

0 commit comments

Comments
 (0)