summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/icons/SceneUniqueName.svg1
-rw-r--r--editor/scene_tree_dock.cpp39
-rw-r--r--editor/scene_tree_dock.h2
-rw-r--r--editor/scene_tree_editor.cpp18
-rw-r--r--editor/scene_tree_editor.h1
5 files changed, 60 insertions, 1 deletions
diff --git a/editor/icons/SceneUniqueName.svg b/editor/icons/SceneUniqueName.svg
new file mode 100644
index 0000000000..34279a14a6
--- /dev/null
+++ b/editor/icons/SceneUniqueName.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.378 2.224q1.235 0 2.084.866.865.85.865 2.083 0 1.17-.881 2.036-.866.85-2.068.85-1.218 0-2.083-.85-.866-.866-.866-2.068t.866-2.051q.865-.866 2.083-.866zm.962 1.988q-.4-.4-.962-.4-.56 0-.961.4-.401.384-.401.93 0 .56.4.961.401.385.962.385.561 0 .962-.385.4-.4.4-.946 0-.56-.4-.945zm5.45-2.116h1.218L5.677 13.78H4.442Zm1.17 5.722q1.234 0 2.083.866.866.849.866 2.1 0 1.17-.882 2.035-.865.85-2.068.85-1.218 0-2.083-.85-.866-.866-.866-2.084 0-1.202.866-2.051.865-.866 2.083-.866zm.961 1.987q-.4-.4-.962-.4-.56 0-.961.4-.4.385-.4.946 0 .561.4.962.4.384.961.384.561 0 .962-.384.4-.4.4-.946 0-.56-.4-.962z" aria-label="%" style="font-weight:600;font-size:16.0277px;font-family:FreeSans;-inkscape-font-specification:'FreeSans Semi-Bold';letter-spacing:0;word-spacing:0;fill:#e0e0e0;fill-opacity:.996078;stroke-width:.400692"/></svg>
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 03f65cdf52..c63471720b 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -1061,6 +1061,28 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
+ case TOOL_TOGGLE_SCENE_UNIQUE_NAME: {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ UndoRedo *undo_redo = &editor_data->get_undo_redo();
+ Node *node = e->get();
+ bool enabled = node->is_unique_name_in_owner();
+ if (!enabled && get_tree()->get_edited_scene_root()->get_node_or_null(UNIQUE_NODE_PREFIX + String(node->get_name())) != nullptr) {
+ accept->set_text(TTR("Another node already uses this unique name in the scene."));
+ accept->popup_centered();
+ return;
+ }
+ if (!enabled) {
+ undo_redo->create_action(TTR("Enable Scene Unique Name"));
+ } else {
+ undo_redo->create_action(TTR("Disable Scene Unique Name"));
+ }
+ undo_redo->add_do_method(node, "set_unique_name_in_owner", !enabled);
+ undo_redo->add_undo_method(node, "set_unique_name_in_owner", enabled);
+ undo_redo->commit_action();
+ }
+ } break;
case TOOL_CREATE_2D_SCENE:
case TOOL_CREATE_3D_SCENE:
case TOOL_CREATE_USER_INTERFACE:
@@ -1309,8 +1331,17 @@ void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root
UndoRedo *undo_redo = &editor_data->get_undo_redo();
switch (p_mode) {
case MODE_BIDI: {
+ bool is_unique = p_node->is_unique_name_in_owner() && p_base->get_node_or_null(UNIQUE_NODE_PREFIX + String(p_node->get_name())) != nullptr;
+ if (is_unique) {
+ // Will create a unique name conflict. Disable before setting owner.
+ undo_redo->add_do_method(p_node, "set_unique_name_in_owner", false);
+ }
undo_redo->add_do_method(p_node, "set_owner", p_root);
undo_redo->add_undo_method(p_node, "set_owner", p_base);
+ if (is_unique) {
+ // Will create a unique name conflict. Enable after setting owner.
+ undo_redo->add_undo_method(p_node, "set_unique_name_in_owner", true);
+ }
} break;
case MODE_DO: {
@@ -2774,11 +2805,19 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
menu->add_icon_shortcut(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
}
+
if (full_selection.size() == 1) {
menu->add_separator();
menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
}
+ if (selection[0]->get_owner() == EditorNode::get_singleton()->get_edited_scene()) {
+ // Only for nodes owned by the edited scene root.
+ menu->add_separator();
+ menu->add_icon_check_item(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), TTR("Access as Scene Unique Name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME);
+ menu->set_item_checked(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), selection[0]->is_unique_name_in_owner());
+ }
+
bool is_external = (!selection[0]->get_scene_file_path().is_empty());
if (is_external) {
bool is_inherited = selection[0]->get_scene_inherited_state() != nullptr;
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 599fb01203..842995dfe3 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -91,7 +91,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_SCENE_CLEAR_INHERITANCE,
TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM,
TOOL_SCENE_OPEN_INHERITED,
-
+ TOOL_TOGGLE_SCENE_UNIQUE_NAME,
TOOL_CREATE_2D_SCENE,
TOOL_CREATE_3D_SCENE,
TOOL_CREATE_USER_INTERFACE,
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 44eb5c670d..aa48395152 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -148,6 +148,13 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
TabContainer *tab_container = Object::cast_to<TabContainer>(NodeDock::get_singleton()->get_parent());
NodeDock::get_singleton()->get_parent()->call("set_current_tab", tab_container->get_tab_idx_from_control(NodeDock::get_singleton()));
NodeDock::get_singleton()->show_groups();
+ } else if (p_id == BUTTON_UNIQUE) {
+ undo_redo->create_action(TTR("Disable Scene Unique Name"));
+ undo_redo->add_do_method(n, "set_unique_name_in_owner", false);
+ undo_redo->add_undo_method(n, "set_unique_name_in_owner", true);
+ undo_redo->add_do_method(this, "_update_tree");
+ undo_redo->add_undo_method(this, "_update_tree");
+ undo_redo->commit_action();
}
}
@@ -260,6 +267,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
item->add_button(0, get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + warning);
}
+ if (p_node->is_unique_name_in_owner()) {
+ item->add_button(0, get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), BUTTON_UNIQUE, false, vformat(TTR("This node can be accessed from within anywhere in the scene by preceding it with the '%s' prefix in a node path.\nClick to disable this."), UNIQUE_NODE_PREFIX));
+ }
+
int num_connections = p_node->get_persistent_signal_connection_count();
int num_groups = p_node->get_persistent_group_count();
@@ -832,6 +843,13 @@ void SceneTreeEditor::_renamed() {
// Trim leading/trailing whitespace to prevent node names from containing accidental whitespace, which would make it more difficult to get the node via `get_node()`.
new_name = new_name.strip_edges();
+ if (n->is_unique_name_in_owner() && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name) != nullptr) {
+ error->set_text(TTR("Another node already uses this unique name in the scene."));
+ error->popup_centered();
+ which->set_text(0, n->get_name());
+ return;
+ }
+
if (!undo_redo) {
n->set_name(new_name);
which->set_metadata(0, n->get_path());
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 547a5b57ca..3d88081ab1 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -53,6 +53,7 @@ class SceneTreeEditor : public Control {
BUTTON_SIGNALS = 6,
BUTTON_GROUPS = 7,
BUTTON_PIN = 8,
+ BUTTON_UNIQUE = 9,
};
Tree *tree = nullptr;