summaryrefslogtreecommitdiff
path: root/editor/scene_tree_dock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/scene_tree_dock.cpp')
-rw-r--r--editor/scene_tree_dock.cpp219
1 files changed, 84 insertions, 135 deletions
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 816156ef00..4d5d467857 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -290,6 +290,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!scene) {
EditorNode::get_singleton()->new_inherited_scene();
+ break;
}
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -443,8 +444,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
List<Node *> owned;
node->get_owned_by(node->get_owner(), &owned);
- Map<Node *, Node *> duplimap;
- Node *dup = _duplicate(node, duplimap);
+ Map<const Node *, Node *> duplimap;
+ Node *dup = node->duplicate_from_editor(duplimap);
ERR_CONTINUE(!dup);
@@ -745,6 +746,10 @@ void SceneTreeDock::_notification(int p_what) {
canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
}
+
+ SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
+ spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
+
button_add->set_icon(get_icon("Add", "EditorIcons"));
button_instance->set_icon(get_icon("Instance", "EditorIcons"));
button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
@@ -821,82 +826,6 @@ void SceneTreeDock::_node_renamed() {
_node_selected();
}
-Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node *, Node *> &duplimap) {
-
- Node *node = NULL;
-
- if (p_node->get_filename() != "") { //an instance
-
- Ref<PackedScene> sd = ResourceLoader::load(p_node->get_filename());
- ERR_FAIL_COND_V(!sd.is_valid(), NULL);
- node = sd->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
- ERR_FAIL_COND_V(!node, NULL);
- node->set_scene_instance_load_placeholder(p_node->get_scene_instance_load_placeholder());
- } else {
- Object *obj = ClassDB::instance(p_node->get_class());
- ERR_FAIL_COND_V(!obj, NULL);
- node = Object::cast_to<Node>(obj);
- if (!node)
- memdelete(obj);
- ERR_FAIL_COND_V(!node, NULL);
- }
-
- List<PropertyInfo> plist;
-
- p_node->get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
- String name = E->get().name;
- Variant value = p_node->get(name);
- // Duplicate dictionaries and arrays, mainly needed for __meta__
- if (value.get_type() == Variant::DICTIONARY) {
- value = Dictionary(value).copy();
- } else if (value.get_type() == Variant::ARRAY) {
- value = Array(value).duplicate();
- }
- node->set(name, value);
- }
-
- List<Connection> conns;
- p_node->get_all_signal_connections(&conns);
- for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
- if (E->get().flags & CONNECT_PERSIST) {
- node->connect(E->get().signal, E->get().target, E->get().method, E->get().binds, E->get().flags);
- }
- }
-
- List<Node::GroupInfo> group_info;
- p_node->get_groups(&group_info);
- for (List<Node::GroupInfo>::Element *E = group_info.front(); E; E = E->next()) {
-
- if (E->get().persistent)
- node->add_to_group(E->get().name, true);
- }
-
- node->set_name(p_node->get_name());
- duplimap[p_node] = node;
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- Node *child = p_node->get_child(i);
- if (p_node->get_owner() != child->get_owner())
- continue; //don't bother with not in-scene nodes.
-
- Node *dup = _duplicate(child, duplimap);
- if (!dup) {
- memdelete(node);
- return NULL;
- }
-
- node->add_child(dup);
- }
-
- return node;
-}
-
void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) {
for (int i = 0; i < p_nodes.size(); i++) {
@@ -1058,7 +987,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
//will be renamed
NodePath rel_path = new_root_path.rel_path_to(E->get().second);
- NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false, track_np.get_property());
+ NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false);
if (new_path == track_np)
continue; //bleh
editor_data->get_undo_redo().add_do_method(anim.ptr(), "track_set_path", i, new_path);
@@ -1430,7 +1359,7 @@ void SceneTreeDock::_create() {
editor_data->get_undo_redo().commit_action();
editor->push_item(c);
-
+ editor_selection->clear();
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);
@@ -1444,75 +1373,81 @@ void SceneTreeDock::_create() {
}
} else if (current_option == TOOL_REPLACE) {
- Node *n = scene_tree->get_selected();
- ERR_FAIL_COND(!n);
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ ERR_FAIL_COND(selection.size() <= 0);
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Node *n = E->get();
+ ERR_FAIL_COND(!n);
- Object *c = create_dialog->instance_selected();
+ Object *c = create_dialog->instance_selected();
- ERR_FAIL_COND(!c);
- Node *newnode = Object::cast_to<Node>(c);
- ERR_FAIL_COND(!newnode);
+ ERR_FAIL_COND(!c);
+ Node *newnode = Object::cast_to<Node>(c);
+ ERR_FAIL_COND(!newnode);
- List<PropertyInfo> pinfo;
- n->get_property_list(&pinfo);
+ List<PropertyInfo> pinfo;
+ n->get_property_list(&pinfo);
- for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
- newnode->set(E->get().name, n->get(E->get().name));
- }
+ for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
+ if (E->get().name == "__meta__")
+ continue;
+ newnode->set(E->get().name, n->get(E->get().name));
+ }
- editor->push_item(NULL);
+ editor->push_item(NULL);
- //reconnect signals
- List<MethodInfo> sl;
+ //reconnect signals
+ List<MethodInfo> sl;
- n->get_signal_list(&sl);
- for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) {
+ n->get_signal_list(&sl);
+ for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) {
- List<Object::Connection> cl;
- n->get_signal_connection_list(E->get().name, &cl);
+ List<Object::Connection> cl;
+ n->get_signal_connection_list(E->get().name, &cl);
- for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) {
+ for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) {
- Object::Connection &c = F->get();
- if (!(c.flags & Object::CONNECT_PERSIST))
- continue;
- newnode->connect(c.signal, c.target, c.method, varray(), Object::CONNECT_PERSIST);
+ Object::Connection &c = F->get();
+ if (!(c.flags & Object::CONNECT_PERSIST))
+ continue;
+ newnode->connect(c.signal, c.target, c.method, varray(), Object::CONNECT_PERSIST);
+ }
}
- }
- String newname = n->get_name();
+ String newname = n->get_name();
- List<Node *> to_erase;
- for (int i = 0; i < n->get_child_count(); i++) {
- if (n->get_child(i)->get_owner() == NULL && n->is_owned_by_parent()) {
- to_erase.push_back(n->get_child(i));
+ List<Node *> to_erase;
+ for (int i = 0; i < n->get_child_count(); i++) {
+ if (n->get_child(i)->get_owner() == NULL && n->is_owned_by_parent()) {
+ to_erase.push_back(n->get_child(i));
+ }
}
- }
- n->replace_by(newnode, true);
+ n->replace_by(newnode, true);
- if (n == edited_scene) {
- edited_scene = newnode;
- editor->set_edited_scene(newnode);
- newnode->set_editable_instances(n->get_editable_instances());
- }
+ if (n == edited_scene) {
+ edited_scene = newnode;
+ editor->set_edited_scene(newnode);
+ newnode->set_editable_instances(n->get_editable_instances());
+ }
- //small hack to make collisionshapes and other kind of nodes to work
- for (int i = 0; i < newnode->get_child_count(); i++) {
- Node *c = newnode->get_child(i);
- c->call("set_transform", c->call("get_transform"));
- }
- editor_data->get_undo_redo().clear_history();
- newnode->set_name(newname);
+ //small hack to make collisionshapes and other kind of nodes to work
+ for (int i = 0; i < newnode->get_child_count(); i++) {
+ Node *c = newnode->get_child(i);
+ c->call("set_transform", c->call("get_transform"));
+ }
+ editor_data->get_undo_redo().clear_history();
+ newnode->set_name(newname);
- editor->push_item(newnode);
+ editor->push_item(newnode);
- memdelete(n);
+ memdelete(n);
- while (to_erase.front()) {
- memdelete(to_erase.front()->get());
- to_erase.pop_front();
+ while (to_erase.front()) {
+ memdelete(to_erase.front()->get());
+ to_erase.pop_front();
+ }
}
}
}
@@ -1806,13 +1741,12 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
- menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
- menu->add_separator();
menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
menu->add_separator();
}
-
+ menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
+ menu->add_separator();
menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
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);
@@ -1897,16 +1831,24 @@ void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
void SceneTreeDock::show_remote_tree() {
- button_hb->show();
_remote_tree_selected();
}
void SceneTreeDock::hide_remote_tree() {
- button_hb->hide();
_local_tree_selected();
}
+void SceneTreeDock::show_tab_buttons() {
+
+ button_hb->show();
+}
+
+void SceneTreeDock::hide_tab_buttons() {
+
+ button_hb->hide();
+}
+
void SceneTreeDock::_remote_tree_selected() {
scene_tree->hide();
@@ -1914,6 +1856,8 @@ void SceneTreeDock::_remote_tree_selected() {
remote_tree->show();
edit_remote->set_pressed(true);
edit_local->set_pressed(false);
+
+ emit_signal("remote_tree_selected");
}
void SceneTreeDock::_local_tree_selected() {
@@ -1923,6 +1867,8 @@ void SceneTreeDock::_local_tree_selected() {
remote_tree->hide();
edit_remote->set_pressed(false);
edit_local->set_pressed(true);
+
+ _node_selected();
}
void SceneTreeDock::_bind_methods() {
@@ -1954,10 +1900,13 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);
+
+ ADD_SIGNAL(MethodInfo("remote_tree_selected"));
}
SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) {
+ set_name("Scene");
editor = p_editor;
edited_scene = NULL;
editor_data = &p_editor_data;