diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 0ac3875ad6b..e8db6ed6790 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -121,6 +121,8 @@ void SceneTreeDock::shortcut_input(const Ref &p_event) { _tool_selected(TOOL_COPY); } else if (ED_IS_SHORTCUT("scene_tree/paste_node", p_event)) { _tool_selected(TOOL_PASTE); + } else if (ED_IS_SHORTCUT("scene_tree/paste_node_as_sibling", p_event)) { + _tool_selected(TOOL_PASTE_AS_SIBLING); } else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) { _tool_selected(TOOL_REPLACE); } else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) { @@ -511,7 +513,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } break; case TOOL_PASTE: { - paste_nodes(); + paste_nodes(false); + } break; + case TOOL_PASTE_AS_SIBLING: { + paste_nodes(true); } break; case TOOL_REPLACE: { if (!profile_allow_editing) { @@ -2957,6 +2962,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node"), TOOL_COPY); if (selection.size() == 1 && !node_clipboard.is_empty()) { menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE); + menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/paste_node_as_sibling"), TOOL_PASTE); } menu->add_separator(); } @@ -3330,7 +3336,7 @@ void SceneTreeDock::open_instance_child_dialog() { _tool_selected(TOOL_INSTANTIATE, true); } -List SceneTreeDock::paste_nodes() { +List SceneTreeDock::paste_nodes(bool p_paste_as_sibling) { List pasted_nodes; if (node_clipboard.is_empty()) { @@ -3360,6 +3366,10 @@ List SceneTreeDock::paste_nodes() { paste_parent = selection.back()->get(); } + if (p_paste_as_sibling) { + paste_parent = paste_parent->get_parent(); + } + Node *owner = nullptr; if (paste_parent) { owner = paste_parent->get_owner(); @@ -3369,7 +3379,7 @@ List SceneTreeDock::paste_nodes() { } EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); - ur->create_action(TTR("Paste Node(s)"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); + ur->create_action(vformat(p_paste_as_sibling ? TTR("Paste Node(s) as Sibling of %s") : TTR("Paste Node(s) as Child of %s"), paste_parent->get_name()), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); ur->add_do_method(editor_selection, "clear"); HashMap, Ref> resource_remap; @@ -3767,6 +3777,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X); ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C); ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD_OR_CTRL | Key::V); + ED_SHORTCUT("scene_tree/paste_node_as_sibling", TTR("Paste as Sibling"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::V); ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script")); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 21424925c53..9c111bce71f 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -60,6 +60,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_CUT, TOOL_COPY, TOOL_PASTE, + TOOL_PASTE_AS_SIBLING, TOOL_RENAME, #ifdef MODULE_REGEX_ENABLED TOOL_BATCH_RENAME, @@ -329,7 +330,7 @@ public: void open_add_child_dialog(); void open_instance_child_dialog(); - List paste_nodes(); + List paste_nodes(bool p_paste_as_sibling = false); List get_node_clipboard() const; ScriptCreateDialog *get_script_create_dialog() {