Add a shortcut to paste nodes as sibling of the selected node

This makes quick pasting jobs easier when you don't want a heavily
nested structure, by pressing Ctrl + Shift + V (Cmd + Shift + V on macOS)
instead of Ctrl + V (Cmd + V on macOS).
This commit is contained in:
Hugo Locurcio 2023-07-14 17:34:35 +02:00
parent 60f3b7967c
commit c0e3dc55ba
No known key found for this signature in database
GPG key ID: 39E8F8BE30B0A49C
2 changed files with 16 additions and 4 deletions

View file

@ -121,6 +121,8 @@ void SceneTreeDock::shortcut_input(const Ref<InputEvent> &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) {
@ -2860,6 +2865,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();
}
@ -3240,7 +3246,7 @@ void SceneTreeDock::open_instance_child_dialog() {
_tool_selected(TOOL_INSTANTIATE, true);
}
List<Node *> SceneTreeDock::paste_nodes() {
List<Node *> SceneTreeDock::paste_nodes(bool p_paste_as_sibling) {
List<Node *> pasted_nodes;
if (node_clipboard.is_empty()) {
@ -3270,6 +3276,10 @@ List<Node *> 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();
@ -3279,7 +3289,7 @@ List<Node *> 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>, Ref<Resource>> resource_remap;
@ -3677,6 +3687,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"));

View file

@ -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,
@ -327,7 +328,7 @@ public:
void open_add_child_dialog();
void open_instance_child_dialog();
List<Node *> paste_nodes();
List<Node *> paste_nodes(bool p_paste_as_sibling = false);
List<Node *> get_node_clipboard() const;
ScriptCreateDialog *get_script_create_dialog() {