From 49c065d29ca07040c3fd810026121164ad86b247 Mon Sep 17 00:00:00 2001 From: Rémi Verschelde Date: Sun, 5 Mar 2017 14:21:25 +0100 Subject: Refactoring: rename tools/editor/ to editor/ The other subfolders of tools/ had already been moved to either editor/, misc/ or thirdparty/, so the hiding the editor code that deep was no longer meaningful. --- editor/scene_tree_dock.cpp | 2061 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2061 insertions(+) create mode 100644 editor/scene_tree_dock.cpp (limited to 'editor/scene_tree_dock.cpp') diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp new file mode 100644 index 000000000..47eb84ab7 --- /dev/null +++ b/editor/scene_tree_dock.cpp @@ -0,0 +1,2061 @@ +/*************************************************************************/ +/* scene_tree_dock.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "scene_tree_dock.h" + +#include "editor_node.h" +#include "global_config.h" +#include "os/keyboard.h" +#include "scene/resources/packed_scene.h" +#include "editor_settings.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#include "editor/plugins/spatial_editor_plugin.h" +#include "script_editor_debugger.h" +#include "editor/plugins/script_editor_plugin.h" +#include "core/io/resource_saver.h" +#include "multi_node_edit.h" +#include "editor/plugins/animation_player_editor_plugin.h" +#include "animation_editor.h" +#include "scene/main/viewport.h" + + +void SceneTreeDock::_nodes_drag_begin() { + + + if (restore_script_editor_on_drag) { + EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); + restore_script_editor_on_drag=false; + } + +} + +void SceneTreeDock::_input(InputEvent p_event) { + + if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==BUTTON_LEFT) { + restore_script_editor_on_drag=false; //lost chance + } +} + +void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { + + if (get_viewport()->get_modal_stack_top()) + return; //ignore because of modal window + + if (!p_event.key.pressed || p_event.key.echo) + return; + + if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) { + _tool_selected(TOOL_NEW); + } + else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) { + _tool_selected(TOOL_INSTANCE); + } + 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)) { + _tool_selected(TOOL_DUPLICATE); + } + else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) { + _tool_selected(TOOL_ATTACH_SCRIPT); + } + else if(ED_IS_SHORTCUT("scene_tree/clear_script", p_event)) { + _tool_selected(TOOL_CLEAR_SCRIPT); + } + else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) { + _tool_selected(TOOL_MOVE_UP); + } + else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) { + _tool_selected(TOOL_MOVE_DOWN); + } + else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) { + _tool_selected(TOOL_REPARENT); + } + else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) { + _tool_selected(TOOL_MERGE_FROM_SCENE); + } + else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) { + _tool_selected(TOOL_NEW_SCENE_FROM); + } + else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", 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/delete", p_event)) { + _tool_selected(TOOL_ERASE); + } +} + +void SceneTreeDock::instance(const String& p_file) { + + Node *parent = scene_tree->get_selected(); + if (!parent || !edited_scene) { + + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + return; + }; + + ERR_FAIL_COND(!parent); + + Vector scenes; + scenes.push_back(p_file); + _perform_instance_scenes(scenes,parent,-1); + +} + +void SceneTreeDock::instance_scenes(const Vector& p_files, Node *p_parent) { + + Node *parent = p_parent; + + if (!parent) { + parent = scene_tree->get_selected(); + } + + if (!parent || !edited_scene) { + + accept->get_ok()->set_text(TTR("OK")); + accept->set_text(TTR("No parent to instance the scenes at.")); + accept->popup_centered_minsize(); + return; + }; + + _perform_instance_scenes(p_files, parent, -1); +} + +void SceneTreeDock::_perform_instance_scenes(const Vector& p_files,Node* parent,int p_pos) { + + + + ERR_FAIL_COND(!parent); + + + Vector instances; + + bool error=false; + + for(int i=0;i sdata = ResourceLoader::load(p_files[i]); + if (!sdata.is_valid()) { + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error loading scene from %s"),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + + } + + Node*instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + + } + + if (edited_scene->get_filename()!="") { + + if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { + + accept->get_ok()->set_text(TTR("Ok")); + accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + } + } + + instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(p_files[i]) ); + + instances.push_back(instanced_scene); + } + + if (error) { + for(int i=0;igenerate_instance_state(); + + editor_data->get_undo_redo().create_action(TTR("Instance Scene(s)")); + + for(int i=0;iget_undo_redo().add_do_method(parent,"add_child",instanced_scene); + if (p_pos>=0) { + editor_data->get_undo_redo().add_do_method(parent,"move_child",instanced_scene,p_pos+i); + } + editor_data->get_undo_redo().add_do_method(instanced_scene,"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",instanced_scene); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); + + String new_name = parent->validate_child_name(instanced_scene); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_files[i],new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); + } + + editor_data->get_undo_redo().commit_action(); + + +} + +void SceneTreeDock::_replace_with_branch_scene(const String& p_file,Node* base) { + Ref sdata = ResourceLoader::load(p_file); + if (!sdata.is_valid()) { + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error loading scene from %s"),p_file)); + accept->popup_centered_minsize(); + return; + } + + Node *instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"),p_file)); + accept->popup_centered_minsize(); + return; + } + + Node *parent = base->get_parent(); + int pos = base->get_index(); + memdelete(base); + parent->add_child(instanced_scene); + parent->move_child(instanced_scene, pos); + instanced_scene->set_owner(edited_scene); + editor_selection->clear(); + editor_selection->add_node(instanced_scene); + scene_tree->set_selected(instanced_scene); +} + +bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { + int childCount = p_desired_node->get_child_count(); + + if (p_desired_node->get_filename()==p_target_scene_path) { + return true; + } + + for (int i=0;iget_child(i); + + if(_cyclical_dependency_exists(p_target_scene_path,child)) { + return true; + } + } + + return false; +} + + +void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { + + current_option=p_tool; + + switch(p_tool) { + + case TOOL_NEW: { + /* + if (!_validate_no_foreign()) + break; + */ + create_dialog->popup(true); + } break; + case TOOL_INSTANCE: { + + Node *scene = edited_scene; + + if (!scene) { + + EditorNode::get_singleton()->new_inherited_scene(); + + /* should be legal now + current_option=-1; + //confirmation->get_cancel()->hide(); + accept->get_ok()->set_text("I see.."); + accept->set_text("This operation can't be done without a tree root."); + accept->popup_centered_minsize(); + */ + break; + } + + /* + if (!_validate_no_foreign()) + break; + */ + + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); + List extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); + file->clear_filters(); + for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + + //file->set_current_path(current_path); + file->popup_centered_ratio(); + + } break; + case TOOL_REPLACE: { + + create_dialog->popup(false); + } break; + case TOOL_CONNECT: { + + Node *current = scene_tree->get_selected(); + if (!current) + break; + + /* + if (!_validate_no_foreign()) + break; + connect_dialog->popup_centered_ratio(); + connect_dialog->set_node(current); + */ + + } break; + case TOOL_GROUP: { + + Node *current = scene_tree->get_selected(); + if (!current) + break; + /* + if (!_validate_no_foreign()) + break; + groups_editor->set_current(current); + groups_editor->popup_centered_ratio(); + */ + } break; + case TOOL_ATTACH_SCRIPT: { + + Node *selected = scene_tree->get_selected(); + if (!selected) + break; + + /* + if (!_validate_no_foreign()) + break; + */ + + Ref