|
@@ -35,6 +35,7 @@
|
|
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
|
|
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
|
|
#include "script_editor_debugger.h"
|
|
#include "script_editor_debugger.h"
|
|
#include "tools/editor/plugins/script_editor_plugin.h"
|
|
#include "tools/editor/plugins/script_editor_plugin.h"
|
|
|
|
+#include "core/io/resource_saver.h"
|
|
#include "multi_node_edit.h"
|
|
#include "multi_node_edit.h"
|
|
|
|
|
|
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
|
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
|
@@ -485,7 +486,54 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|
delete_dialog->popup_centered_minsize();
|
|
delete_dialog->popup_centered_minsize();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ } break;
|
|
|
|
+ case TOOL_NEW_SCENE_FROM: {
|
|
|
|
+
|
|
|
|
+ Node *scene = editor_data->get_edited_scene_root();
|
|
|
|
|
|
|
|
+ if (!scene) {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("This operation can't be done without a scene.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Node*> selection = editor_selection->get_selected_node_list();
|
|
|
|
+
|
|
|
|
+ if (selection.size()!=1) {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("This operation requires a single selected node.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Node *tocopy = selection.front()->get();
|
|
|
|
+
|
|
|
|
+ if (tocopy!=editor_data->get_edited_scene_root() && tocopy->get_filename()!="") {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("This operation can't be done on instanced scenes.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
|
|
|
|
+
|
|
|
|
+ List<String> extensions;
|
|
|
|
+ Ref<PackedScene> sd = memnew( PackedScene );
|
|
|
|
+ ResourceSaver::get_recognized_extensions(sd,&extensions);
|
|
|
|
+ new_scene_from_dialog->clear_filters();
|
|
|
|
+ for(int i=0;i<extensions.size();i++) {
|
|
|
|
+ new_scene_from_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String existing;
|
|
|
|
+ if (extensions.size()) {
|
|
|
|
+ existing="new_scene."+extensions.front()->get().to_lower();
|
|
|
|
+ }
|
|
|
|
+ new_scene_from_dialog->set_current_path(existing);
|
|
|
|
+
|
|
|
|
+ new_scene_from_dialog->popup_centered_ratio();
|
|
|
|
+ new_scene_from_dialog->set_title("Save New Scene As..");
|
|
|
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
@@ -520,6 +568,7 @@ void SceneTreeDock::_notification(int p_what) {
|
|
"MoveDown",
|
|
"MoveDown",
|
|
"Duplicate",
|
|
"Duplicate",
|
|
"Reparent",
|
|
"Reparent",
|
|
|
|
+ "CreateNewSceneFrom",
|
|
"MultiNodeEdit",
|
|
"MultiNodeEdit",
|
|
"Remove",
|
|
"Remove",
|
|
};
|
|
};
|
|
@@ -1140,6 +1189,7 @@ void SceneTreeDock::_update_tool_buttons() {
|
|
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
|
|
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
|
|
tool_buttons[TOOL_REPARENT]->set_disabled(disable_root);
|
|
tool_buttons[TOOL_REPARENT]->set_disabled(disable_root);
|
|
tool_buttons[TOOL_ERASE]->set_disabled(disable);
|
|
tool_buttons[TOOL_ERASE]->set_disabled(disable);
|
|
|
|
+ tool_buttons[TOOL_NEW_SCENE_FROM]->set_disabled(disable_root);
|
|
tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
|
|
tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
|
|
|
|
|
|
|
|
|
|
@@ -1326,6 +1376,59 @@ void SceneTreeDock::_import_subscene() {
|
|
*/
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void SceneTreeDock::_new_scene_from(String p_file) {
|
|
|
|
+
|
|
|
|
+ List<Node*> selection = editor_selection->get_selected_node_list();
|
|
|
|
+
|
|
|
|
+ if (selection.size()!=1) {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("This operation requires a single selected node.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Node *base = selection.front()->get();
|
|
|
|
+
|
|
|
|
+ Map<Node*,Node*> reown;
|
|
|
|
+ reown[editor_data->get_edited_scene_root()]=base;
|
|
|
|
+ Node *copy = base->duplicate_and_reown(reown);
|
|
|
|
+ if (copy) {
|
|
|
|
+
|
|
|
|
+ Ref<PackedScene> sdata = memnew( PackedScene );
|
|
|
|
+ Error err = sdata->pack(copy);
|
|
|
|
+ memdelete(copy);
|
|
|
|
+
|
|
|
|
+ if (err!=OK) {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int flg=0;
|
|
|
|
+ if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources"))
|
|
|
|
+ flg|=ResourceSaver::FLAG_COMPRESS;
|
|
|
|
+ if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative"))
|
|
|
|
+ flg|=ResourceSaver::FLAG_RELATIVE_PATHS;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ err = ResourceSaver::save(p_file,sdata,flg);
|
|
|
|
+ if (err!=OK) {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("Error saving scene.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ accept->get_ok()->set_text("I see..");
|
|
|
|
+ accept->set_text("Error duplicating scene to save it.");
|
|
|
|
+ accept->popup_centered_minsize();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
void SceneTreeDock::_bind_methods() {
|
|
void SceneTreeDock::_bind_methods() {
|
|
|
|
|
|
ObjectTypeDB::bind_method(_MD("_tool_selected"),&SceneTreeDock::_tool_selected);
|
|
ObjectTypeDB::bind_method(_MD("_tool_selected"),&SceneTreeDock::_tool_selected);
|
|
@@ -1343,6 +1446,7 @@ void SceneTreeDock::_bind_methods() {
|
|
ObjectTypeDB::bind_method(_MD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed);
|
|
ObjectTypeDB::bind_method(_MD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed);
|
|
ObjectTypeDB::bind_method(_MD("_import_subscene"),&SceneTreeDock::_import_subscene);
|
|
ObjectTypeDB::bind_method(_MD("_import_subscene"),&SceneTreeDock::_import_subscene);
|
|
ObjectTypeDB::bind_method(_MD("_selection_changed"),&SceneTreeDock::_selection_changed);
|
|
ObjectTypeDB::bind_method(_MD("_selection_changed"),&SceneTreeDock::_selection_changed);
|
|
|
|
+ ObjectTypeDB::bind_method(_MD("_new_scene_from"),&SceneTreeDock::_new_scene_from);
|
|
|
|
|
|
ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance);
|
|
ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance);
|
|
}
|
|
}
|
|
@@ -1415,9 +1519,10 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|
scene_tree->set_undo_redo(&editor_data->get_undo_redo());
|
|
scene_tree->set_undo_redo(&editor_data->get_undo_redo());
|
|
scene_tree->set_editor_selection(editor_selection);
|
|
scene_tree->set_editor_selection(editor_selection);
|
|
|
|
|
|
|
|
+
|
|
HBoxContainer *hbc_bottom = memnew( HBoxContainer );
|
|
HBoxContainer *hbc_bottom = memnew( HBoxContainer );
|
|
vbc->add_child(hbc_bottom);
|
|
vbc->add_child(hbc_bottom);
|
|
-
|
|
|
|
|
|
+ hbc_bottom->add_constant_override("separation", 0);
|
|
|
|
|
|
tb = memnew( ToolButton );
|
|
tb = memnew( ToolButton );
|
|
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MOVE_UP, false));
|
|
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MOVE_UP, false));
|
|
@@ -1445,6 +1550,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|
|
|
|
|
hbc_bottom->add_spacer();
|
|
hbc_bottom->add_spacer();
|
|
|
|
|
|
|
|
+ tb = memnew( ToolButton );
|
|
|
|
+ tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW_SCENE_FROM, false));
|
|
|
|
+ tb->set_tooltip("Create New Scene From Node(s)");
|
|
|
|
+ hbc_bottom->add_child(tb);
|
|
|
|
+ tool_buttons[TOOL_NEW_SCENE_FROM]=tb;
|
|
|
|
+
|
|
tb = memnew( ToolButton );
|
|
tb = memnew( ToolButton );
|
|
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MULTI_EDIT, false));
|
|
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MULTI_EDIT, false));
|
|
tb->set_tooltip("Multi-Edit Selected Nodes");
|
|
tb->set_tooltip("Multi-Edit Selected Nodes");
|
|
@@ -1465,12 +1576,15 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|
groups_editor = memnew( GroupsEditor );
|
|
groups_editor = memnew( GroupsEditor );
|
|
add_child(groups_editor);
|
|
add_child(groups_editor);
|
|
groups_editor->set_undo_redo(&editor_data->get_undo_redo());
|
|
groups_editor->set_undo_redo(&editor_data->get_undo_redo());
|
|
|
|
+
|
|
connect_dialog = memnew( ConnectionsDialog(p_editor) );
|
|
connect_dialog = memnew( ConnectionsDialog(p_editor) );
|
|
add_child(connect_dialog);
|
|
add_child(connect_dialog);
|
|
connect_dialog->set_undoredo(&editor_data->get_undo_redo());
|
|
connect_dialog->set_undoredo(&editor_data->get_undo_redo());
|
|
|
|
+
|
|
script_create_dialog = memnew( ScriptCreateDialog );
|
|
script_create_dialog = memnew( ScriptCreateDialog );
|
|
add_child(script_create_dialog);
|
|
add_child(script_create_dialog);
|
|
script_create_dialog->connect("script_created",this,"_script_created");
|
|
script_create_dialog->connect("script_created",this,"_script_created");
|
|
|
|
+
|
|
reparent_dialog = memnew( ReparentDialog );
|
|
reparent_dialog = memnew( ReparentDialog );
|
|
add_child(reparent_dialog);
|
|
add_child(reparent_dialog);
|
|
reparent_dialog->connect("reparent",this,"_node_reparent");
|
|
reparent_dialog->connect("reparent",this,"_node_reparent");
|
|
@@ -1486,10 +1600,16 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|
delete_dialog = memnew( ConfirmationDialog );
|
|
delete_dialog = memnew( ConfirmationDialog );
|
|
add_child(delete_dialog);
|
|
add_child(delete_dialog);
|
|
delete_dialog->connect("confirmed",this,"_delete_confirm");
|
|
delete_dialog->connect("confirmed",this,"_delete_confirm");
|
|
|
|
+
|
|
import_subscene_dialog = memnew( EditorSubScene );
|
|
import_subscene_dialog = memnew( EditorSubScene );
|
|
add_child(import_subscene_dialog);
|
|
add_child(import_subscene_dialog);
|
|
import_subscene_dialog->connect("subscene_selected",this,"_import_subscene");
|
|
import_subscene_dialog->connect("subscene_selected",this,"_import_subscene");
|
|
|
|
|
|
|
|
+ new_scene_from_dialog = memnew( EditorFileDialog );
|
|
|
|
+ new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
|
|
|
|
+ add_child(new_scene_from_dialog);
|
|
|
|
+ new_scene_from_dialog->connect("file_selected",this,"_new_scene_from");
|
|
|
|
+
|
|
first_enter=true;
|
|
first_enter=true;
|
|
|
|
|
|
|
|
|