scene_tree_editor.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. /*************************************************************************/
  2. /* scene_tree_editor.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 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. #include "scene_tree_editor.h"
  31. #include "editor/plugins/canvas_item_editor_plugin.h"
  32. #include "editor_node.h"
  33. #include "message_queue.h"
  34. #include "print_string.h"
  35. #include "scene/gui/label.h"
  36. #include "scene/main/viewport.h"
  37. #include "scene/resources/packed_scene.h"
  38. Node *SceneTreeEditor::get_scene_node() {
  39. ERR_FAIL_COND_V(!is_inside_tree(), NULL);
  40. return get_tree()->get_edited_scene_root();
  41. }
  42. void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
  43. TreeItem *item = Object::cast_to<TreeItem>(p_item);
  44. ERR_FAIL_COND(!item);
  45. NodePath np = item->get_metadata(0);
  46. Node *n = get_node(np);
  47. ERR_FAIL_COND(!n);
  48. if (p_id == BUTTON_SUBSCENE) {
  49. if (n == get_scene_node()) {
  50. if (n && n->get_scene_inherited_state().is_valid()) {
  51. emit_signal("open", n->get_scene_inherited_state()->get_path());
  52. }
  53. } else {
  54. emit_signal("open", n->get_filename());
  55. }
  56. } else if (p_id == BUTTON_SCRIPT) {
  57. RefPtr script = n->get_script();
  58. if (!script.is_null())
  59. emit_signal("open_script", script);
  60. } else if (p_id == BUTTON_VISIBILITY) {
  61. if (n->is_class("Spatial")) {
  62. bool v = bool(n->call("is_visible"));
  63. undo_redo->create_action(TTR("Toggle Spatial Visible"));
  64. undo_redo->add_do_method(n, "set_visible", !v);
  65. undo_redo->add_undo_method(n, "set_visible", v);
  66. undo_redo->commit_action();
  67. } else if (n->is_class("CanvasItem")) {
  68. bool v = bool(n->call("is_visible"));
  69. undo_redo->create_action(TTR("Toggle CanvasItem Visible"));
  70. undo_redo->add_do_method(n, v ? "hide" : "show");
  71. undo_redo->add_undo_method(n, v ? "show" : "hide");
  72. undo_redo->commit_action();
  73. }
  74. } else if (p_id == BUTTON_LOCK) {
  75. if (n->is_class("CanvasItem")) {
  76. n->set_meta("_edit_lock_", Variant());
  77. _update_tree();
  78. emit_signal("node_changed");
  79. }
  80. } else if (p_id == BUTTON_GROUP) {
  81. if (n->is_class("CanvasItem")) {
  82. n->set_meta("_edit_group_", Variant());
  83. _update_tree();
  84. emit_signal("node_changed");
  85. }
  86. } else if (p_id == BUTTON_WARNING) {
  87. String config_err = n->get_configuration_warning();
  88. if (config_err == String())
  89. return;
  90. config_err = config_err.word_wrap(80);
  91. warning->set_text(config_err);
  92. warning->popup_centered_minsize();
  93. } else if (p_id == BUTTON_SIGNALS) {
  94. editor_selection->clear();
  95. editor_selection->add_node(n);
  96. set_selected(n);
  97. NodeDock::singleton->get_parent()->call("set_current_tab", NodeDock::singleton->get_index());
  98. NodeDock::singleton->show_connections();
  99. } else if (p_id == BUTTON_GROUPS) {
  100. editor_selection->clear();
  101. editor_selection->add_node(n);
  102. set_selected(n);
  103. NodeDock::singleton->get_parent()->call("set_current_tab", NodeDock::singleton->get_index());
  104. NodeDock::singleton->show_groups();
  105. }
  106. }
  107. bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
  108. if (!p_node)
  109. return false;
  110. // only owned nodes are editable, since nodes can create their own (manually owned) child nodes,
  111. // which the editor needs not to know about.
  112. bool part_of_subscene = false;
  113. if (!display_foreign && p_node->get_owner() != get_scene_node() && p_node != get_scene_node()) {
  114. if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
  115. part_of_subscene = true;
  116. //allow
  117. } else {
  118. return false;
  119. }
  120. } else {
  121. part_of_subscene = p_node != get_scene_node() && get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node)) >= 0;
  122. }
  123. TreeItem *item = tree->create_item(p_parent);
  124. item->set_text(0, p_node->get_name());
  125. if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/)
  126. item->set_editable(0, true);
  127. item->set_selectable(0, true);
  128. if (can_rename) {
  129. #ifndef DISABLE_DEPRECATED
  130. if (p_node->has_meta("_editor_collapsed")) {
  131. //remove previous way of storing folding, which did not get along with scene inheritance and instancing
  132. if ((bool)p_node->get_meta("_editor_collapsed"))
  133. p_node->set_display_folded(true);
  134. p_node->set_meta("_editor_collapsed", Variant());
  135. }
  136. #endif
  137. bool collapsed = p_node->is_displayed_folded();
  138. if (collapsed)
  139. item->set_collapsed(true);
  140. }
  141. Ref<Texture> icon;
  142. if (p_node->has_meta("_editor_icon"))
  143. icon = p_node->get_meta("_editor_icon");
  144. else
  145. icon = get_icon((has_icon(p_node->get_class(), "EditorIcons") ? p_node->get_class() : String("Object")), "EditorIcons");
  146. item->set_icon(0, icon);
  147. item->set_metadata(0, p_node->get_path());
  148. if (part_of_subscene) {
  149. //item->set_selectable(0,marked_selectable);
  150. item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
  151. } else if (marked.has(p_node)) {
  152. item->set_selectable(0, marked_selectable);
  153. item->set_custom_color(0, get_color("error_color", "Editor"));
  154. } else if (!marked_selectable && !marked_children_selectable) {
  155. Node *node = p_node;
  156. while (node) {
  157. if (marked.has(node)) {
  158. item->set_selectable(0, false);
  159. item->set_custom_color(0, get_color("error_color", "Editor"));
  160. break;
  161. }
  162. node = node->get_parent();
  163. }
  164. }
  165. if (can_rename) { //should be can edit..
  166. String warning = p_node->get_configuration_warning();
  167. if (warning != String()) {
  168. item->add_button(0, get_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning());
  169. }
  170. bool has_connections = p_node->has_persistent_signal_connections();
  171. bool has_groups = p_node->has_persistent_groups();
  172. if (has_connections && has_groups) {
  173. item->add_button(0, get_icon("SignalsAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s)\nClick to show signals dock."));
  174. } else if (has_connections) {
  175. item->add_button(0, get_icon("Signals", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock."));
  176. } else if (has_groups) {
  177. item->add_button(0, get_icon("Groups", "EditorIcons"), BUTTON_GROUPS, false, TTR("Node is in group(s).\nClick to show groups dock."));
  178. }
  179. }
  180. if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
  181. item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
  182. item->set_tooltip(0, TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class());
  183. } else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) {
  184. item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
  185. item->set_tooltip(0, TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class());
  186. } else {
  187. item->set_tooltip(0, String(p_node->get_name()) + "\n" + TTR("Type:") + " " + p_node->get_class());
  188. }
  189. if (can_open_instance) {
  190. if (!p_node->is_connected("script_changed", this, "_node_script_changed"))
  191. p_node->connect("script_changed", this, "_node_script_changed", varray(p_node));
  192. if (!p_node->get_script().is_null()) {
  193. item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT, false, TTR("Open script"));
  194. }
  195. if (p_node->is_class("CanvasItem")) {
  196. bool is_locked = p_node->has_meta("_edit_lock_"); //_edit_group_
  197. if (is_locked)
  198. item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock"));
  199. bool is_grouped = p_node->has_meta("_edit_group_");
  200. if (is_grouped)
  201. item->add_button(0, get_icon("Group", "EditorIcons"), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable"));
  202. bool v = p_node->call("is_visible");
  203. if (v)
  204. item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
  205. else
  206. item->add_button(0, get_icon("Hidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
  207. if (!p_node->is_connected("visibility_changed", this, "_node_visibility_changed"))
  208. p_node->connect("visibility_changed", this, "_node_visibility_changed", varray(p_node));
  209. _update_visibility_color(p_node, item);
  210. } else if (p_node->is_class("Spatial")) {
  211. bool v = p_node->call("is_visible");
  212. if (v)
  213. item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
  214. else
  215. item->add_button(0, get_icon("Hidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
  216. if (!p_node->is_connected("visibility_changed", this, "_node_visibility_changed"))
  217. p_node->connect("visibility_changed", this, "_node_visibility_changed", varray(p_node));
  218. _update_visibility_color(p_node, item);
  219. }
  220. }
  221. if (editor_selection) {
  222. if (editor_selection->is_selected(p_node)) {
  223. item->select(0);
  224. }
  225. }
  226. if (selected == p_node) {
  227. if (!editor_selection)
  228. item->select(0);
  229. item->set_as_cursor(0);
  230. }
  231. bool keep = (filter.is_subsequence_ofi(String(p_node->get_name())));
  232. for (int i = 0; i < p_node->get_child_count(); i++) {
  233. bool child_keep = _add_nodes(p_node->get_child(i), item);
  234. keep = keep || child_keep;
  235. }
  236. if (!keep) {
  237. memdelete(item);
  238. return false;
  239. } else {
  240. return true;
  241. }
  242. }
  243. void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
  244. if (p_node != get_scene_node() && !p_node->get_owner()) {
  245. return;
  246. }
  247. TreeItem *item = p_node ? _find(tree->get_root(), p_node->get_path()) : NULL;
  248. if (!item) {
  249. return;
  250. }
  251. int idx = item->get_button_by_id(0, BUTTON_VISIBILITY);
  252. ERR_FAIL_COND(idx == -1);
  253. bool visible = false;
  254. if (p_node->is_class("CanvasItem")) {
  255. visible = p_node->call("is_visible");
  256. CanvasItemEditor::get_singleton()->get_viewport_control()->update();
  257. } else if (p_node->is_class("Spatial")) {
  258. visible = p_node->call("is_visible");
  259. }
  260. if (visible)
  261. item->set_button(0, idx, get_icon("Visible", "EditorIcons"));
  262. else
  263. item->set_button(0, idx, get_icon("Hidden", "EditorIcons"));
  264. _update_visibility_color(p_node, item);
  265. }
  266. void SceneTreeEditor::_update_visibility_color(Node *p_node, TreeItem *p_item) {
  267. if (p_node->is_class("CanvasItem") || p_node->is_class("Spatial")) {
  268. Color color(1, 1, 1, 1);
  269. bool visible_on_screen = p_node->call("is_visible_in_tree");
  270. if (!visible_on_screen) {
  271. color.a = 0.6;
  272. }
  273. int idx = p_item->get_button_by_id(0, BUTTON_VISIBILITY);
  274. p_item->set_button_color(0, idx, color);
  275. }
  276. }
  277. void SceneTreeEditor::_node_script_changed(Node *p_node) {
  278. _update_tree();
  279. /*
  280. changes the order :|
  281. TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL;
  282. if (p_node->get_script().is_null()) {
  283. int idx=item->get_button_by_id(0,2);
  284. if (idx>=0)
  285. item->erase_button(0,idx);
  286. } else {
  287. int idx=item->get_button_by_id(0,2);
  288. if (idx<0)
  289. item->add_button(0,get_icon("Script","EditorIcons"),2);
  290. }*/
  291. }
  292. void SceneTreeEditor::_node_removed(Node *p_node) {
  293. if (EditorNode::get_singleton()->is_exiting())
  294. return; //speed up exit
  295. if (p_node->is_connected("script_changed", this, "_node_script_changed"))
  296. p_node->disconnect("script_changed", this, "_node_script_changed");
  297. if (p_node->is_class("Spatial") || p_node->is_class("CanvasItem")) {
  298. if (p_node->is_connected("visibility_changed", this, "_node_visibility_changed"))
  299. p_node->disconnect("visibility_changed", this, "_node_visibility_changed");
  300. }
  301. if (p_node == selected) {
  302. selected = NULL;
  303. emit_signal("node_selected");
  304. }
  305. }
  306. void SceneTreeEditor::_update_tree() {
  307. if (!is_inside_tree()) {
  308. tree_dirty = false;
  309. return;
  310. }
  311. updating_tree = true;
  312. tree->clear();
  313. if (get_scene_node()) {
  314. _add_nodes(get_scene_node(), NULL);
  315. last_hash = hash_djb2_one_64(0);
  316. _compute_hash(get_scene_node(), last_hash);
  317. }
  318. updating_tree = false;
  319. tree_dirty = false;
  320. }
  321. void SceneTreeEditor::_compute_hash(Node *p_node, uint64_t &hash) {
  322. hash = hash_djb2_one_64(p_node->get_instance_id(), hash);
  323. if (p_node->get_parent())
  324. hash = hash_djb2_one_64(p_node->get_parent()->get_instance_id(), hash); //so a reparent still produces a different hash
  325. for (int i = 0; i < p_node->get_child_count(); i++) {
  326. _compute_hash(p_node->get_child(i), hash);
  327. }
  328. }
  329. void SceneTreeEditor::_test_update_tree() {
  330. pending_test_update = false;
  331. if (!is_inside_tree())
  332. return;
  333. if (tree_dirty)
  334. return; // don't even bother
  335. uint64_t hash = hash_djb2_one_64(0);
  336. if (get_scene_node())
  337. _compute_hash(get_scene_node(), hash);
  338. //test hash
  339. if (hash == last_hash)
  340. return; // did not change
  341. MessageQueue::get_singleton()->push_call(this, "_update_tree");
  342. tree_dirty = true;
  343. }
  344. void SceneTreeEditor::_tree_changed() {
  345. if (EditorNode::get_singleton()->is_exiting())
  346. return; //speed up exit
  347. if (pending_test_update)
  348. return;
  349. if (tree_dirty)
  350. return;
  351. MessageQueue::get_singleton()->push_call(this, "_test_update_tree");
  352. pending_test_update = true;
  353. }
  354. void SceneTreeEditor::_selected_changed() {
  355. TreeItem *s = tree->get_selected();
  356. ERR_FAIL_COND(!s);
  357. NodePath np = s->get_metadata(0);
  358. Node *n = get_node(np);
  359. if (n == selected)
  360. return;
  361. selected = get_node(np);
  362. blocked++;
  363. emit_signal("node_selected");
  364. blocked--;
  365. }
  366. void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_selected) {
  367. TreeItem *item = Object::cast_to<TreeItem>(p_object);
  368. ERR_FAIL_COND(!item);
  369. NodePath np = item->get_metadata(0);
  370. Node *n = get_node(np);
  371. if (!n)
  372. return;
  373. if (!editor_selection)
  374. return;
  375. if (p_selected) {
  376. editor_selection->add_node(n);
  377. } else {
  378. editor_selection->remove_node(n);
  379. }
  380. }
  381. void SceneTreeEditor::_notification(int p_what) {
  382. if (p_what == NOTIFICATION_ENTER_TREE) {
  383. get_tree()->connect("tree_changed", this, "_tree_changed");
  384. get_tree()->connect("node_removed", this, "_node_removed");
  385. get_tree()->connect("node_configuration_warning_changed", this, "_warning_changed");
  386. tree->connect("item_collapsed", this, "_cell_collapsed");
  387. EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed");
  388. //get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED);
  389. //get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED);
  390. _update_tree();
  391. }
  392. if (p_what == NOTIFICATION_EXIT_TREE) {
  393. get_tree()->disconnect("tree_changed", this, "_tree_changed");
  394. get_tree()->disconnect("node_removed", this, "_node_removed");
  395. tree->disconnect("item_collapsed", this, "_cell_collapsed");
  396. get_tree()->disconnect("node_configuration_warning_changed", this, "_warning_changed");
  397. EditorSettings::get_singleton()->disconnect("settings_changed", this, "_editor_settings_changed");
  398. }
  399. }
  400. TreeItem *SceneTreeEditor::_find(TreeItem *p_node, const NodePath &p_path) {
  401. if (!p_node)
  402. return NULL;
  403. NodePath np = p_node->get_metadata(0);
  404. if (np == p_path)
  405. return p_node;
  406. TreeItem *children = p_node->get_children();
  407. while (children) {
  408. TreeItem *n = _find(children, p_path);
  409. if (n)
  410. return n;
  411. children = children->get_next();
  412. }
  413. return NULL;
  414. }
  415. void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
  416. ERR_FAIL_COND(blocked > 0);
  417. if (pending_test_update)
  418. _test_update_tree();
  419. if (tree_dirty)
  420. _update_tree();
  421. if (selected == p_node)
  422. return;
  423. TreeItem *item = p_node ? _find(tree->get_root(), p_node->get_path()) : NULL;
  424. if (item) {
  425. // make visible when it's collapsed
  426. TreeItem *node = item->get_parent();
  427. while (node && node != tree->get_root()) {
  428. node->set_collapsed(false);
  429. node = node->get_parent();
  430. }
  431. item->select(0);
  432. item->set_as_cursor(0);
  433. selected = p_node;
  434. tree->ensure_cursor_is_visible();
  435. } else {
  436. if (!p_node)
  437. selected = NULL;
  438. _update_tree();
  439. selected = p_node;
  440. }
  441. if (p_emit_selected) {
  442. emit_signal("node_selected");
  443. }
  444. }
  445. void SceneTreeEditor::_rename_node(ObjectID p_node, const String &p_name) {
  446. Object *o = ObjectDB::get_instance(p_node);
  447. ERR_FAIL_COND(!o);
  448. Node *n = Object::cast_to<Node>(o);
  449. ERR_FAIL_COND(!n);
  450. TreeItem *item = _find(tree->get_root(), n->get_path());
  451. ERR_FAIL_COND(!item);
  452. n->set_name(p_name);
  453. item->set_metadata(0, n->get_path());
  454. item->set_text(0, p_name);
  455. emit_signal("node_renamed");
  456. if (!tree_dirty) {
  457. MessageQueue::get_singleton()->push_call(this, "_update_tree");
  458. tree_dirty = true;
  459. }
  460. }
  461. void SceneTreeEditor::_renamed() {
  462. TreeItem *which = tree->get_edited();
  463. ERR_FAIL_COND(!which);
  464. NodePath np = which->get_metadata(0);
  465. Node *n = get_node(np);
  466. ERR_FAIL_COND(!n);
  467. String new_name = which->get_text(0);
  468. if (new_name.find(".") != -1 || new_name.find("/") != -1) {
  469. error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n \".\", \"/\"");
  470. error->popup_centered_minsize();
  471. new_name = n->get_name();
  472. }
  473. if (new_name == n->get_name())
  474. return;
  475. if (!undo_redo) {
  476. n->set_name(new_name);
  477. which->set_metadata(0, n->get_path());
  478. emit_signal("node_renamed");
  479. } else {
  480. undo_redo->create_action(TTR("Rename Node"));
  481. emit_signal("node_prerename", n, new_name);
  482. undo_redo->add_do_method(this, "_rename_node", n->get_instance_id(), new_name);
  483. undo_redo->add_undo_method(this, "_rename_node", n->get_instance_id(), n->get_name());
  484. undo_redo->commit_action();
  485. }
  486. }
  487. Node *SceneTreeEditor::get_selected() {
  488. return selected;
  489. }
  490. void SceneTreeEditor::set_marked(const Set<Node *> &p_marked, bool p_selectable, bool p_children_selectable) {
  491. if (tree_dirty)
  492. _update_tree();
  493. marked = p_marked;
  494. marked_selectable = p_selectable;
  495. marked_children_selectable = p_children_selectable;
  496. _update_tree();
  497. }
  498. void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_children_selectable) {
  499. Set<Node *> s;
  500. if (p_marked)
  501. s.insert(p_marked);
  502. set_marked(s, p_selectable, p_children_selectable);
  503. }
  504. void SceneTreeEditor::set_filter(const String &p_filter) {
  505. filter = p_filter;
  506. _update_tree();
  507. }
  508. String SceneTreeEditor::get_filter() const {
  509. return filter;
  510. }
  511. void SceneTreeEditor::set_display_foreign_nodes(bool p_display) {
  512. display_foreign = p_display;
  513. _update_tree();
  514. }
  515. bool SceneTreeEditor::get_display_foreign_nodes() const {
  516. return display_foreign;
  517. }
  518. void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) {
  519. editor_selection = p_selection;
  520. tree->set_select_mode(Tree::SELECT_MULTI);
  521. tree->set_cursor_can_exit_tree(false);
  522. editor_selection->connect("selection_changed", this, "_selection_changed");
  523. }
  524. void SceneTreeEditor::_update_selection(TreeItem *item) {
  525. ERR_FAIL_COND(!item);
  526. NodePath np = item->get_metadata(0);
  527. if (!has_node(np))
  528. return;
  529. Node *n = get_node(np);
  530. if (!n)
  531. return;
  532. if (editor_selection->is_selected(n))
  533. item->select(0);
  534. else
  535. item->deselect(0);
  536. TreeItem *c = item->get_children();
  537. while (c) {
  538. _update_selection(c);
  539. c = c->get_next();
  540. }
  541. }
  542. void SceneTreeEditor::_selection_changed() {
  543. if (!editor_selection)
  544. return;
  545. TreeItem *root = tree->get_root();
  546. if (!root)
  547. return;
  548. _update_selection(root);
  549. }
  550. void SceneTreeEditor::_cell_collapsed(Object *p_obj) {
  551. if (updating_tree)
  552. return;
  553. if (!can_rename)
  554. return;
  555. TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
  556. if (!ti)
  557. return;
  558. bool collapsed = ti->is_collapsed();
  559. NodePath np = ti->get_metadata(0);
  560. Node *n = get_node(np);
  561. ERR_FAIL_COND(!n);
  562. n->set_display_folded(collapsed);
  563. }
  564. Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
  565. if (!can_rename)
  566. return Variant(); //not editable tree
  567. Vector<Node *> selected;
  568. Vector<Ref<Texture> > icons;
  569. TreeItem *next = tree->get_next_selected(NULL);
  570. while (next) {
  571. NodePath np = next->get_metadata(0);
  572. Node *n = get_node(np);
  573. if (n) {
  574. selected.push_back(n);
  575. icons.push_back(next->get_icon(0));
  576. }
  577. next = tree->get_next_selected(next);
  578. }
  579. if (selected.empty())
  580. return Variant();
  581. VBoxContainer *vb = memnew(VBoxContainer);
  582. Array objs;
  583. int list_max = 10;
  584. float opacity_step = 1.0f / list_max;
  585. float opacity_item = 1.0f;
  586. for (int i = 0; i < selected.size(); i++) {
  587. if (i < list_max) {
  588. HBoxContainer *hb = memnew(HBoxContainer);
  589. TextureRect *tf = memnew(TextureRect);
  590. tf->set_texture(icons[i]);
  591. hb->add_child(tf);
  592. Label *label = memnew(Label(selected[i]->get_name()));
  593. hb->add_child(label);
  594. vb->add_child(hb);
  595. hb->set_modulate(Color(1, 1, 1, opacity_item));
  596. opacity_item -= opacity_step;
  597. }
  598. NodePath p = selected[i]->get_path();
  599. objs.push_back(p);
  600. }
  601. set_drag_preview(vb);
  602. Dictionary drag_data;
  603. drag_data["type"] = "nodes";
  604. drag_data["nodes"] = objs;
  605. tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM);
  606. emit_signal("nodes_dragged");
  607. return drag_data;
  608. }
  609. bool SceneTreeEditor::_is_script_type(const StringName &p_type) const {
  610. return (script_types->find(p_type));
  611. }
  612. bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
  613. if (!can_rename)
  614. return false; //not editable tree
  615. if (filter != String())
  616. return false; //can't rearrange tree with filter turned on
  617. Dictionary d = p_data;
  618. if (!d.has("type"))
  619. return false;
  620. TreeItem *item = tree->get_item_at_position(p_point);
  621. if (!item)
  622. return false;
  623. int section = tree->get_drop_section_at_position(p_point);
  624. if (section < -1 || (section == -1 && !item->get_parent()))
  625. return false;
  626. if (String(d["type"]) == "files") {
  627. Vector<String> files = d["files"];
  628. if (files.size() == 0)
  629. return false; //weird
  630. if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(files[0]))) {
  631. tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
  632. return true;
  633. }
  634. for (int i = 0; i < files.size(); i++) {
  635. String file = files[i];
  636. String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
  637. if (ftype != "PackedScene")
  638. return false;
  639. }
  640. tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM); //so it works..
  641. return true;
  642. }
  643. if (String(d["type"]) == "nodes") {
  644. return true;
  645. }
  646. return false;
  647. }
  648. void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
  649. if (!can_drop_data_fw(p_point, p_data, p_from))
  650. return;
  651. TreeItem *item = tree->get_item_at_position(p_point);
  652. if (!item)
  653. return;
  654. int section = tree->get_drop_section_at_position(p_point);
  655. if (section < -1)
  656. return;
  657. NodePath np = item->get_metadata(0);
  658. Node *n = get_node(np);
  659. if (!n)
  660. return;
  661. Dictionary d = p_data;
  662. if (String(d["type"]) == "nodes") {
  663. Array nodes = d["nodes"];
  664. emit_signal("nodes_rearranged", nodes, np, section);
  665. }
  666. if (String(d["type"]) == "files") {
  667. Vector<String> files = d["files"];
  668. String ftype = EditorFileSystem::get_singleton()->get_file_type(files[0]);
  669. if (_is_script_type(ftype)) {
  670. emit_signal("script_dropped", files[0], np);
  671. } else {
  672. emit_signal("files_dropped", files, np, section);
  673. }
  674. }
  675. }
  676. void SceneTreeEditor::_rmb_select(const Vector2 &p_pos) {
  677. emit_signal("rmb_pressed", tree->get_global_transform().xform(p_pos));
  678. }
  679. void SceneTreeEditor::_warning_changed(Node *p_for_node) {
  680. //should use a timer
  681. update_timer->start();
  682. //print_line("WARNING CHANGED "+String(p_for_node->get_name()));
  683. }
  684. void SceneTreeEditor::_editor_settings_changed() {
  685. bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines");
  686. Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color");
  687. if (enable_rl) {
  688. tree->add_constant_override("draw_relationship_lines", 1);
  689. tree->add_color_override("relationship_line_color", rl_color);
  690. } else
  691. tree->add_constant_override("draw_relationship_lines", 0);
  692. }
  693. void SceneTreeEditor::_bind_methods() {
  694. ClassDB::bind_method("_tree_changed", &SceneTreeEditor::_tree_changed);
  695. ClassDB::bind_method("_update_tree", &SceneTreeEditor::_update_tree);
  696. ClassDB::bind_method("_node_removed", &SceneTreeEditor::_node_removed);
  697. ClassDB::bind_method("_selected_changed", &SceneTreeEditor::_selected_changed);
  698. ClassDB::bind_method("_renamed", &SceneTreeEditor::_renamed);
  699. ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node);
  700. ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree);
  701. ClassDB::bind_method("_cell_multi_selected", &SceneTreeEditor::_cell_multi_selected);
  702. ClassDB::bind_method("_selection_changed", &SceneTreeEditor::_selection_changed);
  703. ClassDB::bind_method("_cell_button_pressed", &SceneTreeEditor::_cell_button_pressed);
  704. ClassDB::bind_method("_cell_collapsed", &SceneTreeEditor::_cell_collapsed);
  705. ClassDB::bind_method("_rmb_select", &SceneTreeEditor::_rmb_select);
  706. ClassDB::bind_method("_warning_changed", &SceneTreeEditor::_warning_changed);
  707. ClassDB::bind_method("_node_script_changed", &SceneTreeEditor::_node_script_changed);
  708. ClassDB::bind_method("_node_visibility_changed", &SceneTreeEditor::_node_visibility_changed);
  709. ClassDB::bind_method("_editor_settings_changed", &SceneTreeEditor::_editor_settings_changed);
  710. ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SceneTreeEditor::get_drag_data_fw);
  711. ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SceneTreeEditor::can_drop_data_fw);
  712. ClassDB::bind_method(D_METHOD("drop_data_fw"), &SceneTreeEditor::drop_data_fw);
  713. ClassDB::bind_method(D_METHOD("update_tree"), &SceneTreeEditor::update_tree);
  714. ADD_SIGNAL(MethodInfo("node_selected"));
  715. ADD_SIGNAL(MethodInfo("node_renamed"));
  716. ADD_SIGNAL(MethodInfo("node_prerename"));
  717. ADD_SIGNAL(MethodInfo("node_changed"));
  718. ADD_SIGNAL(MethodInfo("nodes_dragged"));
  719. ADD_SIGNAL(MethodInfo("nodes_rearranged", PropertyInfo(Variant::ARRAY, "paths"), PropertyInfo(Variant::NODE_PATH, "to_path"), PropertyInfo(Variant::INT, "type")));
  720. ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::NODE_PATH, "to_path"), PropertyInfo(Variant::INT, "type")));
  721. ADD_SIGNAL(MethodInfo("script_dropped", PropertyInfo(Variant::STRING, "file"), PropertyInfo(Variant::NODE_PATH, "to_path")));
  722. ADD_SIGNAL(MethodInfo("rmb_pressed", PropertyInfo(Variant::VECTOR2, "position")));
  723. ADD_SIGNAL(MethodInfo("open"));
  724. ADD_SIGNAL(MethodInfo("open_script"));
  725. }
  726. SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_open_instance) {
  727. undo_redo = NULL;
  728. tree_dirty = true;
  729. selected = NULL;
  730. marked_selectable = false;
  731. marked_children_selectable = false;
  732. can_rename = p_can_rename;
  733. can_open_instance = p_can_open_instance;
  734. display_foreign = false;
  735. editor_selection = NULL;
  736. if (p_label) {
  737. Label *label = memnew(Label);
  738. label->set_position(Point2(10, 0));
  739. label->set_text(TTR("Scene Tree (Nodes):"));
  740. add_child(label);
  741. }
  742. tree = memnew(Tree);
  743. tree->set_anchor(MARGIN_RIGHT, ANCHOR_END);
  744. tree->set_anchor(MARGIN_BOTTOM, ANCHOR_END);
  745. tree->set_begin(Point2(0, p_label ? 18 : 0));
  746. tree->set_end(Point2(0, 0));
  747. tree->add_constant_override("button_margin", 0);
  748. add_child(tree);
  749. tree->set_drag_forwarding(this);
  750. if (p_can_rename) {
  751. tree->set_allow_rmb_select(true);
  752. tree->connect("item_rmb_selected", this, "_rmb_select");
  753. tree->connect("empty_tree_rmb_selected", this, "_rmb_select");
  754. }
  755. tree->connect("cell_selected", this, "_selected_changed");
  756. tree->connect("item_edited", this, "_renamed", varray(), CONNECT_DEFERRED);
  757. tree->connect("multi_selected", this, "_cell_multi_selected");
  758. tree->connect("button_pressed", this, "_cell_button_pressed");
  759. //tree->connect("item_edited", this,"_renamed",Vector<Variant>(),true);
  760. error = memnew(AcceptDialog);
  761. add_child(error);
  762. warning = memnew(AcceptDialog);
  763. add_child(warning);
  764. warning->set_title(TTR("Node Configuration Warning!"));
  765. show_enabled_subscene = false;
  766. last_hash = 0;
  767. pending_test_update = false;
  768. updating_tree = false;
  769. blocked = 0;
  770. update_timer = memnew(Timer);
  771. update_timer->connect("timeout", this, "_update_tree");
  772. update_timer->set_one_shot(true);
  773. update_timer->set_wait_time(0.5);
  774. add_child(update_timer);
  775. script_types = memnew(List<StringName>);
  776. ClassDB::get_inheriters_from_class("Script", script_types);
  777. }
  778. SceneTreeEditor::~SceneTreeEditor() {
  779. memdelete(script_types);
  780. }
  781. /******** DIALOG *********/
  782. void SceneTreeDialog::_notification(int p_what) {
  783. if (p_what == NOTIFICATION_ENTER_TREE) {
  784. connect("confirmed", this, "_select");
  785. }
  786. if (p_what == NOTIFICATION_EXIT_TREE) {
  787. disconnect("confirmed", this, "_select");
  788. }
  789. if (p_what == NOTIFICATION_DRAW) {
  790. RID ci = get_canvas_item();
  791. get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size()));
  792. }
  793. if (p_what == NOTIFICATION_VISIBILITY_CHANGED && is_visible_in_tree()) {
  794. tree->update_tree();
  795. }
  796. }
  797. void SceneTreeDialog::_cancel() {
  798. hide();
  799. }
  800. void SceneTreeDialog::_select() {
  801. if (tree->get_selected()) {
  802. emit_signal("selected", tree->get_selected()->get_path());
  803. hide();
  804. }
  805. }
  806. void SceneTreeDialog::_bind_methods() {
  807. ClassDB::bind_method("_select", &SceneTreeDialog::_select);
  808. ClassDB::bind_method("_cancel", &SceneTreeDialog::_cancel);
  809. ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::NODE_PATH, "path")));
  810. }
  811. SceneTreeDialog::SceneTreeDialog() {
  812. set_title(TTR("Select a Node"));
  813. tree = memnew(SceneTreeEditor(false, false));
  814. add_child(tree);
  815. //set_child_rect(tree);
  816. tree->get_scene_tree()->connect("item_activated", this, "_select");
  817. }
  818. SceneTreeDialog::~SceneTreeDialog() {
  819. }