Skip to content

Commit

Permalink
Scene Tree Dock: added ability to cut/paste on nodes.
Browse files Browse the repository at this point in the history
Added icons

Small adjustments
Possible fix X11 compilation issue.
  • Loading branch information
Krakean committed Nov 28, 2017
1 parent 95e7656 commit a2d08f8
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 1 deletion.
14 changes: 14 additions & 0 deletions editor/icons/icon_cut_node.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions editor/icons/icon_paste_node.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
102 changes: 102 additions & 0 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
_tool_selected(TOOL_ERASE, true);
} else if (ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) {
_tool_selected(TOOL_COPY_NODE_PATH);
} else if (ED_IS_SHORTCUT("scene_tree/cut_node", p_event)) {
_tool_selected(TOOL_CUT_NODE);
} else if (ED_IS_SHORTCUT("scene_tree/paste_node", p_event)) {
_tool_selected(TOOL_PASTE_NODE);
} else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) {
_tool_selected(TOOL_ERASE);
}
Expand Down Expand Up @@ -480,6 +484,96 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor->push_item(dupsingle);

} break;
case TOOL_CUT_NODE: {
if (!edited_scene)
break;

if (editor_selection->is_selected(edited_scene)) {

current_option = -1;
//accept->get_cancel()->hide();
accept->get_ok()->set_text(TTR("I see.."));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
}

if (!_validate_no_foreign())
break;

List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() == 0)
break;

for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {

cutpastecopy_map m;
m.action = NODE_CUT;
Node *node = E->get();
if (node) {
m.node = node;

cpc_map->push_back(m);
}
}
} break;
case TOOL_PASTE_NODE: {
if (!edited_scene)
break;

if (editor->get_edited_scene()->get_tree()->get_node_count() == 0) {
current_option = -1;
//accept->get_cancel()->hide();
accept->get_ok()->set_text(TTR("I see.."));
accept->set_text(TTR("This operation can't be done without having the tree root."));
accept->popup_centered_minsize();
break;
}

if (!_validate_no_foreign())
break;

if (cpc_map->size() == 0)
break;

List<Node *> selection = editor_selection->get_selected_node_list();
// If nothing selected, then lets try to select root node.
if (selection.size() == 0) {
Node *p = editor->get_edited_scene();
// ...and paste it to there.
if (p)
selection.push_back(p);
}

// Should be just 1, we do not support multiple selection here.
if (selection.size() != 1)
break;

// Determine destination node for cut/copy(todo) operation.
Node *to_node = NULL;
List<Node *>::Element *E = selection.front();
if (E) {
to_node = E->get();

if (!to_node)
break; // something wrong with selected node.
}

Vector<Node *> nodes;
while (cpc_map->size() != 0) {
cutpastecopy_map item = cpc_map->get(0);

// Cut operation.
if (item.action == NODE_CUT)
nodes.push_back(item.node);

cpc_map->remove(0);
}

// Perform nodes cut-paste operation via reparenting nodes.
if (nodes.size() > 0)
_do_reparent(to_node, -1, nodes, true);
} break;
case TOOL_REPARENT: {

if (!scene_tree->get_selected())
Expand Down Expand Up @@ -1749,6 +1843,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);

menu->add_separator();
menu->add_icon_shortcut(get_icon("CutNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/cut_node"), TOOL_CUT_NODE);
menu->add_icon_shortcut(get_icon("PasteNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE_NODE);

if (selection.size() == 1) {
menu->add_separator();
menu->add_icon_shortcut(get_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE);
Expand Down Expand Up @@ -1928,6 +2026,8 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene"));
ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_C);
ED_SHORTCUT("scene_tree/cut_node", TTR("Cut Node"), KEY_MASK_CMD | KEY_X);
ED_SHORTCUT("scene_tree/paste_node", TTR("Paste Node"), KEY_MASK_CMD | KEY_V);
ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT | KEY_DELETE);
ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE);

Expand Down Expand Up @@ -2054,5 +2154,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
clear_inherit_confirm->get_ok()->set_text(TTR("Clear!"));
add_child(clear_inherit_confirm);

cpc_map = memnew(Vector<cutpastecopy_map>());

set_process_input(true);
}
16 changes: 15 additions & 1 deletion editor/scene_tree_dock.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,27 @@ class SceneTreeDock : public VBoxContainer {
TOOL_SCENE_OPEN,
TOOL_SCENE_CLEAR_INHERITANCE,
TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM,
TOOL_SCENE_OPEN_INHERITED
TOOL_SCENE_OPEN_INHERITED,
TOOL_CUT_NODE,
TOOL_PASTE_NODE,
};

enum {
EDIT_SUBRESOURCE_BASE = 100
};

enum CPC_ACTION {
NODE_CUT,
// TODO: NODE_COPY support?
};

struct cutpastecopy_map {
Node *node;
CPC_ACTION action;
};

Vector<cutpastecopy_map> *cpc_map;

Vector<ObjectID> subresources;

bool restore_script_editor_on_drag;
Expand Down

0 comments on commit a2d08f8

Please sign in to comment.