diff options
-rw-r--r-- | editor/icons/icon_reparent_to_new_node.svg | 83 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 145 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 2 |
3 files changed, 184 insertions, 46 deletions
diff --git a/editor/icons/icon_reparent_to_new_node.svg b/editor/icons/icon_reparent_to_new_node.svg new file mode 100644 index 0000000000..29db56279c --- /dev/null +++ b/editor/icons/icon_reparent_to_new_node.svg @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg8" + sodipodi:docname="icon_reparent_to_new_node.svg" + inkscape:version="0.92.1 r15371"> + <metadata + id="metadata14"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs12" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1023" + id="namedview10" + showgrid="false" + inkscape:zoom="29.5" + inkscape:cx="2.2588225" + inkscape:cy="3.6882199" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="g6" /> + <g + transform="translate(0 -1036.4)" + id="g6"> + <path + transform="translate(0,1036.4)" + d="m 1.4915254,13 c 0,1.104569 0.8954305,2 2,2 0.7139771,-5.54e-4 1.3735116,-0.381677 1.7305,-1 H 11.2715 c 0.356631,0.617705 1.015238,0.998733 1.7285,1 1.104569,0 2,-0.895431 2,-2 0,-1.104569 -0.895431,-2 -2,-2 -0.713977,5.54e-4 -1.373512,0.381677 -1.7305,1 H 5.2200254 c -0.1747809,-0.30301 -0.8483719,-1 -1.7285,-1 -0.9027301,0 -2,0.891221 -2,2 z" + id="path2" + inkscape:connector-curvature="0" + style="fill:#e0e0e0" + sodipodi:nodetypes="cccccsccccc" /> + <path + d="m 10.421845,1038.2814 -2.7947264,2.096 2.7947264,2.0961 v -1.3974 c 2.716918,0 2.180792,1.4469 2.180792,3.9265 V 1046.4 H 14 v -1.3974 c 0,-3.863 0.13086,-5.3239 -3.578155,-5.3239 z" + id="path4" + inkscape:connector-curvature="0" + style="fill:#84ffb1;stroke-width:0.69868171" + sodipodi:nodetypes="cccccccccc" /> + <g + transform="translate(-8.5,-8)" + id="g6-7"> + <path + style="fill:#84ffb1" + inkscape:connector-curvature="0" + transform="translate(0,1036.4)" + d="m 11,9 v 2 H 9 v 2 h 2 v 2 h 2 v -2 h 2 V 11 H 13 V 9 Z" + id="path4-5" /> + </g> + <path + d="m 4.5,1047.7968 v -3.1171 H 2.4999995 v 3.1171 z" + id="path2-3" + inkscape:connector-curvature="0" + style="fill:#e0e0e0;stroke-width:0.7178387" + sodipodi:nodetypes="ccccc" /> + </g> +</svg> diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index c43d164078..c7fc466cd8 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -338,7 +338,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { tree->edit_selected(); } } break; - case TOOL_NEW: { + case TOOL_NEW: + case TOOL_REPARENT_TO_NEW_NODE: { if (!profile_allow_editing) { break; @@ -1909,6 +1910,54 @@ Node *SceneTreeDock::_get_selection_group_tail(Node *p_node, List<Node *> p_list return tail; } +void SceneTreeDock::_do_create(Node *p_parent) { + Object *c = create_dialog->instance_selected(); + + ERR_FAIL_COND(!c); + Node *child = Object::cast_to<Node>(c); + ERR_FAIL_COND(!child); + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + if (edited_scene) { + + editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child); + editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene); + editor_data->get_undo_redo().add_do_method(editor_selection, "clear"); + editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child); + editor_data->get_undo_redo().add_do_reference(child); + editor_data->get_undo_redo().add_undo_method(p_parent, "remove_child", child); + + String new_name = p_parent->validate_child_name(child); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", edited_scene->get_path_to(p_parent), child->get_class(), new_name); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).plus_file(new_name))); + + } else { + + editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child); + editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); + editor_data->get_undo_redo().add_do_reference(child); + editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL); + } + + editor_data->get_undo_redo().commit_action(); + editor->push_item(c); + editor_selection->clear(); + editor_selection->add_node(child); + if (Object::cast_to<Control>(c)) { + //make editor more comfortable, so some controls don't appear super shrunk + Control *ct = Object::cast_to<Control>(c); + + Size2 ms = ct->get_minimum_size(); + if (ms.width < 4) + ms.width = 40; + if (ms.height < 4) + ms.height = 40; + ct->set_size(ms); + } +} + void SceneTreeDock::_create() { if (current_option == TOOL_NEW) { @@ -1927,51 +1976,7 @@ void SceneTreeDock::_create() { ERR_FAIL_COND(!parent); } - Object *c = create_dialog->instance_selected(); - - ERR_FAIL_COND(!c); - Node *child = Object::cast_to<Node>(c); - ERR_FAIL_COND(!child); - - editor_data->get_undo_redo().create_action(TTR("Create Node")); - - if (edited_scene) { - - editor_data->get_undo_redo().add_do_method(parent, "add_child", child); - editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene); - editor_data->get_undo_redo().add_do_method(editor_selection, "clear"); - editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child); - editor_data->get_undo_redo().add_do_reference(child); - editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child); - - String new_name = parent->validate_child_name(child); - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", edited_scene->get_path_to(parent), child->get_class(), new_name); - editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(new_name))); - - } else { - - editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child); - editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree"); - editor_data->get_undo_redo().add_do_reference(child); - editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL); - } - - editor_data->get_undo_redo().commit_action(); - editor->push_item(c); - editor_selection->clear(); - editor_selection->add_node(child); - if (Object::cast_to<Control>(c)) { - //make editor more comfortable, so some controls don't appear super shrunk - Control *ct = Object::cast_to<Control>(c); - - Size2 ms = ct->get_minimum_size(); - if (ms.width < 4) - ms.width = 40; - if (ms.height < 4) - ms.height = 40; - ct->set_size(ms); - } + _do_create(parent); } else if (current_option == TOOL_REPLACE) { List<Node *> selection = editor_selection->get_selected_node_list(); @@ -1988,6 +1993,52 @@ void SceneTreeDock::_create() { replace_node(n, newnode); } + } else if (current_option == TOOL_REPARENT_TO_NEW_NODE) { + List<Node *> selection = editor_selection->get_selected_node_list(); + ERR_FAIL_COND(selection.size() <= 0); + + // Find top level node in selection + bool only_one_top_node = true; + + Node *first = selection.front()->get(); + ERR_FAIL_COND(!first); + int smaller_path_to_top = first->get_path_to(scene_root).get_name_count(); + Node *top_node = first; + + for (List<Node *>::Element *E = selection.front()->next(); E; E = E->next()) { + Node *n = E->get(); + ERR_FAIL_COND(!n); + + int path_length = n->get_path_to(scene_root).get_name_count(); + + if (top_node != n) { + if (smaller_path_to_top > path_length) { + top_node = n; + smaller_path_to_top = path_length; + only_one_top_node = true; + } else if (smaller_path_to_top == path_length) { + if (only_one_top_node && top_node->get_parent() != n->get_parent()) + only_one_top_node = false; + } + } + } + + Node *parent = NULL; + if (only_one_top_node) + parent = top_node->get_parent(); + else + parent = top_node->get_parent()->get_parent(); + + _do_create(parent); + + Vector<Node *> nodes; + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + nodes.push_back(E->get()); + } + + // This works because editor_selection was cleared and populated with last created node in _do_create() + Node *last_created = editor_selection->get_selected_node_list().front()->get(); + _do_reparent(last_created, -1, nodes, true); } scene_tree->get_scene_tree()->call_deferred("grab_focus"); @@ -2377,6 +2428,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN); 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_icon_shortcut(get_icon("ReparentToNewNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE); menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT); } } @@ -2673,6 +2725,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN); ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); + ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node")); ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root")); ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 8a2b237b8b..cd582fdf57 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -70,6 +70,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_MOVE_DOWN, TOOL_DUPLICATE, TOOL_REPARENT, + TOOL_REPARENT_TO_NEW_NODE, TOOL_MAKE_ROOT, TOOL_NEW_SCENE_FROM, TOOL_MERGE_FROM_SCENE, @@ -142,6 +143,7 @@ class SceneTreeDock : public VBoxContainer { bool first_enter; void _create(); + void _do_create(Node *p_parent); Node *scene_root; Node *edited_scene; EditorNode *editor; |