1 /*************************************************************************/
2 /* scene_tree_dock.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "scene_tree_dock.h"
32
33 #include "core/io/resource_saver.h"
34 #include "core/os/input.h"
35 #include "core/os/keyboard.h"
36 #include "core/project_settings.h"
37
38 #include "editor/editor_feature_profile.h"
39 #include "editor/editor_node.h"
40 #include "editor/editor_scale.h"
41 #include "editor/editor_settings.h"
42 #include "editor/multi_node_edit.h"
43 #include "editor/plugins/animation_player_editor_plugin.h"
44 #include "editor/plugins/canvas_item_editor_plugin.h"
45 #include "editor/plugins/script_editor_plugin.h"
46 #include "editor/plugins/spatial_editor_plugin.h"
47 #include "editor/script_editor_debugger.h"
48 #include "scene/main/viewport.h"
49 #include "scene/resources/packed_scene.h"
50
_nodes_drag_begin()51 void SceneTreeDock::_nodes_drag_begin() {
52
53 if (restore_script_editor_on_drag) {
54 EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
55 restore_script_editor_on_drag = false;
56 }
57 }
58
_quick_open()59 void SceneTreeDock::_quick_open() {
60 Vector<String> files = quick_open->get_selected_files();
61 for (int i = 0; i < files.size(); i++) {
62 instance(files[i]);
63 }
64 }
65
_input(Ref<InputEvent> p_event)66 void SceneTreeDock::_input(Ref<InputEvent> p_event) {
67
68 Ref<InputEventMouseButton> mb = p_event;
69
70 if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
71 restore_script_editor_on_drag = false; //lost chance
72 }
73 }
74
_unhandled_key_input(Ref<InputEvent> p_event)75 void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
76
77 if (get_viewport()->get_modal_stack_top())
78 return; //ignore because of modal window
79
80 if (get_focus_owner() && get_focus_owner()->is_text_field())
81 return;
82
83 if (!p_event->is_pressed() || p_event->is_echo())
84 return;
85
86 if (ED_IS_SHORTCUT("scene_tree/batch_rename", p_event)) {
87 _tool_selected(TOOL_BATCH_RENAME);
88 } else if (ED_IS_SHORTCUT("scene_tree/rename", p_event)) {
89 _tool_selected(TOOL_RENAME);
90 } else if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) {
91 _tool_selected(TOOL_NEW);
92 } else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) {
93 _tool_selected(TOOL_INSTANCE);
94 } else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) {
95 _tool_selected(TOOL_EXPAND_COLLAPSE);
96 } else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) {
97 _tool_selected(TOOL_REPLACE);
98 } else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) {
99 _tool_selected(TOOL_DUPLICATE);
100 } else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) {
101 _tool_selected(TOOL_ATTACH_SCRIPT);
102 } else if (ED_IS_SHORTCUT("scene_tree/detach_script", p_event)) {
103 _tool_selected(TOOL_DETACH_SCRIPT);
104 } else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) {
105 _tool_selected(TOOL_MOVE_UP);
106 } else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) {
107 _tool_selected(TOOL_MOVE_DOWN);
108 } else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) {
109 _tool_selected(TOOL_REPARENT);
110 } else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) {
111 _tool_selected(TOOL_MERGE_FROM_SCENE);
112 } else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) {
113 _tool_selected(TOOL_NEW_SCENE_FROM);
114 } else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) {
115 _tool_selected(TOOL_ERASE, true);
116 } else if (ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) {
117 _tool_selected(TOOL_COPY_NODE_PATH);
118 } else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) {
119 _tool_selected(TOOL_ERASE);
120 }
121 }
122
instance(const String & p_file)123 void SceneTreeDock::instance(const String &p_file) {
124
125 Node *parent = scene_tree->get_selected();
126
127 if (!parent) {
128 parent = edited_scene;
129 };
130
131 if (!edited_scene) {
132
133 current_option = -1;
134 accept->set_text(TTR("No parent to instance a child at."));
135 accept->popup_centered_minsize();
136 return;
137 };
138
139 ERR_FAIL_COND(!parent);
140
141 Vector<String> scenes;
142 scenes.push_back(p_file);
143 _perform_instance_scenes(scenes, parent, -1);
144 }
145
instance_scenes(const Vector<String> & p_files,Node * p_parent)146 void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_parent) {
147
148 Node *parent = p_parent;
149
150 if (!parent) {
151 parent = scene_tree->get_selected();
152 }
153
154 if (!parent || !edited_scene) {
155
156 accept->set_text(TTR("No parent to instance the scenes at."));
157 accept->popup_centered_minsize();
158 return;
159 };
160
161 _perform_instance_scenes(p_files, parent, -1);
162 }
163
_perform_instance_scenes(const Vector<String> & p_files,Node * parent,int p_pos)164 void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node *parent, int p_pos) {
165
166 ERR_FAIL_COND(!parent);
167
168 Vector<Node *> instances;
169
170 bool error = false;
171
172 for (int i = 0; i < p_files.size(); i++) {
173
174 Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]);
175 if (!sdata.is_valid()) {
176 current_option = -1;
177 accept->set_text(vformat(TTR("Error loading scene from %s"), p_files[i]));
178 accept->popup_centered_minsize();
179 error = true;
180 break;
181 }
182
183 Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
184 if (!instanced_scene) {
185 current_option = -1;
186 accept->set_text(vformat(TTR("Error instancing scene from %s"), p_files[i]));
187 accept->popup_centered_minsize();
188 error = true;
189 break;
190 }
191
192 if (edited_scene->get_filename() != "") {
193
194 if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) {
195
196 accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i]));
197 accept->popup_centered_minsize();
198 error = true;
199 break;
200 }
201 }
202
203 instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_files[i]));
204
205 instances.push_back(instanced_scene);
206 }
207
208 if (error) {
209 for (int i = 0; i < instances.size(); i++) {
210 memdelete(instances[i]);
211 }
212 return;
213 }
214
215 editor_data->get_undo_redo().create_action(TTR("Instance Scene(s)"));
216
217 for (int i = 0; i < instances.size(); i++) {
218
219 Node *instanced_scene = instances[i];
220
221 editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene);
222 if (p_pos >= 0) {
223 editor_data->get_undo_redo().add_do_method(parent, "move_child", instanced_scene, p_pos + i);
224 }
225 editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", edited_scene);
226 editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
227 editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", instanced_scene);
228 editor_data->get_undo_redo().add_do_reference(instanced_scene);
229 editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene);
230
231 String new_name = parent->validate_child_name(instanced_scene);
232 ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
233 editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", edited_scene->get_path_to(parent), p_files[i], new_name);
234 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)));
235 }
236
237 editor_data->get_undo_redo().commit_action();
238 }
239
_replace_with_branch_scene(const String & p_file,Node * base)240 void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
241 Ref<PackedScene> sdata = ResourceLoader::load(p_file);
242 if (!sdata.is_valid()) {
243 accept->set_text(vformat(TTR("Error loading scene from %s"), p_file));
244 accept->popup_centered_minsize();
245 return;
246 }
247
248 Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
249 if (!instanced_scene) {
250 accept->set_text(vformat(TTR("Error instancing scene from %s"), p_file));
251 accept->popup_centered_minsize();
252 return;
253 }
254
255 UndoRedo *undo_redo = editor->get_undo_redo();
256 undo_redo->create_action(TTR("Replace with Branch Scene"));
257
258 Node *parent = base->get_parent();
259 int pos = base->get_index();
260 undo_redo->add_do_method(parent, "remove_child", base);
261 undo_redo->add_undo_method(parent, "remove_child", instanced_scene);
262 undo_redo->add_do_method(parent, "add_child", instanced_scene);
263 undo_redo->add_undo_method(parent, "add_child", base);
264 undo_redo->add_do_method(parent, "move_child", instanced_scene, pos);
265 undo_redo->add_undo_method(parent, "move_child", base, pos);
266
267 List<Node *> owned;
268 base->get_owned_by(base->get_owner(), &owned);
269 Array owners;
270 for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
271 owners.push_back(F->get());
272 }
273 undo_redo->add_do_method(instanced_scene, "set_owner", edited_scene);
274 undo_redo->add_undo_method(this, "_set_owners", edited_scene, owners);
275
276 undo_redo->add_do_method(editor_selection, "clear");
277 undo_redo->add_undo_method(editor_selection, "clear");
278 undo_redo->add_do_method(editor_selection, "add_node", instanced_scene);
279 undo_redo->add_undo_method(editor_selection, "add_node", base);
280 undo_redo->add_do_property(scene_tree, "set_selected", instanced_scene);
281 undo_redo->add_undo_property(scene_tree, "set_selected", base);
282
283 undo_redo->add_do_reference(instanced_scene);
284 undo_redo->add_undo_reference(base);
285 undo_redo->commit_action();
286 }
287
_cyclical_dependency_exists(const String & p_target_scene_path,Node * p_desired_node)288 bool SceneTreeDock::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) {
289 int childCount = p_desired_node->get_child_count();
290
291 if (_track_inherit(p_target_scene_path, p_desired_node)) {
292 return true;
293 }
294
295 for (int i = 0; i < childCount; i++) {
296 Node *child = p_desired_node->get_child(i);
297
298 if (_cyclical_dependency_exists(p_target_scene_path, child)) {
299 return true;
300 }
301 }
302
303 return false;
304 }
305
_track_inherit(const String & p_target_scene_path,Node * p_desired_node)306 bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_desired_node) {
307 Node *p = p_desired_node;
308 bool result = false;
309 Vector<Node *> instances;
310 while (true) {
311 if (p->get_filename() == p_target_scene_path) {
312 result = true;
313 break;
314 }
315 Ref<SceneState> ss = p->get_scene_inherited_state();
316 if (ss.is_valid()) {
317 String path = ss->get_path();
318 Ref<PackedScene> data = ResourceLoader::load(path);
319 if (data.is_valid()) {
320 p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
321 if (!p)
322 continue;
323 instances.push_back(p);
324 } else
325 break;
326 } else
327 break;
328 }
329 for (int i = 0; i < instances.size(); i++) {
330 memdelete(instances[i]);
331 }
332 return result;
333 }
334
_tool_selected(int p_tool,bool p_confirm_override)335 void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
336
337 current_option = p_tool;
338
339 switch (p_tool) {
340
341 case TOOL_BATCH_RENAME: {
342 if (!profile_allow_editing) {
343 break;
344 }
345 if (editor_selection->get_selected_node_list().size() > 1) {
346 rename_dialog->popup_centered();
347 }
348 } break;
349 case TOOL_RENAME: {
350 if (!profile_allow_editing) {
351 break;
352 }
353 Tree *tree = scene_tree->get_scene_tree();
354 if (tree->is_anything_selected()) {
355 tree->grab_focus();
356 tree->edit_selected();
357 }
358 } break;
359 case TOOL_NEW:
360 case TOOL_REPARENT_TO_NEW_NODE: {
361
362 if (!profile_allow_editing) {
363 break;
364 }
365
366 // Prefer nodes that inherit from the current scene root.
367 Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();
368 if (current_edited_scene_root) {
369 String root_class = current_edited_scene_root->get_class_name();
370 static Vector<String> preferred_types;
371 if (preferred_types.empty()) {
372 preferred_types.push_back("Control");
373 preferred_types.push_back("Node2D");
374 preferred_types.push_back("Node3D");
375 }
376
377 for (int i = 0; i < preferred_types.size(); i++) {
378 if (ClassDB::is_parent_class(root_class, preferred_types[i])) {
379 create_dialog->set_preferred_search_result_type(preferred_types[i]);
380 break;
381 }
382 }
383 }
384
385 create_dialog->popup_create(true);
386 } break;
387 case TOOL_INSTANCE: {
388
389 if (!profile_allow_editing) {
390 break;
391 }
392 Node *scene = edited_scene;
393
394 if (!scene) {
395 EditorNode::get_singleton()->new_inherited_scene();
396 break;
397 }
398
399 quick_open->popup_dialog("PackedScene", true);
400 quick_open->set_title(TTR("Instance Child Scene"));
401
402 } break;
403 case TOOL_EXPAND_COLLAPSE: {
404
405 if (!scene_tree->get_selected())
406 break;
407
408 Tree *tree = scene_tree->get_scene_tree();
409 TreeItem *selected_item = tree->get_selected();
410
411 if (!selected_item)
412 selected_item = tree->get_root();
413
414 bool collapsed = _is_collapsed_recursive(selected_item);
415 _set_collapsed_recursive(selected_item, !collapsed);
416
417 tree->ensure_cursor_is_visible();
418
419 } break;
420 case TOOL_REPLACE: {
421
422 if (!profile_allow_editing) {
423 break;
424 }
425
426 Node *selected = scene_tree->get_selected();
427 if (!selected && !editor_selection->get_selected_node_list().empty())
428 selected = editor_selection->get_selected_node_list().front()->get();
429
430 if (selected)
431 create_dialog->popup_create(false, true, selected->get_class());
432
433 } break;
434 case TOOL_EXTEND_SCRIPT: {
435 attach_script_to_selected(true);
436 } break;
437 case TOOL_ATTACH_SCRIPT: {
438 attach_script_to_selected(false);
439 } break;
440 case TOOL_DETACH_SCRIPT: {
441
442 if (!profile_allow_script_editing) {
443 break;
444 }
445
446 Array selection = editor_selection->get_selected_nodes();
447
448 if (selection.empty())
449 return;
450
451 editor_data->get_undo_redo().create_action(TTR("Detach Script"));
452 editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)NULL);
453
454 for (int i = 0; i < selection.size(); i++) {
455
456 Node *n = Object::cast_to<Node>(selection[i]);
457 Ref<Script> existing = n->get_script();
458 Ref<Script> empty = EditorNode::get_singleton()->get_object_custom_type_base(n);
459 if (existing != empty) {
460 editor_data->get_undo_redo().add_do_method(n, "set_script", empty);
461 editor_data->get_undo_redo().add_undo_method(n, "set_script", existing);
462 }
463 }
464
465 editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
466 editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
467
468 editor_data->get_undo_redo().commit_action();
469 } break;
470 case TOOL_MOVE_UP:
471 case TOOL_MOVE_DOWN: {
472
473 if (!profile_allow_editing) {
474 break;
475 }
476
477 if (!scene_tree->get_selected())
478 break;
479
480 if (scene_tree->get_selected() == edited_scene) {
481
482 current_option = -1;
483 accept->set_text(TTR("This operation can't be done on the tree root."));
484 accept->popup_centered_minsize();
485 break;
486 }
487
488 if (!_validate_no_foreign())
489 break;
490
491 bool MOVING_DOWN = (p_tool == TOOL_MOVE_DOWN);
492 bool MOVING_UP = !MOVING_DOWN;
493
494 Node *common_parent = scene_tree->get_selected()->get_parent();
495 List<Node *> selection = editor_selection->get_selected_node_list();
496 selection.sort_custom<Node::Comparator>(); // sort by index
497 if (MOVING_DOWN)
498 selection.invert();
499
500 int lowest_id = common_parent->get_child_count() - 1;
501 int highest_id = 0;
502 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
503 int index = E->get()->get_index();
504
505 if (index > highest_id) highest_id = index;
506 if (index < lowest_id) lowest_id = index;
507
508 if (E->get()->get_parent() != common_parent)
509 common_parent = NULL;
510 }
511
512 if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0))
513 break; // one or more nodes can not be moved
514
515 if (selection.size() == 1) editor_data->get_undo_redo().create_action(TTR("Move Node In Parent"));
516 if (selection.size() > 1) editor_data->get_undo_redo().create_action(TTR("Move Nodes In Parent"));
517
518 for (int i = 0; i < selection.size(); i++) {
519 Node *top_node = selection[i];
520 Node *bottom_node = selection[selection.size() - 1 - i];
521
522 ERR_FAIL_COND(!top_node->get_parent());
523 ERR_FAIL_COND(!bottom_node->get_parent());
524
525 int bottom_node_pos = bottom_node->get_index();
526 int top_node_pos_next = top_node->get_index() + (MOVING_DOWN ? 1 : -1);
527
528 editor_data->get_undo_redo().add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next);
529 editor_data->get_undo_redo().add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos);
530 }
531
532 editor_data->get_undo_redo().commit_action();
533
534 } break;
535 case TOOL_DUPLICATE: {
536
537 if (!profile_allow_editing) {
538 break;
539 }
540
541 if (!edited_scene)
542 break;
543
544 if (editor_selection->is_selected(edited_scene)) {
545
546 current_option = -1;
547 accept->set_text(TTR("This operation can't be done on the tree root."));
548 accept->popup_centered_minsize();
549 break;
550 }
551
552 if (!_validate_no_foreign())
553 break;
554
555 List<Node *> selection = editor_selection->get_selected_node_list();
556 if (selection.size() == 0)
557 break;
558
559 editor_data->get_undo_redo().create_action(TTR("Duplicate Node(s)"));
560 editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
561
562 Node *dupsingle = NULL;
563 List<Node *> editable_children;
564
565 selection.sort_custom<Node::Comparator>();
566
567 Node *add_below_node = selection.back()->get();
568
569 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
570
571 Node *node = E->get();
572 Node *parent = node->get_parent();
573
574 List<Node *> owned;
575 node->get_owned_by(node->get_owner(), &owned);
576
577 Map<const Node *, Node *> duplimap;
578 Node *dup = node->duplicate_from_editor(duplimap);
579
580 if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node))
581 editable_children.push_back(dup);
582
583 ERR_CONTINUE(!dup);
584
585 if (selection.size() == 1)
586 dupsingle = dup;
587
588 dup->set_name(parent->validate_child_name(dup));
589
590 editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", add_below_node, dup);
591 for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
592
593 if (!duplimap.has(F->get())) {
594
595 continue;
596 }
597 Node *d = duplimap[F->get()];
598 editor_data->get_undo_redo().add_do_method(d, "set_owner", node->get_owner());
599 }
600 editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup);
601 editor_data->get_undo_redo().add_undo_method(parent, "remove_child", dup);
602 editor_data->get_undo_redo().add_do_reference(dup);
603
604 ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
605
606 editor_data->get_undo_redo().add_do_method(sed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name());
607 editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(dup->get_name())));
608
609 add_below_node = dup;
610 }
611
612 editor_data->get_undo_redo().commit_action();
613
614 if (dupsingle)
615 editor->push_item(dupsingle);
616
617 for (List<Node *>::Element *E = editable_children.back(); E; E = E->prev())
618 _toggle_editable_children(E->get());
619
620 } break;
621 case TOOL_REPARENT: {
622
623 if (!profile_allow_editing) {
624 break;
625 }
626
627 if (!scene_tree->get_selected())
628 break;
629
630 if (editor_selection->is_selected(edited_scene)) {
631
632 current_option = -1;
633 accept->set_text(TTR("This operation can't be done on the tree root."));
634 accept->popup_centered_minsize();
635 break;
636 }
637
638 if (!_validate_no_foreign())
639 break;
640
641 List<Node *> nodes = editor_selection->get_selected_node_list();
642 Set<Node *> nodeset;
643 for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
644
645 nodeset.insert(E->get());
646 }
647 reparent_dialog->popup_centered_ratio();
648 reparent_dialog->set_current(nodeset);
649
650 } break;
651 case TOOL_MAKE_ROOT: {
652
653 if (!profile_allow_editing) {
654 break;
655 }
656
657 List<Node *> nodes = editor_selection->get_selected_node_list();
658 ERR_FAIL_COND(nodes.size() != 1);
659
660 Node *node = nodes.front()->get();
661 Node *root = get_tree()->get_edited_scene_root();
662
663 if (node == root)
664 return;
665
666 //check that from node to root, all owners are right
667
668 if (root->get_scene_inherited_state().is_valid()) {
669 accept->set_text(TTR("Can't reparent nodes in inherited scenes, order of nodes can't change."));
670 accept->popup_centered_minsize();
671 return;
672 }
673
674 if (node->get_owner() != root) {
675 accept->set_text(TTR("Node must belong to the edited scene to become root."));
676 accept->popup_centered_minsize();
677 return;
678 }
679
680 if (node->get_filename() != String()) {
681 accept->set_text(TTR("Instantiated scenes can't become root"));
682 accept->popup_centered_minsize();
683 return;
684 }
685
686 editor_data->get_undo_redo().create_action(TTR("Make node as Root"));
687 editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
688 editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", node);
689 editor_data->get_undo_redo().add_do_method(node, "add_child", root);
690 editor_data->get_undo_redo().add_do_method(node, "set_filename", root->get_filename());
691 editor_data->get_undo_redo().add_do_method(root, "set_filename", String());
692 editor_data->get_undo_redo().add_do_method(node, "set_owner", (Object *)NULL);
693 editor_data->get_undo_redo().add_do_method(root, "set_owner", node);
694 _node_replace_owner(root, root, node, MODE_DO);
695
696 editor_data->get_undo_redo().add_undo_method(root, "set_filename", root->get_filename());
697 editor_data->get_undo_redo().add_undo_method(node, "set_filename", String());
698 editor_data->get_undo_redo().add_undo_method(node, "remove_child", root);
699 editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", root);
700 editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node);
701 editor_data->get_undo_redo().add_undo_method(node->get_parent(), "move_child", node, node->get_index());
702 editor_data->get_undo_redo().add_undo_method(root, "set_owner", (Object *)NULL);
703 editor_data->get_undo_redo().add_undo_method(node, "set_owner", root);
704 _node_replace_owner(root, root, root, MODE_UNDO);
705
706 editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
707 editor_data->get_undo_redo().add_undo_method(scene_tree, "update_tree");
708 editor_data->get_undo_redo().commit_action();
709 } break;
710 case TOOL_MULTI_EDIT: {
711
712 if (!profile_allow_editing) {
713 break;
714 }
715
716 Node *root = EditorNode::get_singleton()->get_edited_scene();
717 if (!root)
718 break;
719 Ref<MultiNodeEdit> mne = memnew(MultiNodeEdit);
720 for (const Map<Node *, Object *>::Element *E = EditorNode::get_singleton()->get_editor_selection()->get_selection().front(); E; E = E->next()) {
721 mne->add_node(root->get_path_to(E->key()));
722 }
723
724 EditorNode::get_singleton()->push_item(mne.ptr());
725
726 } break;
727
728 case TOOL_ERASE: {
729
730 if (!profile_allow_editing) {
731 break;
732 }
733
734 List<Node *> remove_list = editor_selection->get_selected_node_list();
735
736 if (remove_list.empty())
737 return;
738
739 if (!_validate_no_foreign())
740 break;
741
742 if (p_confirm_override) {
743 _delete_confirm();
744
745 } else {
746 String msg;
747 if (remove_list.size() > 1) {
748 bool any_children = false;
749 for (int i = 0; !any_children && i < remove_list.size(); i++) {
750 any_children = remove_list[i]->get_child_count() > 0;
751 }
752
753 msg = vformat(any_children ? TTR("Delete %d nodes and any children?") : TTR("Delete %d nodes?"), remove_list.size());
754 } else {
755 Node *node = remove_list[0];
756 if (node == editor_data->get_edited_scene_root()) {
757 msg = vformat(TTR("Delete the root node \"%s\"?"), node->get_name());
758 } else if (node->get_filename() == "" && node->get_child_count() > 0) {
759 // Display this message only for non-instanced scenes
760 msg = vformat(TTR("Delete node \"%s\" and its children?"), node->get_name());
761 } else {
762 msg = vformat(TTR("Delete node \"%s\"?"), node->get_name());
763 }
764 }
765
766 delete_dialog->set_text(msg);
767
768 // Resize the dialog to its minimum size.
769 // This prevents the dialog from being too wide after displaying
770 // a deletion confirmation for a node with a long name.
771 delete_dialog->set_size(Size2());
772 delete_dialog->popup_centered_minsize();
773 }
774
775 } break;
776 case TOOL_MERGE_FROM_SCENE: {
777
778 if (!profile_allow_editing) {
779 break;
780 }
781
782 EditorNode::get_singleton()->merge_from_scene();
783 } break;
784 case TOOL_NEW_SCENE_FROM: {
785
786 if (!profile_allow_editing) {
787 break;
788 }
789
790 Node *scene = editor_data->get_edited_scene_root();
791
792 if (!scene) {
793 accept->set_text(TTR("This operation can't be done without a scene."));
794 accept->popup_centered_minsize();
795 break;
796 }
797
798 List<Node *> selection = editor_selection->get_selected_node_list();
799
800 if (selection.size() != 1) {
801 accept->set_text(TTR("This operation requires a single selected node."));
802 accept->popup_centered_minsize();
803 break;
804 }
805
806 Node *tocopy = selection.front()->get();
807
808 if (tocopy == scene) {
809 accept->set_text(TTR("Can not perform with the root node."));
810 accept->popup_centered_minsize();
811 break;
812 }
813
814 if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_filename() != "") {
815 accept->set_text(TTR("This operation can't be done on instanced scenes."));
816 accept->popup_centered_minsize();
817 break;
818 }
819
820 new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
821
822 List<String> extensions;
823 Ref<PackedScene> sd = memnew(PackedScene);
824 ResourceSaver::get_recognized_extensions(sd, &extensions);
825 new_scene_from_dialog->clear_filters();
826 for (int i = 0; i < extensions.size(); i++) {
827 new_scene_from_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
828 }
829
830 String existing;
831 if (extensions.size()) {
832 String root_name(tocopy->get_name());
833 existing = root_name + "." + extensions.front()->get().to_lower();
834 }
835 new_scene_from_dialog->set_current_path(existing);
836
837 new_scene_from_dialog->popup_centered_ratio();
838 new_scene_from_dialog->set_title(TTR("Save New Scene As..."));
839 } break;
840 case TOOL_COPY_NODE_PATH: {
841
842 List<Node *> selection = editor_selection->get_selected_node_list();
843 List<Node *>::Element *e = selection.front();
844 if (e) {
845 Node *node = e->get();
846 if (node) {
847 Node *root = EditorNode::get_singleton()->get_edited_scene();
848 NodePath path = root->get_path().rel_path_to(node->get_path());
849 OS::get_singleton()->set_clipboard(path);
850 }
851 }
852 } break;
853 case TOOL_OPEN_DOCUMENTATION: {
854 List<Node *> selection = editor_selection->get_selected_node_list();
855 for (int i = 0; i < selection.size(); i++) {
856 ScriptEditor::get_singleton()->goto_help("class_name:" + selection[i]->get_class());
857 }
858 EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
859 } break;
860 case TOOL_SCENE_EDITABLE_CHILDREN: {
861
862 if (!profile_allow_editing) {
863 break;
864 }
865
866 List<Node *> selection = editor_selection->get_selected_node_list();
867 List<Node *>::Element *e = selection.front();
868 if (e) {
869 Node *node = e->get();
870 if (node) {
871 bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
872
873 if (editable) {
874 editable_instance_remove_dialog->set_text(TTR("Disabling \"editable_instance\" will cause all properties of the node to be reverted to their default."));
875 editable_instance_remove_dialog->popup_centered_minsize();
876 break;
877 }
878 _toggle_editable_children(node);
879 }
880 }
881 } break;
882 case TOOL_SCENE_USE_PLACEHOLDER: {
883
884 if (!profile_allow_editing) {
885 break;
886 }
887
888 List<Node *> selection = editor_selection->get_selected_node_list();
889 List<Node *>::Element *e = selection.front();
890 if (e) {
891 Node *node = e->get();
892 if (node) {
893 bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
894 bool placeholder = node->get_scene_instance_load_placeholder();
895
896 // Fire confirmation dialog when children are editable.
897 if (editable && !placeholder) {
898 placeholder_editable_instance_remove_dialog->set_text(TTR("Enabling \"Load As Placeholder\" will disable \"Editable Children\" and cause all properties of the node to be reverted to their default."));
899 placeholder_editable_instance_remove_dialog->popup_centered_minsize();
900 break;
901 }
902
903 placeholder = !placeholder;
904
905 if (placeholder)
906 EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, false);
907
908 node->set_scene_instance_load_placeholder(placeholder);
909 scene_tree->update_tree();
910 }
911 }
912 } break;
913 case TOOL_SCENE_MAKE_LOCAL: {
914
915 if (!profile_allow_editing) {
916 break;
917 }
918
919 List<Node *> selection = editor_selection->get_selected_node_list();
920 List<Node *>::Element *e = selection.front();
921 if (e) {
922 Node *node = e->get();
923 if (node) {
924 Node *root = EditorNode::get_singleton()->get_edited_scene();
925 UndoRedo *undo_redo = &editor_data->get_undo_redo();
926 if (!root)
927 break;
928
929 ERR_FAIL_COND(node->get_filename() == String());
930 undo_redo->create_action(TTR("Make Local"));
931 undo_redo->add_do_method(node, "set_filename", "");
932 undo_redo->add_undo_method(node, "set_filename", node->get_filename());
933 _node_replace_owner(node, node, root);
934 undo_redo->add_do_method(scene_tree, "update_tree");
935 undo_redo->add_undo_method(scene_tree, "update_tree");
936 undo_redo->commit_action();
937 }
938 }
939 } break;
940 case TOOL_SCENE_OPEN: {
941
942 List<Node *> selection = editor_selection->get_selected_node_list();
943 List<Node *>::Element *e = selection.front();
944 if (e) {
945 Node *node = e->get();
946 if (node) {
947 scene_tree->emit_signal("open", node->get_filename());
948 }
949 }
950 } break;
951 case TOOL_SCENE_CLEAR_INHERITANCE: {
952 if (!profile_allow_editing) {
953 break;
954 }
955
956 clear_inherit_confirm->popup_centered_minsize();
957 } break;
958 case TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM: {
959 if (!profile_allow_editing) {
960 break;
961 }
962
963 List<Node *> selection = editor_selection->get_selected_node_list();
964 List<Node *>::Element *e = selection.front();
965 if (e) {
966 Node *node = e->get();
967 if (node) {
968 node->set_scene_inherited_state(Ref<SceneState>());
969 scene_tree->update_tree();
970 EditorNode::get_singleton()->get_inspector()->update_tree();
971 }
972 }
973 } break;
974 case TOOL_SCENE_OPEN_INHERITED: {
975
976 List<Node *> selection = editor_selection->get_selected_node_list();
977 List<Node *>::Element *e = selection.front();
978 if (e) {
979 Node *node = e->get();
980 if (node && node->get_scene_inherited_state().is_valid()) {
981 scene_tree->emit_signal("open", node->get_scene_inherited_state()->get_path());
982 }
983 }
984 } break;
985 case TOOL_CREATE_2D_SCENE:
986 case TOOL_CREATE_3D_SCENE:
987 case TOOL_CREATE_USER_INTERFACE:
988 case TOOL_CREATE_FAVORITE: {
989
990 Node *new_node = NULL;
991
992 if (TOOL_CREATE_FAVORITE == p_tool) {
993 String name = selected_favorite_root.get_slicec(' ', 0);
994 if (ScriptServer::is_global_class(name)) {
995 new_node = Object::cast_to<Node>(ClassDB::instance(ScriptServer::get_global_class_native_base(name)));
996 Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script");
997 if (new_node && script.is_valid()) {
998 new_node->set_script(script.get_ref_ptr());
999 new_node->set_name(name);
1000 }
1001 } else {
1002 new_node = Object::cast_to<Node>(ClassDB::instance(selected_favorite_root));
1003 }
1004
1005 if (!new_node) {
1006 new_node = memnew(Node);
1007 ERR_PRINTS("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead.");
1008 }
1009 } else {
1010 switch (p_tool) {
1011 case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break;
1012 case TOOL_CREATE_3D_SCENE: new_node = memnew(Spatial); break;
1013 case TOOL_CREATE_USER_INTERFACE: {
1014 Control *node = memnew(Control);
1015 node->set_anchors_and_margins_preset(PRESET_WIDE); //more useful for resizable UIs.
1016 new_node = node;
1017
1018 } break;
1019 }
1020 }
1021
1022 editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
1023 editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", new_node);
1024 editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
1025 editor_data->get_undo_redo().add_do_reference(new_node);
1026 editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL);
1027 editor_data->get_undo_redo().commit_action();
1028
1029 editor->edit_node(new_node);
1030 editor_selection->clear();
1031 editor_selection->add_node(new_node);
1032
1033 } break;
1034
1035 default: {
1036
1037 if (p_tool >= EDIT_SUBRESOURCE_BASE) {
1038
1039 int idx = p_tool - EDIT_SUBRESOURCE_BASE;
1040
1041 ERR_FAIL_INDEX(idx, subresources.size());
1042
1043 Object *obj = ObjectDB::get_instance(subresources[idx]);
1044 ERR_FAIL_COND(!obj);
1045
1046 editor->push_item(obj);
1047 }
1048 }
1049 }
1050 }
1051
_node_collapsed(Object * p_obj)1052 void SceneTreeDock::_node_collapsed(Object *p_obj) {
1053
1054 TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
1055 if (!ti)
1056 return;
1057
1058 if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
1059 _set_collapsed_recursive(ti, ti->is_collapsed());
1060 }
1061 }
1062
_notification(int p_what)1063 void SceneTreeDock::_notification(int p_what) {
1064
1065 switch (p_what) {
1066 case NOTIFICATION_READY: {
1067
1068 if (!first_enter)
1069 break;
1070 first_enter = false;
1071
1072 EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", this, "_feature_profile_changed");
1073
1074 CanvasItemEditorPlugin *canvas_item_plugin = Object::cast_to<CanvasItemEditorPlugin>(editor_data->get_editor("2D"));
1075 if (canvas_item_plugin) {
1076 canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
1077 canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
1078 scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
1079 }
1080
1081 SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
1082 spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
1083 spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
1084
1085 button_add->set_icon(get_icon("Add", "EditorIcons"));
1086 button_instance->set_icon(get_icon("Instance", "EditorIcons"));
1087 button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
1088 button_detach_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
1089
1090 filter->set_right_icon(get_icon("Search", "EditorIcons"));
1091 filter->set_clear_button_enabled(true);
1092
1093 EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed");
1094 scene_tree->get_scene_tree()->connect("item_collapsed", this, "_node_collapsed");
1095
1096 // create_root_dialog
1097 HBoxContainer *top_row = memnew(HBoxContainer);
1098 top_row->set_name("NodeShortcutsTopRow");
1099 top_row->set_h_size_flags(SIZE_EXPAND_FILL);
1100 top_row->add_child(memnew(Label(TTR("Create Root Node:"))));
1101 top_row->add_spacer();
1102
1103 ToolButton *node_shortcuts_toggle = memnew(ToolButton);
1104 node_shortcuts_toggle->set_name("NodeShortcutsToggle");
1105 node_shortcuts_toggle->set_icon(get_icon("Favorites", "EditorIcons"));
1106 node_shortcuts_toggle->set_toggle_mode(true);
1107 node_shortcuts_toggle->set_pressed(EDITOR_GET("_use_favorites_root_selection"));
1108 node_shortcuts_toggle->set_anchors_and_margins_preset(Control::PRESET_CENTER_RIGHT);
1109 node_shortcuts_toggle->connect("pressed", this, "_update_create_root_dialog");
1110 top_row->add_child(node_shortcuts_toggle);
1111
1112 create_root_dialog->add_child(top_row);
1113
1114 VBoxContainer *node_shortcuts = memnew(VBoxContainer);
1115 node_shortcuts->set_name("NodeShortcuts");
1116
1117 VBoxContainer *beginner_node_shortcuts = memnew(VBoxContainer);
1118 beginner_node_shortcuts->set_name("BeginnerNodeShortcuts");
1119 node_shortcuts->add_child(beginner_node_shortcuts);
1120
1121 Button *button_2d = memnew(Button);
1122 beginner_node_shortcuts->add_child(button_2d);
1123 button_2d->set_text(TTR("2D Scene"));
1124 button_2d->set_icon(get_icon("Node2D", "EditorIcons"));
1125 button_2d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_2D_SCENE, false));
1126 button_3d = memnew(Button);
1127 beginner_node_shortcuts->add_child(button_3d);
1128 button_3d->set_text(TTR("3D Scene"));
1129 button_3d->set_icon(get_icon("Spatial", "EditorIcons"));
1130 button_3d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_3D_SCENE, false));
1131
1132 Button *button_ui = memnew(Button);
1133 beginner_node_shortcuts->add_child(button_ui);
1134 button_ui->set_text(TTR("User Interface"));
1135 button_ui->set_icon(get_icon("Control", "EditorIcons"));
1136 button_ui->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_USER_INTERFACE, false));
1137
1138 VBoxContainer *favorite_node_shortcuts = memnew(VBoxContainer);
1139 favorite_node_shortcuts->set_name("FavoriteNodeShortcuts");
1140 node_shortcuts->add_child(favorite_node_shortcuts);
1141
1142 Button *button_custom = memnew(Button);
1143 node_shortcuts->add_child(button_custom);
1144 button_custom->set_text(TTR("Other Node"));
1145 button_custom->set_icon(get_icon("Add", "EditorIcons"));
1146 button_custom->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false));
1147
1148 node_shortcuts->add_spacer();
1149 create_root_dialog->add_child(node_shortcuts);
1150 _update_create_root_dialog();
1151 } break;
1152
1153 case NOTIFICATION_ENTER_TREE: {
1154 clear_inherit_confirm->connect("confirmed", this, "_tool_selected", varray(TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM));
1155 } break;
1156
1157 case NOTIFICATION_EXIT_TREE: {
1158 clear_inherit_confirm->disconnect("confirmed", this, "_tool_selected");
1159 } break;
1160 case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
1161 button_add->set_icon(get_icon("Add", "EditorIcons"));
1162 button_instance->set_icon(get_icon("Instance", "EditorIcons"));
1163 button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
1164 button_detach_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
1165
1166 filter->set_right_icon(get_icon("Search", "EditorIcons"));
1167 filter->set_clear_button_enabled(true);
1168 } break;
1169 case NOTIFICATION_PROCESS: {
1170
1171 bool show_create_root = bool(EDITOR_GET("interface/editors/show_scene_tree_root_selection")) && get_tree()->get_edited_scene_root() == NULL;
1172
1173 if (show_create_root != create_root_dialog->is_visible_in_tree() && !remote_tree->is_visible()) {
1174 if (show_create_root) {
1175 create_root_dialog->show();
1176 scene_tree->hide();
1177 } else {
1178 create_root_dialog->hide();
1179 scene_tree->show();
1180 }
1181 }
1182
1183 } break;
1184 }
1185 }
1186
_node_replace_owner(Node * p_base,Node * p_node,Node * p_root,ReplaceOwnerMode p_mode)1187 void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) {
1188
1189 if (p_node->get_owner() == p_base && p_node != p_root) {
1190 UndoRedo *undo_redo = &editor_data->get_undo_redo();
1191 switch (p_mode) {
1192 case MODE_BIDI: {
1193 undo_redo->add_do_method(p_node, "set_owner", p_root);
1194 undo_redo->add_undo_method(p_node, "set_owner", p_base);
1195
1196 } break;
1197 case MODE_DO: {
1198 undo_redo->add_do_method(p_node, "set_owner", p_root);
1199
1200 } break;
1201 case MODE_UNDO: {
1202 undo_redo->add_undo_method(p_node, "set_owner", p_root);
1203
1204 } break;
1205 }
1206 }
1207
1208 for (int i = 0; i < p_node->get_child_count(); i++) {
1209 _node_replace_owner(p_base, p_node->get_child(i), p_root, p_mode);
1210 }
1211 }
1212
_load_request(const String & p_path)1213 void SceneTreeDock::_load_request(const String &p_path) {
1214
1215 editor->open_request(p_path);
1216 }
1217
_script_open_request(const Ref<Script> & p_script)1218 void SceneTreeDock::_script_open_request(const Ref<Script> &p_script) {
1219
1220 editor->edit_resource(p_script);
1221 }
1222
_node_selected()1223 void SceneTreeDock::_node_selected() {
1224
1225 Node *node = scene_tree->get_selected();
1226
1227 if (!node) {
1228
1229 editor->push_item(NULL);
1230 return;
1231 }
1232
1233 if (ScriptEditor::get_singleton()->is_visible_in_tree()) {
1234 restore_script_editor_on_drag = true;
1235 }
1236
1237 editor->push_item(node);
1238 }
1239
_node_renamed()1240 void SceneTreeDock::_node_renamed() {
1241
1242 _node_selected();
1243 }
1244
_set_owners(Node * p_owner,const Array & p_nodes)1245 void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) {
1246
1247 for (int i = 0; i < p_nodes.size(); i++) {
1248
1249 Node *n = Object::cast_to<Node>(p_nodes[i]);
1250 if (!n)
1251 continue;
1252 n->set_owner(p_owner);
1253 }
1254 }
1255
_fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node,List<Pair<NodePath,NodePath>> * p_renames)1256 void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath> > *p_renames) {
1257
1258 base_path.push_back(p_node->get_name());
1259 if (new_base_path.size())
1260 new_base_path.push_back(p_node->get_name());
1261
1262 NodePath from(base_path, true);
1263 NodePath to;
1264 if (new_base_path.size())
1265 to = NodePath(new_base_path, true);
1266
1267 Pair<NodePath, NodePath> npp;
1268 npp.first = from;
1269 npp.second = to;
1270
1271 p_renames->push_back(npp);
1272
1273 for (int i = 0; i < p_node->get_child_count(); i++) {
1274
1275 _fill_path_renames(base_path, new_base_path, p_node->get_child(i), p_renames);
1276 }
1277 }
1278
fill_path_renames(Node * p_node,Node * p_new_parent,List<Pair<NodePath,NodePath>> * p_renames)1279 void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath> > *p_renames) {
1280
1281 if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true)))
1282 return;
1283
1284 Vector<StringName> base_path;
1285 Node *n = p_node->get_parent();
1286 while (n) {
1287 base_path.push_back(n->get_name());
1288 n = n->get_parent();
1289 }
1290 base_path.invert();
1291
1292 Vector<StringName> new_base_path;
1293 if (p_new_parent) {
1294 n = p_new_parent;
1295 while (n) {
1296 new_base_path.push_back(n->get_name());
1297 n = n->get_parent();
1298 }
1299
1300 new_base_path.invert();
1301 }
1302
1303 _fill_path_renames(base_path, new_base_path, p_node, p_renames);
1304 }
1305
perform_node_renames(Node * p_base,List<Pair<NodePath,NodePath>> * p_renames,Map<Ref<Animation>,Set<int>> * r_rem_anims)1306 void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims) {
1307
1308 Map<Ref<Animation>, Set<int> > rem_anims;
1309
1310 if (!r_rem_anims)
1311 r_rem_anims = &rem_anims;
1312
1313 if (!p_base) {
1314
1315 p_base = edited_scene;
1316 }
1317
1318 if (!p_base)
1319 return;
1320
1321 // Renaming node paths used in script instances
1322 if (p_base->get_script_instance()) {
1323
1324 ScriptInstance *si = p_base->get_script_instance();
1325
1326 if (si) {
1327
1328 List<PropertyInfo> properties;
1329 si->get_property_list(&properties);
1330
1331 for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
1332
1333 String propertyname = E->get().name;
1334 Variant p = p_base->get(propertyname);
1335 if (p.get_type() == Variant::NODE_PATH) {
1336
1337 // Goes through all paths to check if its matching
1338 for (List<Pair<NodePath, NodePath> >::Element *F = p_renames->front(); F; F = F->next()) {
1339
1340 NodePath root_path = p_base->get_path();
1341
1342 NodePath rel_path_old = root_path.rel_path_to(F->get().first);
1343
1344 NodePath rel_path_new = F->get().second;
1345
1346 // if not empty, get new relative path
1347 if (F->get().second != NodePath()) {
1348 rel_path_new = root_path.rel_path_to(F->get().second);
1349 }
1350
1351 // if old path detected, then it needs to be replaced with the new one
1352 if (p == rel_path_old) {
1353
1354 editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new);
1355 editor_data->get_undo_redo().add_undo_property(p_base, propertyname, rel_path_old);
1356
1357 p_base->set(propertyname, rel_path_new);
1358 break;
1359 }
1360 }
1361 }
1362 }
1363 }
1364 }
1365
1366 bool autorename_animation_tracks = bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true));
1367
1368 if (autorename_animation_tracks && Object::cast_to<AnimationPlayer>(p_base)) {
1369
1370 AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_base);
1371 List<StringName> anims;
1372 ap->get_animation_list(&anims);
1373 Node *root = ap->get_node(ap->get_root());
1374
1375 if (root) {
1376
1377 NodePath root_path = root->get_path();
1378 NodePath new_root_path = root_path;
1379
1380 for (List<Pair<NodePath, NodePath> >::Element *E = p_renames->front(); E; E = E->next()) {
1381
1382 if (E->get().first == root_path) {
1383 new_root_path = E->get().second;
1384 break;
1385 }
1386 }
1387
1388 if (new_root_path != NodePath()) {
1389 //will not be erased
1390
1391 for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
1392
1393 Ref<Animation> anim = ap->get_animation(E->get());
1394 if (!r_rem_anims->has(anim)) {
1395 r_rem_anims->insert(anim, Set<int>());
1396 Set<int> &ran = r_rem_anims->find(anim)->get();
1397 for (int i = 0; i < anim->get_track_count(); i++)
1398 ran.insert(i);
1399 }
1400
1401 Set<int> &ran = r_rem_anims->find(anim)->get();
1402
1403 if (anim.is_null())
1404 continue;
1405
1406 for (int i = 0; i < anim->get_track_count(); i++) {
1407
1408 NodePath track_np = anim->track_get_path(i);
1409 Node *n = root->get_node(track_np);
1410 if (!n) {
1411 continue;
1412 }
1413
1414 NodePath old_np = n->get_path();
1415
1416 if (!ran.has(i))
1417 continue; //channel was removed
1418
1419 for (List<Pair<NodePath, NodePath> >::Element *F = p_renames->front(); F; F = F->next()) {
1420
1421 if (F->get().first == old_np) {
1422
1423 if (F->get().second == NodePath()) {
1424 //will be erased
1425
1426 int idx = 0;
1427 Set<int>::Element *EI = ran.front();
1428 ERR_FAIL_COND(!EI); //bug
1429 while (EI->get() != i) {
1430 idx++;
1431 EI = EI->next();
1432 ERR_FAIL_COND(!EI); //another bug
1433 }
1434
1435 editor_data->get_undo_redo().add_do_method(anim.ptr(), "remove_track", idx);
1436 editor_data->get_undo_redo().add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx);
1437 editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", idx, track_np);
1438 editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i));
1439 for (int j = 0; j < anim->track_get_key_count(i); j++) {
1440
1441 editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j));
1442 }
1443
1444 ran.erase(i); //byebye channel
1445
1446 } else {
1447 //will be renamed
1448 NodePath rel_path = new_root_path.rel_path_to(F->get().second);
1449
1450 NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false);
1451 if (new_path == track_np)
1452 continue; //bleh
1453 editor_data->get_undo_redo().add_do_method(anim.ptr(), "track_set_path", i, new_path);
1454 editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", i, track_np);
1455 }
1456 }
1457 }
1458 }
1459 }
1460 }
1461 }
1462 }
1463
1464 for (int i = 0; i < p_base->get_child_count(); i++)
1465 perform_node_renames(p_base->get_child(i), p_renames, r_rem_anims);
1466 }
1467
_node_prerenamed(Node * p_node,const String & p_new_name)1468 void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) {
1469
1470 List<Pair<NodePath, NodePath> > path_renames;
1471
1472 Vector<StringName> base_path;
1473 Node *n = p_node->get_parent();
1474 while (n) {
1475 base_path.push_back(n->get_name());
1476 n = n->get_parent();
1477 }
1478 base_path.invert();
1479
1480 Vector<StringName> new_base_path = base_path;
1481 base_path.push_back(p_node->get_name());
1482
1483 new_base_path.push_back(p_new_name);
1484
1485 Pair<NodePath, NodePath> npp;
1486 npp.first = NodePath(base_path, true);
1487 npp.second = NodePath(new_base_path, true);
1488 path_renames.push_back(npp);
1489
1490 for (int i = 0; i < p_node->get_child_count(); i++)
1491 _fill_path_renames(base_path, new_base_path, p_node->get_child(i), &path_renames);
1492
1493 perform_node_renames(NULL, &path_renames);
1494 }
1495
_validate_no_foreign()1496 bool SceneTreeDock::_validate_no_foreign() {
1497
1498 List<Node *> selection = editor_selection->get_selected_node_list();
1499
1500 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
1501
1502 if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) {
1503
1504 accept->set_text(TTR("Can't operate on nodes from a foreign scene!"));
1505 accept->popup_centered_minsize();
1506 return false;
1507 }
1508
1509 // When edited_scene inherits from another one the root Node will be the parent Scene,
1510 // we don't want to consider that Node a foreign one otherwise we would not be able to
1511 // delete it.
1512 if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) {
1513 continue;
1514 }
1515
1516 if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) {
1517
1518 accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
1519 accept->popup_centered_minsize();
1520 return false;
1521 }
1522 }
1523
1524 return true;
1525 }
1526
_node_reparent(NodePath p_path,bool p_keep_global_xform)1527 void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
1528
1529 Node *new_parent = scene_root->get_node(p_path);
1530 ERR_FAIL_COND(!new_parent);
1531
1532 List<Node *> selection = editor_selection->get_selected_node_list();
1533
1534 if (selection.empty())
1535 return; // Nothing to reparent.
1536
1537 Vector<Node *> nodes;
1538
1539 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
1540 nodes.push_back(E->get());
1541 }
1542
1543 _do_reparent(new_parent, -1, nodes, p_keep_global_xform);
1544 }
1545
_do_reparent(Node * p_new_parent,int p_position_in_parent,Vector<Node * > p_nodes,bool p_keep_global_xform)1546 void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform) {
1547
1548 Node *new_parent = p_new_parent;
1549 ERR_FAIL_COND(!new_parent);
1550
1551 if (p_nodes.size() == 0)
1552 return; // Nothing to reparent.
1553
1554 p_nodes.sort_custom<Node::Comparator>(); //Makes result reliable.
1555
1556 bool no_change = true;
1557 for (int ni = 0; ni < p_nodes.size(); ni++) {
1558
1559 if (p_nodes[ni] == p_new_parent)
1560 return; // Attempt to reparent to itself.
1561
1562 if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_position_in_parent())
1563 no_change = false;
1564 }
1565
1566 if (no_change)
1567 return; // Position and parent didn't change.
1568
1569 Node *validate = new_parent;
1570 while (validate) {
1571
1572 ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent.");
1573 validate = validate->get_parent();
1574 }
1575
1576 // Sort by tree order, so re-adding is easy.
1577 p_nodes.sort_custom<Node::Comparator>();
1578
1579 editor_data->get_undo_redo().create_action(TTR("Reparent Node"));
1580
1581 List<Pair<NodePath, NodePath> > path_renames;
1582 Vector<StringName> former_names;
1583
1584 int inc = 0;
1585
1586 for (int ni = 0; ni < p_nodes.size(); ni++) {
1587
1588 // No undo implemented for this yet.
1589 Node *node = p_nodes[ni];
1590
1591 fill_path_renames(node, new_parent, &path_renames);
1592 former_names.push_back(node->get_name());
1593
1594 List<Node *> owned;
1595 node->get_owned_by(node->get_owner(), &owned);
1596 Array owners;
1597 for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
1598 owners.push_back(E->get());
1599 }
1600
1601 if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni)
1602 inc--; // If the child will generate a gap when moved, adjust.
1603
1604 editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
1605 editor_data->get_undo_redo().add_do_method(new_parent, "add_child", node);
1606
1607 if (p_position_in_parent >= 0)
1608 editor_data->get_undo_redo().add_do_method(new_parent, "move_child", node, p_position_in_parent + inc);
1609
1610 ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
1611 String old_name = former_names[ni];
1612 String new_name = new_parent->validate_child_name(node);
1613
1614 // Name was modified, fix the path renames.
1615 if (old_name.casecmp_to(new_name) != 0) {
1616
1617 // Fix the to name to have the new name.
1618 NodePath old_new_name = path_renames[ni].second;
1619 NodePath new_path;
1620
1621 Vector<StringName> unfixed_new_names = old_new_name.get_names();
1622 Vector<StringName> fixed_new_names;
1623
1624 // Get last name and replace with fixed new name.
1625 for (int a = 0; a < (unfixed_new_names.size() - 1); a++) {
1626 fixed_new_names.push_back(unfixed_new_names[a]);
1627 }
1628 fixed_new_names.push_back(new_name);
1629
1630 NodePath fixed_node_path = NodePath(fixed_new_names, true);
1631
1632 path_renames[ni].second = fixed_node_path;
1633 }
1634
1635 editor_data->get_undo_redo().add_do_method(sed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, p_position_in_parent + inc);
1636 editor_data->get_undo_redo().add_undo_method(sed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).plus_file(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index());
1637
1638 if (p_keep_global_xform) {
1639 if (Object::cast_to<Node2D>(node))
1640 editor_data->get_undo_redo().add_do_method(node, "set_global_transform", Object::cast_to<Node2D>(node)->get_global_transform());
1641 if (Object::cast_to<Spatial>(node))
1642 editor_data->get_undo_redo().add_do_method(node, "set_global_transform", Object::cast_to<Spatial>(node)->get_global_transform());
1643 if (Object::cast_to<Control>(node))
1644 editor_data->get_undo_redo().add_do_method(node, "set_global_position", Object::cast_to<Control>(node)->get_global_position());
1645 }
1646
1647 editor_data->get_undo_redo().add_do_method(this, "_set_owners", edited_scene, owners);
1648
1649 if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node)
1650 editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
1651
1652 editor_data->get_undo_redo().add_undo_method(new_parent, "remove_child", node);
1653 editor_data->get_undo_redo().add_undo_method(node, "set_name", former_names[ni]);
1654
1655 inc++;
1656 }
1657
1658 // Add and move in a second step (so old order is preserved).
1659 for (int ni = 0; ni < p_nodes.size(); ni++) {
1660
1661 Node *node = p_nodes[ni];
1662
1663 List<Node *> owned;
1664 node->get_owned_by(node->get_owner(), &owned);
1665 Array owners;
1666 for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
1667
1668 owners.push_back(E->get());
1669 }
1670
1671 int child_pos = node->get_position_in_parent();
1672
1673 editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node);
1674 editor_data->get_undo_redo().add_undo_method(node->get_parent(), "move_child", node, child_pos);
1675 editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
1676 if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node)
1677 editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
1678
1679 if (p_keep_global_xform) {
1680 if (Object::cast_to<Node2D>(node))
1681 editor_data->get_undo_redo().add_undo_method(node, "set_transform", Object::cast_to<Node2D>(node)->get_transform());
1682 if (Object::cast_to<Spatial>(node))
1683 editor_data->get_undo_redo().add_undo_method(node, "set_transform", Object::cast_to<Spatial>(node)->get_transform());
1684 if (Object::cast_to<Control>(node))
1685 editor_data->get_undo_redo().add_undo_method(node, "set_position", Object::cast_to<Control>(node)->get_position());
1686 }
1687 }
1688
1689 perform_node_renames(NULL, &path_renames);
1690
1691 editor_data->get_undo_redo().commit_action();
1692 }
1693
_is_collapsed_recursive(TreeItem * p_item) const1694 bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
1695
1696 bool is_branch_collapsed = false;
1697
1698 List<TreeItem *> needs_check;
1699 needs_check.push_back(p_item);
1700
1701 while (!needs_check.empty()) {
1702
1703 TreeItem *item = needs_check.back()->get();
1704 needs_check.pop_back();
1705
1706 TreeItem *child = item->get_children();
1707 is_branch_collapsed = item->is_collapsed() && child;
1708
1709 if (is_branch_collapsed) {
1710 break;
1711 }
1712 while (child) {
1713 needs_check.push_back(child);
1714 child = child->get_next();
1715 }
1716 }
1717 return is_branch_collapsed;
1718 }
1719
_set_collapsed_recursive(TreeItem * p_item,bool p_collapsed)1720 void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) {
1721
1722 List<TreeItem *> to_collapse;
1723 to_collapse.push_back(p_item);
1724
1725 while (!to_collapse.empty()) {
1726
1727 TreeItem *item = to_collapse.back()->get();
1728 to_collapse.pop_back();
1729
1730 item->set_collapsed(p_collapsed);
1731
1732 TreeItem *child = item->get_children();
1733 while (child) {
1734 to_collapse.push_back(child);
1735 child = child->get_next();
1736 }
1737 }
1738 }
1739
_script_created(Ref<Script> p_script)1740 void SceneTreeDock::_script_created(Ref<Script> p_script) {
1741
1742 List<Node *> selected = editor_selection->get_selected_node_list();
1743
1744 if (selected.empty())
1745 return;
1746
1747 editor_data->get_undo_redo().create_action(TTR("Attach Script"));
1748 for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
1749
1750 Ref<Script> existing = E->get()->get_script();
1751 editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr());
1752 editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
1753 editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
1754 editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
1755 }
1756
1757 editor_data->get_undo_redo().commit_action();
1758
1759 editor->push_item(p_script.operator->());
1760 _update_script_button();
1761 }
1762
_script_creation_closed()1763 void SceneTreeDock::_script_creation_closed() {
1764 script_create_dialog->disconnect("script_created", this, "_script_created");
1765 }
1766
_toggle_editable_children_from_selection()1767 void SceneTreeDock::_toggle_editable_children_from_selection() {
1768
1769 List<Node *> selection = editor_selection->get_selected_node_list();
1770 List<Node *>::Element *e = selection.front();
1771
1772 if (e) {
1773 _toggle_editable_children(e->get());
1774 }
1775 }
1776
_toggle_placeholder_from_selection()1777 void SceneTreeDock::_toggle_placeholder_from_selection() {
1778
1779 List<Node *> selection = editor_selection->get_selected_node_list();
1780 List<Node *>::Element *e = selection.front();
1781
1782 if (e) {
1783 Node *node = e->get();
1784 if (node) {
1785 _toggle_editable_children(node);
1786
1787 bool placeholder = node->get_scene_instance_load_placeholder();
1788 placeholder = !placeholder;
1789
1790 node->set_scene_instance_load_placeholder(placeholder);
1791 scene_tree->update_tree();
1792 }
1793 }
1794 }
1795
_toggle_editable_children(Node * p_node)1796 void SceneTreeDock::_toggle_editable_children(Node *p_node) {
1797
1798 if (p_node) {
1799 bool editable = !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node);
1800 EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(p_node, editable);
1801 if (editable)
1802 p_node->set_scene_instance_load_placeholder(false);
1803
1804 SpatialEditor::get_singleton()->update_all_gizmos(p_node);
1805
1806 scene_tree->update_tree();
1807 }
1808 }
1809
_delete_confirm()1810 void SceneTreeDock::_delete_confirm() {
1811
1812 List<Node *> remove_list = editor_selection->get_selected_node_list();
1813
1814 if (remove_list.empty())
1815 return;
1816
1817 editor->get_editor_plugins_over()->make_visible(false);
1818
1819 editor_data->get_undo_redo().create_action(TTR("Remove Node(s)"));
1820
1821 bool entire_scene = false;
1822
1823 for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
1824
1825 if (E->get() == edited_scene) {
1826 entire_scene = true;
1827 }
1828 }
1829
1830 if (entire_scene) {
1831
1832 editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", (Object *)NULL);
1833 editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", edited_scene);
1834 editor_data->get_undo_redo().add_undo_method(edited_scene, "set_owner", edited_scene->get_owner());
1835 editor_data->get_undo_redo().add_undo_method(scene_tree, "update_tree");
1836 editor_data->get_undo_redo().add_undo_reference(edited_scene);
1837
1838 } else {
1839
1840 remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions
1841 List<Pair<NodePath, NodePath> > path_renames;
1842
1843 //delete from animation
1844 for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
1845 Node *n = E->get();
1846 if (!n->is_inside_tree() || !n->get_parent())
1847 continue;
1848
1849 fill_path_renames(n, NULL, &path_renames);
1850 }
1851
1852 perform_node_renames(NULL, &path_renames);
1853 //delete for read
1854 for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
1855 Node *n = E->get();
1856 if (!n->is_inside_tree() || !n->get_parent())
1857 continue;
1858
1859 List<Node *> owned;
1860 n->get_owned_by(n->get_owner(), &owned);
1861 Array owners;
1862 for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
1863
1864 owners.push_back(F->get());
1865 }
1866
1867 editor_data->get_undo_redo().add_do_method(n->get_parent(), "remove_child", n);
1868 editor_data->get_undo_redo().add_undo_method(n->get_parent(), "add_child", n);
1869 editor_data->get_undo_redo().add_undo_method(n->get_parent(), "move_child", n, n->get_index());
1870 if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == n)
1871 editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", n);
1872 editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
1873 editor_data->get_undo_redo().add_undo_reference(n);
1874
1875 ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
1876 editor_data->get_undo_redo().add_do_method(sed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id());
1877 editor_data->get_undo_redo().add_undo_method(sed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index());
1878 }
1879 }
1880 editor_data->get_undo_redo().commit_action();
1881
1882 // hack, force 2d editor viewport to refresh after deletion
1883 if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton())
1884 editor->get_viewport_control()->update();
1885
1886 editor->push_item(NULL);
1887
1888 // Fixes the EditorHistory from still offering deleted notes
1889 EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
1890 editor_history->cleanup_history();
1891 EditorNode::get_singleton()->get_inspector_dock()->call("_prepare_history");
1892 }
1893
_update_script_button()1894 void SceneTreeDock::_update_script_button() {
1895
1896 if (!profile_allow_script_editing) {
1897
1898 button_create_script->hide();
1899 button_detach_script->hide();
1900 } else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 0) {
1901 button_create_script->hide();
1902 button_detach_script->hide();
1903 } else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
1904 Node *n = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0];
1905 if (n->get_script().is_null()) {
1906 button_create_script->show();
1907 button_detach_script->hide();
1908 } else {
1909 button_create_script->hide();
1910 button_detach_script->show();
1911 }
1912 } else {
1913 button_create_script->hide();
1914 Array selection = editor_selection->get_selected_nodes();
1915 for (int i = 0; i < selection.size(); i++) {
1916 Node *n = Object::cast_to<Node>(selection[i]);
1917 if (!n->get_script().is_null()) {
1918 button_detach_script->show();
1919 return;
1920 }
1921 }
1922 button_detach_script->hide();
1923 }
1924 }
1925
_selection_changed()1926 void SceneTreeDock::_selection_changed() {
1927
1928 int selection_size = EditorNode::get_singleton()->get_editor_selection()->get_selection().size();
1929 if (selection_size > 1) {
1930 //automatically turn on multi-edit
1931 _tool_selected(TOOL_MULTI_EDIT);
1932 } else if (selection_size == 1) {
1933 editor->push_item(EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0]);
1934 } else {
1935 editor->push_item(NULL);
1936 }
1937 _update_script_button();
1938 }
1939
_get_selection_group_tail(Node * p_node,List<Node * > p_list)1940 Node *SceneTreeDock::_get_selection_group_tail(Node *p_node, List<Node *> p_list) {
1941
1942 Node *tail = p_node;
1943 Node *parent = tail->get_parent();
1944
1945 for (int i = p_node->get_position_in_parent(); i < parent->get_child_count(); i++) {
1946 Node *sibling = parent->get_child(i);
1947
1948 if (p_list.find(sibling))
1949 tail = sibling;
1950 else
1951 break;
1952 }
1953
1954 return tail;
1955 }
1956
_do_create(Node * p_parent)1957 void SceneTreeDock::_do_create(Node *p_parent) {
1958 Object *c = create_dialog->instance_selected();
1959
1960 ERR_FAIL_COND(!c);
1961 Node *child = Object::cast_to<Node>(c);
1962 ERR_FAIL_COND(!child);
1963
1964 editor_data->get_undo_redo().create_action(TTR("Create Node"));
1965
1966 if (edited_scene) {
1967
1968 editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child);
1969 editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene);
1970 editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
1971 editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child);
1972 editor_data->get_undo_redo().add_do_reference(child);
1973 editor_data->get_undo_redo().add_undo_method(p_parent, "remove_child", child);
1974
1975 String new_name = p_parent->validate_child_name(child);
1976 ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
1977 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);
1978 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)));
1979
1980 } else {
1981
1982 editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child);
1983 editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
1984 editor_data->get_undo_redo().add_do_reference(child);
1985 editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL);
1986 }
1987
1988 editor_data->get_undo_redo().commit_action();
1989 editor->push_item(c);
1990 editor_selection->clear();
1991 editor_selection->add_node(child);
1992 if (Object::cast_to<Control>(c)) {
1993 //make editor more comfortable, so some controls don't appear super shrunk
1994 Control *ct = Object::cast_to<Control>(c);
1995
1996 Size2 ms = ct->get_minimum_size();
1997 if (ms.width < 4)
1998 ms.width = 40;
1999 if (ms.height < 4)
2000 ms.height = 40;
2001 ct->set_size(ms);
2002 }
2003 }
2004
_create()2005 void SceneTreeDock::_create() {
2006
2007 if (current_option == TOOL_NEW) {
2008
2009 Node *parent = NULL;
2010
2011 if (edited_scene) {
2012 // If root exists in edited scene
2013 parent = scene_tree->get_selected();
2014 if (!parent)
2015 parent = edited_scene;
2016
2017 } else {
2018 // If no root exist in edited scene
2019 parent = scene_root;
2020 ERR_FAIL_COND(!parent);
2021 }
2022
2023 _do_create(parent);
2024
2025 } else if (current_option == TOOL_REPLACE) {
2026 List<Node *> selection = editor_selection->get_selected_node_list();
2027 ERR_FAIL_COND(selection.size() <= 0);
2028
2029 UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
2030 ur->create_action(TTR("Change type of node(s)"));
2031
2032 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
2033 Node *n = E->get();
2034 ERR_FAIL_COND(!n);
2035
2036 Object *c = create_dialog->instance_selected();
2037
2038 ERR_FAIL_COND(!c);
2039 Node *newnode = Object::cast_to<Node>(c);
2040 ERR_FAIL_COND(!newnode);
2041
2042 ur->add_do_method(this, "replace_node", n, newnode, true, false);
2043 ur->add_do_reference(newnode);
2044 ur->add_undo_method(this, "replace_node", newnode, n, false, false);
2045 ur->add_undo_reference(n);
2046 }
2047
2048 ur->commit_action();
2049 } else if (current_option == TOOL_REPARENT_TO_NEW_NODE) {
2050 List<Node *> selection = editor_selection->get_selected_node_list();
2051 ERR_FAIL_COND(selection.size() <= 0);
2052
2053 // Find top level node in selection
2054 bool only_one_top_node = true;
2055
2056 Node *first = selection.front()->get();
2057 ERR_FAIL_COND(!first);
2058 int smaller_path_to_top = first->get_path_to(scene_root).get_name_count();
2059 Node *top_node = first;
2060
2061 for (List<Node *>::Element *E = selection.front()->next(); E; E = E->next()) {
2062 Node *n = E->get();
2063 ERR_FAIL_COND(!n);
2064
2065 int path_length = n->get_path_to(scene_root).get_name_count();
2066
2067 if (top_node != n) {
2068 if (smaller_path_to_top > path_length) {
2069 top_node = n;
2070 smaller_path_to_top = path_length;
2071 only_one_top_node = true;
2072 } else if (smaller_path_to_top == path_length) {
2073 if (only_one_top_node && top_node->get_parent() != n->get_parent())
2074 only_one_top_node = false;
2075 }
2076 }
2077 }
2078
2079 Node *parent = NULL;
2080 if (only_one_top_node)
2081 parent = top_node->get_parent();
2082 else
2083 parent = top_node->get_parent()->get_parent();
2084
2085 _do_create(parent);
2086
2087 Vector<Node *> nodes;
2088 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
2089 nodes.push_back(E->get());
2090 }
2091
2092 // This works because editor_selection was cleared and populated with last created node in _do_create()
2093 Node *last_created = editor_selection->get_selected_node_list().front()->get();
2094 _do_reparent(last_created, -1, nodes, true);
2095 }
2096
2097 scene_tree->get_scene_tree()->call_deferred("grab_focus");
2098 }
2099
replace_node(Node * p_node,Node * p_by_node,bool p_keep_properties,bool p_remove_old)2100 void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties, bool p_remove_old) {
2101
2102 Node *n = p_node;
2103 Node *newnode = p_by_node;
2104
2105 if (p_keep_properties) {
2106 Node *default_oldnode = Object::cast_to<Node>(ClassDB::instance(n->get_class()));
2107 List<PropertyInfo> pinfo;
2108 n->get_property_list(&pinfo);
2109
2110 for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
2111 if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
2112 continue;
2113
2114 if (E->get().name == "__meta__") {
2115 if (Object::cast_to<CanvasItem>(newnode)) {
2116 Dictionary metadata = n->get(E->get().name);
2117 if (metadata.has("_edit_group_") && metadata["_edit_group_"]) {
2118 newnode->set_meta("_edit_group_", true);
2119 }
2120 if (metadata.has("_edit_lock_") && metadata["_edit_lock_"]) {
2121 newnode->set_meta("_edit_lock_", true);
2122 }
2123 }
2124
2125 continue;
2126 }
2127
2128 if (default_oldnode->get(E->get().name) != n->get(E->get().name)) {
2129 newnode->set(E->get().name, n->get(E->get().name));
2130 }
2131 }
2132
2133 memdelete(default_oldnode);
2134 }
2135
2136 editor->push_item(NULL);
2137
2138 //reconnect signals
2139 List<MethodInfo> sl;
2140
2141 n->get_signal_list(&sl);
2142 for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) {
2143
2144 List<Object::Connection> cl;
2145 n->get_signal_connection_list(E->get().name, &cl);
2146
2147 for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) {
2148
2149 Object::Connection &c = F->get();
2150 if (!(c.flags & Object::CONNECT_PERSIST))
2151 continue;
2152 newnode->connect(c.signal, c.target, c.method, c.binds, Object::CONNECT_PERSIST);
2153 }
2154 }
2155
2156 String newname = n->get_name();
2157
2158 List<Node *> to_erase;
2159 for (int i = 0; i < n->get_child_count(); i++) {
2160 if (n->get_child(i)->get_owner() == NULL && n->is_owned_by_parent()) {
2161 to_erase.push_back(n->get_child(i));
2162 }
2163 }
2164 n->replace_by(newnode, true);
2165
2166 if (n == edited_scene) {
2167 edited_scene = newnode;
2168 editor->set_edited_scene(newnode);
2169 newnode->set_editable_instances(n->get_editable_instances());
2170 }
2171
2172 //small hack to make collisionshapes and other kind of nodes to work
2173 for (int i = 0; i < newnode->get_child_count(); i++) {
2174 Node *c = newnode->get_child(i);
2175 c->call("set_transform", c->call("get_transform"));
2176 }
2177 //p_remove_old was added to support undo
2178 if (p_remove_old)
2179 editor_data->get_undo_redo().clear_history();
2180 newnode->set_name(newname);
2181
2182 editor->push_item(newnode);
2183
2184 if (p_remove_old) {
2185 memdelete(n);
2186
2187 while (to_erase.front()) {
2188 memdelete(to_erase.front()->get());
2189 to_erase.pop_front();
2190 }
2191 }
2192 }
2193
set_edited_scene(Node * p_scene)2194 void SceneTreeDock::set_edited_scene(Node *p_scene) {
2195
2196 edited_scene = p_scene;
2197 }
2198
set_selected(Node * p_node,bool p_emit_selected)2199 void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) {
2200
2201 scene_tree->set_selected(p_node, p_emit_selected);
2202 }
2203
import_subscene()2204 void SceneTreeDock::import_subscene() {
2205
2206 import_subscene_dialog->popup_centered_clamped(Size2(500, 800) * EDSCALE, 0.8);
2207 }
2208
_import_subscene()2209 void SceneTreeDock::_import_subscene() {
2210
2211 Node *parent = scene_tree->get_selected();
2212 if (!parent) {
2213 parent = editor_data->get_edited_scene_root();
2214 ERR_FAIL_COND(!parent);
2215 }
2216
2217 import_subscene_dialog->move(parent, edited_scene);
2218 editor_data->get_undo_redo().clear_history(); //no undo for now..
2219 }
2220
_new_scene_from(String p_file)2221 void SceneTreeDock::_new_scene_from(String p_file) {
2222
2223 List<Node *> selection = editor_selection->get_selected_node_list();
2224
2225 if (selection.size() != 1) {
2226 accept->set_text(TTR("This operation requires a single selected node."));
2227 accept->popup_centered_minsize();
2228 return;
2229 }
2230
2231 if (EditorNode::get_singleton()->is_scene_open(p_file)) {
2232 accept->set_text(TTR("Can't overwrite scene that is still open!"));
2233 accept->popup_centered_minsize();
2234 return;
2235 }
2236
2237 Node *base = selection.front()->get();
2238
2239 Map<Node *, Node *> reown;
2240 reown[editor_data->get_edited_scene_root()] = base;
2241 Node *copy = base->duplicate_and_reown(reown);
2242 if (copy) {
2243
2244 Ref<PackedScene> sdata = memnew(PackedScene);
2245 Error err = sdata->pack(copy);
2246 memdelete(copy);
2247
2248 if (err != OK) {
2249 accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied."));
2250 accept->popup_centered_minsize();
2251 return;
2252 }
2253
2254 int flg = 0;
2255 if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
2256 flg |= ResourceSaver::FLAG_COMPRESS;
2257
2258 err = ResourceSaver::save(p_file, sdata, flg);
2259 if (err != OK) {
2260 accept->set_text(TTR("Error saving scene."));
2261 accept->popup_centered_minsize();
2262 return;
2263 }
2264 _replace_with_branch_scene(p_file, base);
2265 } else {
2266 accept->set_text(TTR("Error duplicating scene to save it."));
2267 accept->popup_centered_minsize();
2268 return;
2269 }
2270 }
2271
_is_node_visible(Node * p_node)2272 static bool _is_node_visible(Node *p_node) {
2273
2274 if (!p_node->get_owner())
2275 return false;
2276 if (p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner()))
2277 return false;
2278
2279 return true;
2280 }
2281
_has_visible_children(Node * p_node)2282 static bool _has_visible_children(Node *p_node) {
2283
2284 bool collapsed = p_node->is_displayed_folded();
2285 if (collapsed)
2286 return false;
2287
2288 for (int i = 0; i < p_node->get_child_count(); i++) {
2289
2290 Node *child = p_node->get_child(i);
2291 if (!_is_node_visible(child))
2292 continue;
2293
2294 return true;
2295 }
2296
2297 return false;
2298 }
2299
_normalize_drop(Node * & to_node,int & to_pos,int p_type)2300 void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
2301
2302 to_pos = -1;
2303
2304 if (p_type == -1) {
2305 //drop at above selected node
2306 if (to_node == EditorNode::get_singleton()->get_edited_scene()) {
2307 to_node = NULL;
2308 ERR_FAIL_MSG("Cannot perform drop above the root node!");
2309 }
2310
2311 to_pos = to_node->get_index();
2312 to_node = to_node->get_parent();
2313
2314 } else if (p_type == 1) {
2315 //drop at below selected node
2316 if (to_node == EditorNode::get_singleton()->get_edited_scene()) {
2317 //if at lower sibling of root node
2318 to_pos = 0; //just insert at beginning of root node
2319 return;
2320 }
2321
2322 Node *lower_sibling = NULL;
2323
2324 if (_has_visible_children(to_node)) {
2325 to_pos = 0;
2326 } else {
2327 for (int i = to_node->get_index() + 1; i < to_node->get_parent()->get_child_count(); i++) {
2328 Node *c = to_node->get_parent()->get_child(i);
2329 if (_is_node_visible(c)) {
2330 lower_sibling = c;
2331 break;
2332 }
2333 }
2334 if (lower_sibling) {
2335 to_pos = lower_sibling->get_index();
2336 }
2337
2338 to_node = to_node->get_parent();
2339 }
2340 }
2341 }
2342
_files_dropped(Vector<String> p_files,NodePath p_to,int p_type)2343 void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_type) {
2344
2345 Node *node = get_node(p_to);
2346 ERR_FAIL_COND(!node);
2347
2348 int to_pos = -1;
2349 _normalize_drop(node, to_pos, p_type);
2350 _perform_instance_scenes(p_files, node, to_pos);
2351 }
2352
_script_dropped(String p_file,NodePath p_to)2353 void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
2354 Ref<Script> scr = ResourceLoader::load(p_file);
2355 ERR_FAIL_COND(!scr.is_valid());
2356 Node *n = get_node(p_to);
2357 if (n) {
2358 editor_data->get_undo_redo().create_action(TTR("Attach Script"));
2359 editor_data->get_undo_redo().add_do_method(n, "set_script", scr);
2360 editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script());
2361 editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
2362 editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
2363 editor_data->get_undo_redo().commit_action();
2364 }
2365 }
2366
_nodes_dragged(Array p_nodes,NodePath p_to,int p_type)2367 void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
2368
2369 List<Node *> selection = editor_selection->get_selected_node_list();
2370
2371 if (selection.empty())
2372 return; //nothing to reparent
2373
2374 Node *to_node = get_node(p_to);
2375 if (!to_node)
2376 return;
2377
2378 Vector<Node *> nodes;
2379 for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
2380 nodes.push_back(E->get());
2381 }
2382
2383 int to_pos = -1;
2384
2385 _normalize_drop(to_node, to_pos, p_type);
2386 _do_reparent(to_node, to_pos, nodes, !Input::get_singleton()->is_key_pressed(KEY_SHIFT));
2387 }
2388
_add_children_to_popup(Object * p_obj,int p_depth)2389 void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
2390
2391 if (p_depth > 8)
2392 return;
2393
2394 List<PropertyInfo> pinfo;
2395 p_obj->get_property_list(&pinfo);
2396 for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
2397
2398 if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
2399 continue;
2400 if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE)
2401 continue;
2402
2403 Variant value = p_obj->get(E->get().name);
2404 if (value.get_type() != Variant::OBJECT)
2405 continue;
2406 Object *obj = value;
2407 if (!obj)
2408 continue;
2409
2410 Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj);
2411
2412 if (menu->get_item_count() == 0) {
2413 menu->add_submenu_item(TTR("Sub-Resources"), "Sub-Resources");
2414 }
2415 int index = menu_subresources->get_item_count();
2416 menu_subresources->add_icon_item(icon, E->get().name.capitalize(), EDIT_SUBRESOURCE_BASE + subresources.size());
2417 menu_subresources->set_item_h_offset(index, p_depth * 10 * EDSCALE);
2418 subresources.push_back(obj->get_instance_id());
2419
2420 _add_children_to_popup(obj, p_depth + 1);
2421 }
2422 }
2423
_tree_rmb(const Vector2 & p_menu_pos)2424 void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
2425
2426 if (!EditorNode::get_singleton()->get_edited_scene()) {
2427
2428 menu->clear();
2429 if (profile_allow_editing) {
2430 menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
2431 menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
2432 }
2433
2434 menu->set_size(Size2(1, 1));
2435 menu->set_position(p_menu_pos);
2436 menu->popup();
2437 return;
2438 }
2439
2440 List<Node *> selection = editor_selection->get_selected_node_list();
2441 List<Node *> full_selection = editor_selection->get_full_selected_node_list(); // Above method only returns nodes with common parent.
2442
2443 if (selection.size() == 0)
2444 return;
2445
2446 menu->clear();
2447
2448 Ref<Script> existing_script;
2449 bool exisiting_script_removable = true;
2450 if (selection.size() == 1) {
2451
2452 Node *selected = selection[0];
2453
2454 if (profile_allow_editing) {
2455 subresources.clear();
2456 menu_subresources->clear();
2457 menu_subresources->set_size(Size2(1, 1));
2458 _add_children_to_popup(selection.front()->get(), 0);
2459 if (menu->get_item_count() > 0)
2460 menu->add_separator();
2461
2462 menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
2463 menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
2464 }
2465 menu->add_icon_shortcut(get_icon("Collapse", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE);
2466 menu->add_separator();
2467
2468 existing_script = selected->get_script();
2469
2470 if (EditorNode::get_singleton()->get_object_custom_type_base(selected) == existing_script) {
2471 exisiting_script_removable = false;
2472 }
2473 }
2474
2475 if (profile_allow_script_editing) {
2476 bool add_separator = false;
2477
2478 if (full_selection.size() == 1) {
2479 add_separator = true;
2480 menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
2481 if (existing_script.is_valid()) {
2482 menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_EXTEND_SCRIPT);
2483 }
2484 }
2485 if (existing_script.is_valid() && exisiting_script_removable) {
2486 add_separator = true;
2487 menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
2488 } else if (full_selection.size() > 1) {
2489 bool script_exists = false;
2490 for (List<Node *>::Element *E = full_selection.front(); E; E = E->next()) {
2491 if (!E->get()->get_script().is_null()) {
2492 script_exists = true;
2493 break;
2494 }
2495 }
2496
2497 if (script_exists) {
2498 add_separator = true;
2499 menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
2500 }
2501 }
2502
2503 if (add_separator) {
2504 menu->add_separator();
2505 }
2506 }
2507
2508 if (profile_allow_editing) {
2509 if (full_selection.size() == 1) {
2510 menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
2511 }
2512 menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
2513
2514 if (scene_tree->get_selected() != edited_scene) {
2515 menu->add_separator();
2516 menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
2517 menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
2518 menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
2519 menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
2520 menu->add_icon_shortcut(get_icon("ReparentToNewNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE);
2521 if (selection.size() == 1) {
2522 menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
2523 }
2524 }
2525 }
2526 if (selection.size() == 1) {
2527
2528 if (profile_allow_editing) {
2529 menu->add_separator();
2530 menu->add_icon_shortcut(get_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE);
2531 menu->add_icon_shortcut(get_icon("CreateNewSceneFrom", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
2532 }
2533 if (full_selection.size() == 1) {
2534 menu->add_separator();
2535 menu->add_icon_shortcut(get_icon("CopyNodePath", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
2536 }
2537
2538 bool is_external = (selection[0]->get_filename() != "");
2539 if (is_external) {
2540 bool is_inherited = selection[0]->get_scene_inherited_state() != NULL;
2541 bool is_top_level = selection[0]->get_owner() == NULL;
2542 if (is_inherited && is_top_level) {
2543 menu->add_separator();
2544 if (profile_allow_editing) {
2545 menu->add_item(TTR("Clear Inheritance"), TOOL_SCENE_CLEAR_INHERITANCE);
2546 }
2547 menu->add_icon_item(get_icon("Load", "EditorIcons"), TTR("Open in Editor"), TOOL_SCENE_OPEN_INHERITED);
2548 } else if (!is_top_level) {
2549 menu->add_separator();
2550 bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(selection[0]);
2551 bool placeholder = selection[0]->get_scene_instance_load_placeholder();
2552 if (profile_allow_editing) {
2553 menu->add_check_item(TTR("Editable Children"), TOOL_SCENE_EDITABLE_CHILDREN);
2554 menu->add_check_item(TTR("Load As Placeholder"), TOOL_SCENE_USE_PLACEHOLDER);
2555 menu->add_item(TTR("Make Local"), TOOL_SCENE_MAKE_LOCAL);
2556 }
2557 menu->add_icon_item(get_icon("Load", "EditorIcons"), TTR("Open in Editor"), TOOL_SCENE_OPEN);
2558 if (profile_allow_editing) {
2559 menu->set_item_checked(menu->get_item_idx_from_text(TTR("Editable Children")), editable);
2560 menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
2561 }
2562 }
2563 }
2564 }
2565
2566 if (profile_allow_editing && selection.size() > 1) {
2567 //this is not a commonly used action, it makes no sense for it to be where it was nor always present.
2568 menu->add_separator();
2569 menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/batch_rename"), TOOL_BATCH_RENAME);
2570 }
2571 menu->add_separator();
2572 menu->add_icon_item(get_icon("Help", "EditorIcons"), TTR("Open Documentation"), TOOL_OPEN_DOCUMENTATION);
2573
2574 if (profile_allow_editing) {
2575 menu->add_separator();
2576 menu->add_icon_shortcut(get_icon("Remove", "EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE);
2577 }
2578 menu->set_size(Size2(1, 1));
2579 menu->set_position(p_menu_pos);
2580 menu->popup();
2581 }
2582
_filter_changed(const String & p_filter)2583 void SceneTreeDock::_filter_changed(const String &p_filter) {
2584
2585 scene_tree->set_filter(p_filter);
2586 }
2587
get_filter()2588 String SceneTreeDock::get_filter() {
2589
2590 return filter->get_text();
2591 }
2592
set_filter(const String & p_filter)2593 void SceneTreeDock::set_filter(const String &p_filter) {
2594
2595 filter->set_text(p_filter);
2596 scene_tree->set_filter(p_filter);
2597 }
2598
_focus_node()2599 void SceneTreeDock::_focus_node() {
2600
2601 Node *node = scene_tree->get_selected();
2602 ERR_FAIL_COND(!node);
2603
2604 if (node->is_class("CanvasItem")) {
2605 CanvasItemEditorPlugin *editor = Object::cast_to<CanvasItemEditorPlugin>(editor_data->get_editor("2D"));
2606 editor->get_canvas_item_editor()->focus_selection();
2607 } else {
2608 SpatialEditorPlugin *editor = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
2609 editor->get_spatial_editor()->get_editor_viewport(0)->focus_selection();
2610 }
2611 }
2612
attach_script_to_selected(bool p_extend)2613 void SceneTreeDock::attach_script_to_selected(bool p_extend) {
2614 if (ScriptServer::get_language_count() == 0) {
2615 EditorNode::get_singleton()->show_warning(TTR("Cannot attach a script: there are no languages registered.\nThis is probably because this editor was built with all language modules disabled."));
2616 return;
2617 }
2618
2619 if (!profile_allow_script_editing) {
2620 return;
2621 }
2622
2623 List<Node *> selection = editor_selection->get_selected_node_list();
2624 if (selection.empty())
2625 return;
2626
2627 Node *selected = scene_tree->get_selected();
2628 if (!selected)
2629 selected = selection.front()->get();
2630
2631 Ref<Script> existing = selected->get_script();
2632
2633 String path = selected->get_filename();
2634 if (path == "") {
2635 String root_path = editor_data->get_edited_scene_root()->get_filename();
2636 if (root_path == "") {
2637 path = String("res://").plus_file(selected->get_name());
2638 } else {
2639 path = root_path.get_base_dir().plus_file(selected->get_name());
2640 }
2641 }
2642
2643 String inherits = selected->get_class();
2644
2645 if (p_extend && existing.is_valid()) {
2646 for (int i = 0; i < ScriptServer::get_language_count(); i++) {
2647 ScriptLanguage *l = ScriptServer::get_language(i);
2648 if (l->get_type() == existing->get_class()) {
2649 String name = l->get_global_class_name(existing->get_path());
2650 if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
2651 inherits = name;
2652 } else if (l->can_inherit_from_file()) {
2653 inherits = "\"" + existing->get_path() + "\"";
2654 }
2655 break;
2656 }
2657 }
2658 }
2659
2660 script_create_dialog->connect("script_created", this, "_script_created");
2661 script_create_dialog->connect("popup_hide", this, "_script_creation_closed", varray(), CONNECT_ONESHOT);
2662 script_create_dialog->set_inheritance_base_type("Node");
2663 script_create_dialog->config(inherits, path);
2664 script_create_dialog->popup_centered();
2665 }
2666
open_script_dialog(Node * p_for_node,bool p_extend)2667 void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) {
2668
2669 scene_tree->set_selected(p_for_node, false);
2670
2671 if (p_extend) {
2672 _tool_selected(TOOL_EXTEND_SCRIPT);
2673 } else {
2674 _tool_selected(TOOL_ATTACH_SCRIPT);
2675 }
2676 }
2677
add_remote_tree_editor(Control * p_remote)2678 void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
2679 ERR_FAIL_COND(remote_tree != NULL);
2680 add_child(p_remote);
2681 remote_tree = p_remote;
2682 remote_tree->hide();
2683 }
2684
show_remote_tree()2685 void SceneTreeDock::show_remote_tree() {
2686
2687 _remote_tree_selected();
2688 }
2689
hide_remote_tree()2690 void SceneTreeDock::hide_remote_tree() {
2691
2692 _local_tree_selected();
2693 }
2694
show_tab_buttons()2695 void SceneTreeDock::show_tab_buttons() {
2696
2697 button_hb->show();
2698 }
2699
hide_tab_buttons()2700 void SceneTreeDock::hide_tab_buttons() {
2701
2702 button_hb->hide();
2703 }
2704
_remote_tree_selected()2705 void SceneTreeDock::_remote_tree_selected() {
2706
2707 scene_tree->hide();
2708 create_root_dialog->hide();
2709 if (remote_tree)
2710 remote_tree->show();
2711 edit_remote->set_pressed(true);
2712 edit_local->set_pressed(false);
2713
2714 emit_signal("remote_tree_selected");
2715 }
2716
_local_tree_selected()2717 void SceneTreeDock::_local_tree_selected() {
2718
2719 if (!bool(EDITOR_GET("interface/editors/show_scene_tree_root_selection")) || get_tree()->get_edited_scene_root() != nullptr) {
2720 scene_tree->show();
2721 }
2722 if (remote_tree)
2723 remote_tree->hide();
2724 edit_remote->set_pressed(false);
2725 edit_local->set_pressed(true);
2726 }
2727
_update_create_root_dialog()2728 void SceneTreeDock::_update_create_root_dialog() {
2729
2730 BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle")));
2731 Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcuts"));
2732
2733 if (!toggle || !node_shortcuts)
2734 return;
2735
2736 Control *beginner_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("BeginnerNodeShortcuts")));
2737 Control *favorite_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("FavoriteNodeShortcuts")));
2738
2739 if (!beginner_nodes || !favorite_nodes)
2740 return;
2741
2742 EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", toggle->is_pressed());
2743 EditorSettings::get_singleton()->save();
2744 if (toggle->is_pressed()) {
2745
2746 for (int i = 0; i < favorite_nodes->get_child_count(); i++) {
2747 favorite_nodes->get_child(i)->queue_delete();
2748 }
2749
2750 FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites.Node"), FileAccess::READ);
2751
2752 if (f) {
2753
2754 while (!f->eof_reached()) {
2755 String l = f->get_line().strip_edges();
2756
2757 if (l != String()) {
2758 Button *button = memnew(Button);
2759 favorite_nodes->add_child(button);
2760 button->set_text(TTR(l));
2761 String name = l.get_slicec(' ', 0);
2762 if (ScriptServer::is_global_class(name))
2763 name = ScriptServer::get_global_class_native_base(name);
2764 button->set_icon(EditorNode::get_singleton()->get_class_icon(name));
2765 button->connect("pressed", this, "_favorite_root_selected", make_binds(l));
2766 }
2767 }
2768
2769 memdelete(f);
2770 }
2771
2772 if (!favorite_nodes->is_visible_in_tree()) {
2773 favorite_nodes->show();
2774 beginner_nodes->hide();
2775 }
2776 } else {
2777 if (!beginner_nodes->is_visible_in_tree()) {
2778 beginner_nodes->show();
2779 favorite_nodes->hide();
2780 }
2781 }
2782 }
2783
_favorite_root_selected(const String & p_class)2784 void SceneTreeDock::_favorite_root_selected(const String &p_class) {
2785 selected_favorite_root = p_class;
2786 _tool_selected(TOOL_CREATE_FAVORITE, false);
2787 }
2788
_feature_profile_changed()2789 void SceneTreeDock::_feature_profile_changed() {
2790
2791 Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
2792
2793 if (profile.is_valid()) {
2794
2795 profile_allow_editing = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCENE_TREE);
2796 profile_allow_script_editing = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT);
2797 bool profile_allow_3d = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D);
2798
2799 button_3d->set_visible(profile_allow_3d);
2800 button_add->set_visible(profile_allow_editing);
2801 button_instance->set_visible(profile_allow_editing);
2802 scene_tree->set_can_rename(profile_allow_editing);
2803
2804 } else {
2805 button_3d->set_visible(true);
2806 button_add->set_visible(true);
2807 button_instance->set_visible(true);
2808 scene_tree->set_can_rename(true);
2809 profile_allow_editing = true;
2810 profile_allow_script_editing = true;
2811 }
2812
2813 _update_script_button();
2814 }
2815
_bind_methods()2816 void SceneTreeDock::_bind_methods() {
2817
2818 ClassDB::bind_method(D_METHOD("_tool_selected"), &SceneTreeDock::_tool_selected, DEFVAL(false));
2819 ClassDB::bind_method(D_METHOD("_create"), &SceneTreeDock::_create);
2820 ClassDB::bind_method(D_METHOD("_node_reparent"), &SceneTreeDock::_node_reparent);
2821 ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners);
2822 ClassDB::bind_method(D_METHOD("_node_selected"), &SceneTreeDock::_node_selected);
2823 ClassDB::bind_method(D_METHOD("_node_renamed"), &SceneTreeDock::_node_renamed);
2824 ClassDB::bind_method(D_METHOD("_script_created"), &SceneTreeDock::_script_created);
2825 ClassDB::bind_method(D_METHOD("_script_creation_closed"), &SceneTreeDock::_script_creation_closed);
2826 ClassDB::bind_method(D_METHOD("_load_request"), &SceneTreeDock::_load_request);
2827 ClassDB::bind_method(D_METHOD("_script_open_request"), &SceneTreeDock::_script_open_request);
2828 ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input);
2829 ClassDB::bind_method(D_METHOD("_input"), &SceneTreeDock::_input);
2830 ClassDB::bind_method(D_METHOD("_nodes_drag_begin"), &SceneTreeDock::_nodes_drag_begin);
2831 ClassDB::bind_method(D_METHOD("_delete_confirm"), &SceneTreeDock::_delete_confirm);
2832 ClassDB::bind_method(D_METHOD("_toggle_editable_children_from_selection"), &SceneTreeDock::_toggle_editable_children_from_selection);
2833 ClassDB::bind_method(D_METHOD("_toggle_placeholder_from_selection"), &SceneTreeDock::_toggle_placeholder_from_selection);
2834 ClassDB::bind_method(D_METHOD("_node_prerenamed"), &SceneTreeDock::_node_prerenamed);
2835 ClassDB::bind_method(D_METHOD("_import_subscene"), &SceneTreeDock::_import_subscene);
2836 ClassDB::bind_method(D_METHOD("_selection_changed"), &SceneTreeDock::_selection_changed);
2837 ClassDB::bind_method(D_METHOD("_node_collapsed"), &SceneTreeDock::_node_collapsed);
2838 ClassDB::bind_method(D_METHOD("_new_scene_from"), &SceneTreeDock::_new_scene_from);
2839 ClassDB::bind_method(D_METHOD("_nodes_dragged"), &SceneTreeDock::_nodes_dragged);
2840 ClassDB::bind_method(D_METHOD("_files_dropped"), &SceneTreeDock::_files_dropped);
2841 ClassDB::bind_method(D_METHOD("_quick_open"), &SceneTreeDock::_quick_open);
2842 ClassDB::bind_method(D_METHOD("_script_dropped"), &SceneTreeDock::_script_dropped);
2843 ClassDB::bind_method(D_METHOD("_tree_rmb"), &SceneTreeDock::_tree_rmb);
2844 ClassDB::bind_method(D_METHOD("_filter_changed"), &SceneTreeDock::_filter_changed);
2845 ClassDB::bind_method(D_METHOD("_focus_node"), &SceneTreeDock::_focus_node);
2846 ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected);
2847 ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
2848 ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
2849 ClassDB::bind_method(D_METHOD("_favorite_root_selected"), &SceneTreeDock::_favorite_root_selected);
2850 ClassDB::bind_method(D_METHOD("_update_create_root_dialog"), &SceneTreeDock::_update_create_root_dialog);
2851 ClassDB::bind_method(D_METHOD("_feature_profile_changed"), &SceneTreeDock::_feature_profile_changed);
2852
2853 ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);
2854 ClassDB::bind_method(D_METHOD("get_tree_editor"), &SceneTreeDock::get_tree_editor);
2855 ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node);
2856
2857 ADD_SIGNAL(MethodInfo("remote_tree_selected"));
2858 }
2859
SceneTreeDock(EditorNode * p_editor,Node * p_scene_root,EditorSelection * p_editor_selection,EditorData & p_editor_data)2860 SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) {
2861
2862 set_name("Scene");
2863 editor = p_editor;
2864 edited_scene = NULL;
2865 editor_data = &p_editor_data;
2866 editor_selection = p_editor_selection;
2867 scene_root = p_scene_root;
2868
2869 VBoxContainer *vbc = this;
2870
2871 HBoxContainer *filter_hbc = memnew(HBoxContainer);
2872 filter_hbc->add_constant_override("separate", 0);
2873
2874 ED_SHORTCUT("scene_tree/rename", TTR("Rename"));
2875 ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KEY_MASK_CMD | KEY_F2);
2876 ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KEY_MASK_CMD | KEY_A);
2877 ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene"));
2878 ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All"));
2879 ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
2880 ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
2881 ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
2882 ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script"));
2883 ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP);
2884 ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN);
2885 ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D);
2886 ED_SHORTCUT("scene_tree/reparent", TTR("Reparent"));
2887 ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node"));
2888 ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root"));
2889 ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene"));
2890 ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
2891 ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_C);
2892 ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT | KEY_DELETE);
2893 ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE);
2894
2895 button_add = memnew(ToolButton);
2896 button_add->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false));
2897 button_add->set_tooltip(TTR("Add/Create a New Node."));
2898 button_add->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node"));
2899 filter_hbc->add_child(button_add);
2900
2901 button_instance = memnew(ToolButton);
2902 button_instance->connect("pressed", this, "_tool_selected", make_binds(TOOL_INSTANCE, false));
2903 button_instance->set_tooltip(TTR("Instance a scene file as a Node. Creates an inherited scene if no root node exists."));
2904 button_instance->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene"));
2905 filter_hbc->add_child(button_instance);
2906
2907 vbc->add_child(filter_hbc);
2908 filter = memnew(LineEdit);
2909 filter->set_h_size_flags(SIZE_EXPAND_FILL);
2910 filter->set_placeholder(TTR("Filter nodes"));
2911 filter_hbc->add_child(filter);
2912 filter->add_constant_override("minimum_spaces", 0);
2913 filter->connect("text_changed", this, "_filter_changed");
2914
2915 button_create_script = memnew(ToolButton);
2916 button_create_script->connect("pressed", this, "_tool_selected", make_binds(TOOL_ATTACH_SCRIPT, false));
2917 button_create_script->set_tooltip(TTR("Attach a new or existing script to the selected node."));
2918 button_create_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script"));
2919 filter_hbc->add_child(button_create_script);
2920 button_create_script->hide();
2921
2922 button_detach_script = memnew(ToolButton);
2923 button_detach_script->connect("pressed", this, "_tool_selected", make_binds(TOOL_DETACH_SCRIPT, false));
2924 button_detach_script->set_tooltip(TTR("Detach the script from the selected node."));
2925 button_detach_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/detach_script"));
2926 filter_hbc->add_child(button_detach_script);
2927 button_detach_script->hide();
2928
2929 button_hb = memnew(HBoxContainer);
2930 vbc->add_child(button_hb);
2931
2932 edit_remote = memnew(ToolButton);
2933 button_hb->add_child(edit_remote);
2934 edit_remote->set_h_size_flags(SIZE_EXPAND_FILL);
2935 edit_remote->set_text(TTR("Remote"));
2936 edit_remote->set_toggle_mode(true);
2937 edit_remote->connect("pressed", this, "_remote_tree_selected");
2938
2939 edit_local = memnew(ToolButton);
2940 button_hb->add_child(edit_local);
2941 edit_local->set_h_size_flags(SIZE_EXPAND_FILL);
2942 edit_local->set_text(TTR("Local"));
2943 edit_local->set_toggle_mode(true);
2944 edit_local->connect("pressed", this, "_local_tree_selected");
2945
2946 remote_tree = NULL;
2947 button_hb->hide();
2948
2949 create_root_dialog = memnew(VBoxContainer);
2950 vbc->add_child(create_root_dialog);
2951 create_root_dialog->hide();
2952
2953 scene_tree = memnew(SceneTreeEditor(false, true, true));
2954
2955 vbc->add_child(scene_tree);
2956 scene_tree->set_v_size_flags(SIZE_EXPAND | SIZE_FILL);
2957 scene_tree->connect("rmb_pressed", this, "_tree_rmb");
2958
2959 scene_tree->connect("node_selected", this, "_node_selected", varray(), CONNECT_DEFERRED);
2960 scene_tree->connect("node_renamed", this, "_node_renamed", varray(), CONNECT_DEFERRED);
2961 scene_tree->connect("node_prerename", this, "_node_prerenamed");
2962 scene_tree->connect("open", this, "_load_request");
2963 scene_tree->connect("open_script", this, "_script_open_request");
2964 scene_tree->connect("nodes_rearranged", this, "_nodes_dragged");
2965 scene_tree->connect("files_dropped", this, "_files_dropped");
2966 scene_tree->connect("script_dropped", this, "_script_dropped");
2967 scene_tree->connect("nodes_dragged", this, "_nodes_drag_begin");
2968
2969 scene_tree->get_scene_tree()->connect("item_double_clicked", this, "_focus_node");
2970
2971 scene_tree->set_undo_redo(&editor_data->get_undo_redo());
2972 scene_tree->set_editor_selection(editor_selection);
2973
2974 create_dialog = memnew(CreateDialog);
2975 create_dialog->set_base_type("Node");
2976 add_child(create_dialog);
2977 create_dialog->connect("create", this, "_create");
2978 create_dialog->connect("favorites_updated", this, "_update_create_root_dialog");
2979
2980 rename_dialog = memnew(RenameDialog(scene_tree, &editor_data->get_undo_redo()));
2981 add_child(rename_dialog);
2982
2983 script_create_dialog = memnew(ScriptCreateDialog);
2984 script_create_dialog->set_inheritance_base_type("Node");
2985 add_child(script_create_dialog);
2986
2987 reparent_dialog = memnew(ReparentDialog);
2988 add_child(reparent_dialog);
2989 reparent_dialog->connect("reparent", this, "_node_reparent");
2990
2991 accept = memnew(AcceptDialog);
2992 add_child(accept);
2993
2994 quick_open = memnew(EditorQuickOpen);
2995 add_child(quick_open);
2996 quick_open->connect("quick_open", this, "_quick_open");
2997 set_process_unhandled_key_input(true);
2998
2999 delete_dialog = memnew(ConfirmationDialog);
3000 add_child(delete_dialog);
3001 delete_dialog->connect("confirmed", this, "_delete_confirm");
3002
3003 editable_instance_remove_dialog = memnew(ConfirmationDialog);
3004 add_child(editable_instance_remove_dialog);
3005 editable_instance_remove_dialog->connect("confirmed", this, "_toggle_editable_children_from_selection");
3006
3007 placeholder_editable_instance_remove_dialog = memnew(ConfirmationDialog);
3008 add_child(placeholder_editable_instance_remove_dialog);
3009 placeholder_editable_instance_remove_dialog->connect("confirmed", this, "_toggle_placeholder_from_selection");
3010
3011 import_subscene_dialog = memnew(EditorSubScene);
3012 add_child(import_subscene_dialog);
3013 import_subscene_dialog->connect("subscene_selected", this, "_import_subscene");
3014
3015 new_scene_from_dialog = memnew(EditorFileDialog);
3016 new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
3017 add_child(new_scene_from_dialog);
3018 new_scene_from_dialog->connect("file_selected", this, "_new_scene_from");
3019
3020 menu = memnew(PopupMenu);
3021 add_child(menu);
3022 menu->connect("id_pressed", this, "_tool_selected");
3023 menu->set_hide_on_window_lose_focus(true);
3024 menu_subresources = memnew(PopupMenu);
3025 menu_subresources->set_name("Sub-Resources");
3026 menu_subresources->connect("id_pressed", this, "_tool_selected");
3027 menu->add_child(menu_subresources);
3028 first_enter = true;
3029 restore_script_editor_on_drag = false;
3030
3031 clear_inherit_confirm = memnew(ConfirmationDialog);
3032 clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)"));
3033 clear_inherit_confirm->get_ok()->set_text(TTR("Clear"));
3034 add_child(clear_inherit_confirm);
3035
3036 set_process_input(true);
3037 set_process(true);
3038
3039 profile_allow_editing = true;
3040 profile_allow_script_editing = true;
3041
3042 EDITOR_DEF("interface/editors/show_scene_tree_root_selection", true);
3043 EDITOR_DEF("interface/editors/derive_script_globals_by_name", true);
3044 EDITOR_DEF("_use_favorites_root_selection", false);
3045 }
3046