Przeglądaj źródła

`SceneTreeDock` Toggling unique name in owner for all selected nodes

kleonc 3 lat temu
rodzic
commit
5d7ff1bf44
1 zmienionych plików z 66 dodań i 17 usunięć
  1. 66 17
      editor/scene_tree_dock.cpp

+ 66 - 17
editor/scene_tree_dock.cpp

@@ -1068,24 +1068,61 @@ 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) {
-				Ref<EditorUndoRedoManager> 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."));
+			// Enabling/disabling based on the same node based on which the checkbox in the menu is checked/unchecked.
+			List<Node *>::Element *first_selected = editor_selection->get_selected_node_list().front();
+			if (first_selected == nullptr) {
+				return;
+			}
+			bool enabling = !first_selected->get()->is_unique_name_in_owner();
+
+			List<Node *> full_selection = editor_selection->get_full_selected_node_list();
+			Ref<EditorUndoRedoManager> undo_redo = editor_data->get_undo_redo();
+
+			if (enabling) {
+				Vector<Node *> new_unique_nodes;
+				Vector<StringName> new_unique_names;
+				Vector<StringName> cant_be_set_unique_names;
+
+				for (Node *node : full_selection) {
+					if (node->is_unique_name_in_owner()) {
+						continue;
+					}
+					StringName name = node->get_name();
+					if (new_unique_names.find(name) != -1 || get_tree()->get_edited_scene_root()->get_node_or_null(UNIQUE_NODE_PREFIX + String(name)) != nullptr) {
+						cant_be_set_unique_names.push_back(name);
+					} else {
+						new_unique_nodes.push_back(node);
+						new_unique_names.push_back(name);
+					}
+				}
+
+				if (new_unique_nodes.size()) {
+					undo_redo->create_action(TTR("Enable Scene Unique Name(s)"));
+					for (Node *node : new_unique_nodes) {
+						undo_redo->add_do_method(node, "set_unique_name_in_owner", true);
+						undo_redo->add_undo_method(node, "set_unique_name_in_owner", false);
+					}
+					undo_redo->commit_action();
+				}
+
+				if (cant_be_set_unique_names.size()) {
+					String popup_text = TTR("Unique names already used by another node in the scene:");
+					popup_text += "\n";
+					for (StringName name : cant_be_set_unique_names) {
+						popup_text += "\n" + String(name);
+					}
+					accept->set_text(popup_text);
 					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"));
+			} else { // Disabling.
+				undo_redo->create_action(TTR("Disable Scene Unique Name(s)"));
+				for (Node *node : full_selection) {
+					if (!node->is_unique_name_in_owner()) {
+						continue;
+					}
+					undo_redo->add_do_method(node, "set_unique_name_in_owner", false);
+					undo_redo->add_undo_method(node, "set_unique_name_in_owner", true);
 				}
-				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;
@@ -2821,14 +2858,26 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
 			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.
+	if (profile_allow_editing) {
+		// Allow multi-toggling scene unique names but only if all selected nodes are owned by the edited scene root.
+		bool all_owned = true;
+		for (Node *node : full_selection) {
+			if (node->get_owner() != EditorNode::get_singleton()->get_edited_scene()) {
+				all_owned = false;
+				break;
+			}
+		}
+		if (all_owned) {
 			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);
+			// Checked based on `selection[0]` because `full_selection` has undesired ordering.
 			menu->set_item_checked(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), selection[0]->is_unique_name_in_owner());
 		}
+	}
 
+	if (selection.size() == 1) {
 		bool is_external = (!selection[0]->get_scene_file_path().is_empty());
 		if (is_external) {
 			bool is_inherited = selection[0]->get_scene_inherited_state() != nullptr;