editor_data.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172
  1. /*************************************************************************/
  2. /* editor_data.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 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 "editor_data.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/io/file_access.h"
  33. #include "core/io/resource_loader.h"
  34. #include "editor/editor_node.h"
  35. #include "editor/editor_plugin.h"
  36. #include "editor/plugins/script_editor_plugin.h"
  37. #include "scene/resources/packed_scene.h"
  38. void EditorSelectionHistory::cleanup_history() {
  39. for (int i = 0; i < history.size(); i++) {
  40. bool fail = false;
  41. for (int j = 0; j < history[i].path.size(); j++) {
  42. if (!history[i].path[j].ref.is_null()) {
  43. // Reference is not null - object still alive.
  44. continue;
  45. }
  46. Object *obj = ObjectDB::get_instance(history[i].path[j].object);
  47. if (obj) {
  48. Node *n = Object::cast_to<Node>(obj);
  49. if (n && n->is_inside_tree()) {
  50. // Node valid and inside tree - object still alive.
  51. continue;
  52. }
  53. if (!n) {
  54. // Node possibly still alive.
  55. continue;
  56. }
  57. } // Else: object not valid - not alive.
  58. fail = true;
  59. break;
  60. }
  61. if (fail) {
  62. history.remove_at(i);
  63. i--;
  64. }
  65. }
  66. if (current_elem_idx >= history.size()) {
  67. current_elem_idx = history.size() - 1;
  68. }
  69. }
  70. void EditorSelectionHistory::add_object(ObjectID p_object, const String &p_property, bool p_inspector_only) {
  71. Object *obj = ObjectDB::get_instance(p_object);
  72. ERR_FAIL_COND(!obj);
  73. RefCounted *r = Object::cast_to<RefCounted>(obj);
  74. _Object o;
  75. if (r) {
  76. o.ref = Ref<RefCounted>(r);
  77. }
  78. o.object = p_object;
  79. o.property = p_property;
  80. o.inspector_only = p_inspector_only;
  81. bool has_prev = current_elem_idx >= 0 && current_elem_idx < history.size();
  82. if (has_prev) {
  83. history.resize(current_elem_idx + 1); // Clip history to next.
  84. }
  85. HistoryElement h;
  86. if (!p_property.is_empty() && has_prev) {
  87. // Add a sub property.
  88. HistoryElement &prev_element = history.write[current_elem_idx];
  89. h = prev_element;
  90. h.path.resize(h.level + 1);
  91. h.path.push_back(o);
  92. h.level++;
  93. } else {
  94. // Create a new history item.
  95. h.path.push_back(o);
  96. h.level = 0;
  97. }
  98. history.push_back(h);
  99. current_elem_idx++;
  100. }
  101. int EditorSelectionHistory::get_history_len() {
  102. return history.size();
  103. }
  104. int EditorSelectionHistory::get_history_pos() {
  105. return current_elem_idx;
  106. }
  107. bool EditorSelectionHistory::is_history_obj_inspector_only(int p_obj) const {
  108. ERR_FAIL_INDEX_V(p_obj, history.size(), false);
  109. ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), false);
  110. return history[p_obj].path[history[p_obj].level].inspector_only;
  111. }
  112. ObjectID EditorSelectionHistory::get_history_obj(int p_obj) const {
  113. ERR_FAIL_INDEX_V(p_obj, history.size(), ObjectID());
  114. ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), ObjectID());
  115. return history[p_obj].path[history[p_obj].level].object;
  116. }
  117. bool EditorSelectionHistory::is_at_beginning() const {
  118. return current_elem_idx <= 0;
  119. }
  120. bool EditorSelectionHistory::is_at_end() const {
  121. return ((current_elem_idx + 1) >= history.size());
  122. }
  123. bool EditorSelectionHistory::next() {
  124. cleanup_history();
  125. if ((current_elem_idx + 1) < history.size()) {
  126. current_elem_idx++;
  127. } else {
  128. return false;
  129. }
  130. return true;
  131. }
  132. bool EditorSelectionHistory::previous() {
  133. cleanup_history();
  134. if (current_elem_idx > 0) {
  135. current_elem_idx--;
  136. } else {
  137. return false;
  138. }
  139. return true;
  140. }
  141. bool EditorSelectionHistory::is_current_inspector_only() const {
  142. if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
  143. return false;
  144. }
  145. const HistoryElement &h = history[current_elem_idx];
  146. return h.path[h.level].inspector_only;
  147. }
  148. ObjectID EditorSelectionHistory::get_current() {
  149. if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
  150. return ObjectID();
  151. }
  152. Object *obj = ObjectDB::get_instance(get_history_obj(current_elem_idx));
  153. return obj ? obj->get_instance_id() : ObjectID();
  154. }
  155. int EditorSelectionHistory::get_path_size() const {
  156. if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
  157. return 0;
  158. }
  159. return history[current_elem_idx].path.size();
  160. }
  161. ObjectID EditorSelectionHistory::get_path_object(int p_index) const {
  162. if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
  163. return ObjectID();
  164. }
  165. ERR_FAIL_INDEX_V(p_index, history[current_elem_idx].path.size(), ObjectID());
  166. Object *obj = ObjectDB::get_instance(history[current_elem_idx].path[p_index].object);
  167. return obj ? obj->get_instance_id() : ObjectID();
  168. }
  169. String EditorSelectionHistory::get_path_property(int p_index) const {
  170. if (current_elem_idx < 0 || current_elem_idx >= history.size()) {
  171. return "";
  172. }
  173. ERR_FAIL_INDEX_V(p_index, history[current_elem_idx].path.size(), "");
  174. return history[current_elem_idx].path[p_index].property;
  175. }
  176. void EditorSelectionHistory::clear() {
  177. history.clear();
  178. current_elem_idx = -1;
  179. }
  180. EditorSelectionHistory::EditorSelectionHistory() {
  181. current_elem_idx = -1;
  182. }
  183. ////////////////////////////////////////////////////////////
  184. EditorPlugin *EditorData::get_editor(Object *p_object) {
  185. // We need to iterate backwards so that we can check user-created plugins first.
  186. // Otherwise, it would not be possible for plugins to handle CanvasItem and Spatial nodes.
  187. for (int i = editor_plugins.size() - 1; i > -1; i--) {
  188. if (editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
  189. return editor_plugins[i];
  190. }
  191. }
  192. return nullptr;
  193. }
  194. Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) {
  195. Vector<EditorPlugin *> sub_plugins;
  196. for (int i = editor_plugins.size() - 1; i > -1; i--) {
  197. if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
  198. sub_plugins.push_back(editor_plugins[i]);
  199. }
  200. }
  201. return sub_plugins;
  202. }
  203. EditorPlugin *EditorData::get_editor(String p_name) {
  204. for (int i = editor_plugins.size() - 1; i > -1; i--) {
  205. if (editor_plugins[i]->get_name() == p_name) {
  206. return editor_plugins[i];
  207. }
  208. }
  209. return nullptr;
  210. }
  211. void EditorData::copy_object_params(Object *p_object) {
  212. clipboard.clear();
  213. List<PropertyInfo> pinfo;
  214. p_object->get_property_list(&pinfo);
  215. for (const PropertyInfo &E : pinfo) {
  216. if (!(E.usage & PROPERTY_USAGE_EDITOR) || E.name == "script" || E.name == "scripts") {
  217. continue;
  218. }
  219. PropertyData pd;
  220. pd.name = E.name;
  221. pd.value = p_object->get(pd.name);
  222. clipboard.push_back(pd);
  223. }
  224. }
  225. void EditorData::get_editor_breakpoints(List<String> *p_breakpoints) {
  226. for (int i = 0; i < editor_plugins.size(); i++) {
  227. editor_plugins[i]->get_breakpoints(p_breakpoints);
  228. }
  229. }
  230. Dictionary EditorData::get_editor_states() const {
  231. Dictionary metadata;
  232. for (int i = 0; i < editor_plugins.size(); i++) {
  233. Dictionary state = editor_plugins[i]->get_state();
  234. if (state.is_empty()) {
  235. continue;
  236. }
  237. metadata[editor_plugins[i]->get_name()] = state;
  238. }
  239. return metadata;
  240. }
  241. Dictionary EditorData::get_scene_editor_states(int p_idx) const {
  242. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), Dictionary());
  243. EditedScene es = edited_scene[p_idx];
  244. return es.editor_states;
  245. }
  246. void EditorData::set_editor_states(const Dictionary &p_states) {
  247. List<Variant> keys;
  248. p_states.get_key_list(&keys);
  249. List<Variant>::Element *E = keys.front();
  250. for (; E; E = E->next()) {
  251. String name = E->get();
  252. int idx = -1;
  253. for (int i = 0; i < editor_plugins.size(); i++) {
  254. if (editor_plugins[i]->get_name() == name) {
  255. idx = i;
  256. break;
  257. }
  258. }
  259. if (idx == -1) {
  260. continue;
  261. }
  262. editor_plugins[idx]->set_state(p_states[name]);
  263. }
  264. }
  265. void EditorData::notify_edited_scene_changed() {
  266. for (int i = 0; i < editor_plugins.size(); i++) {
  267. editor_plugins[i]->edited_scene_changed();
  268. editor_plugins[i]->notify_scene_changed(get_edited_scene_root());
  269. }
  270. }
  271. void EditorData::notify_resource_saved(const Ref<Resource> &p_resource) {
  272. for (int i = 0; i < editor_plugins.size(); i++) {
  273. editor_plugins[i]->notify_resource_saved(p_resource);
  274. }
  275. }
  276. void EditorData::clear_editor_states() {
  277. for (int i = 0; i < editor_plugins.size(); i++) {
  278. editor_plugins[i]->clear();
  279. }
  280. }
  281. void EditorData::save_editor_external_data() {
  282. for (int i = 0; i < editor_plugins.size(); i++) {
  283. editor_plugins[i]->save_external_data();
  284. }
  285. }
  286. void EditorData::apply_changes_in_editors() {
  287. for (int i = 0; i < editor_plugins.size(); i++) {
  288. editor_plugins[i]->apply_changes();
  289. }
  290. }
  291. void EditorData::save_editor_global_states() {
  292. for (int i = 0; i < editor_plugins.size(); i++) {
  293. editor_plugins[i]->save_global_state();
  294. }
  295. }
  296. void EditorData::restore_editor_global_states() {
  297. for (int i = 0; i < editor_plugins.size(); i++) {
  298. editor_plugins[i]->restore_global_state();
  299. }
  300. }
  301. void EditorData::paste_object_params(Object *p_object) {
  302. ERR_FAIL_NULL(p_object);
  303. undo_redo.create_action(TTR("Paste Params"));
  304. for (const PropertyData &E : clipboard) {
  305. String name = E.name;
  306. undo_redo.add_do_property(p_object, name, E.value);
  307. undo_redo.add_undo_property(p_object, name, p_object->get(name));
  308. }
  309. undo_redo.commit_action();
  310. }
  311. bool EditorData::call_build() {
  312. bool result = true;
  313. for (int i = 0; i < editor_plugins.size() && result; i++) {
  314. result &= editor_plugins[i]->build();
  315. }
  316. return result;
  317. }
  318. UndoRedo &EditorData::get_undo_redo() {
  319. return undo_redo;
  320. }
  321. void EditorData::add_undo_redo_inspector_hook_callback(Callable p_callable) {
  322. undo_redo_callbacks.push_back(p_callable);
  323. }
  324. void EditorData::remove_undo_redo_inspector_hook_callback(Callable p_callable) {
  325. undo_redo_callbacks.erase(p_callable);
  326. }
  327. const Vector<Callable> EditorData::get_undo_redo_inspector_hook_callback() {
  328. return undo_redo_callbacks;
  329. }
  330. void EditorData::add_move_array_element_function(const StringName &p_class, Callable p_callable) {
  331. move_element_functions.insert(p_class, p_callable);
  332. }
  333. void EditorData::remove_move_array_element_function(const StringName &p_class) {
  334. move_element_functions.erase(p_class);
  335. }
  336. Callable EditorData::get_move_array_element_function(const StringName &p_class) const {
  337. if (move_element_functions.has(p_class)) {
  338. return move_element_functions[p_class];
  339. }
  340. return Callable();
  341. }
  342. void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
  343. p_plugin->undo_redo = nullptr;
  344. editor_plugins.erase(p_plugin);
  345. }
  346. void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
  347. p_plugin->undo_redo = &undo_redo;
  348. editor_plugins.push_back(p_plugin);
  349. }
  350. int EditorData::get_editor_plugin_count() const {
  351. return editor_plugins.size();
  352. }
  353. EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
  354. ERR_FAIL_INDEX_V(p_idx, editor_plugins.size(), nullptr);
  355. return editor_plugins[p_idx];
  356. }
  357. void EditorData::add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon) {
  358. ERR_FAIL_COND_MSG(p_script.is_null(), "It's not a reference to a valid Script object.");
  359. CustomType ct;
  360. ct.name = p_type;
  361. ct.icon = p_icon;
  362. ct.script = p_script;
  363. if (!custom_types.has(p_inherits)) {
  364. custom_types[p_inherits] = Vector<CustomType>();
  365. }
  366. custom_types[p_inherits].push_back(ct);
  367. }
  368. Variant EditorData::instance_custom_type(const String &p_type, const String &p_inherits) {
  369. if (get_custom_types().has(p_inherits)) {
  370. for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) {
  371. if (get_custom_types()[p_inherits][i].name == p_type) {
  372. Ref<Script> script = get_custom_types()[p_inherits][i].script;
  373. Variant ob = ClassDB::instantiate(p_inherits);
  374. ERR_FAIL_COND_V(!ob, Variant());
  375. Node *n = Object::cast_to<Node>(ob);
  376. if (n) {
  377. n->set_name(p_type);
  378. }
  379. ((Object *)ob)->set_script(script);
  380. return ob;
  381. }
  382. }
  383. }
  384. return Variant();
  385. }
  386. void EditorData::remove_custom_type(const String &p_type) {
  387. for (Map<String, Vector<CustomType>>::Element *E = custom_types.front(); E; E = E->next()) {
  388. for (int i = 0; i < E->get().size(); i++) {
  389. if (E->get()[i].name == p_type) {
  390. E->get().remove_at(i);
  391. if (E->get().is_empty()) {
  392. custom_types.erase(E->key());
  393. }
  394. return;
  395. }
  396. }
  397. }
  398. }
  399. void EditorData::instantiate_object_properties(Object *p_object) {
  400. ERR_FAIL_NULL(p_object);
  401. // Check if any Object-type property should be instantiated.
  402. List<PropertyInfo> pinfo;
  403. p_object->get_property_list(&pinfo);
  404. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  405. PropertyInfo pi = E->get();
  406. if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) {
  407. Object *prop = ClassDB::instantiate(pi.class_name);
  408. p_object->set(pi.name, prop);
  409. }
  410. }
  411. }
  412. int EditorData::add_edited_scene(int p_at_pos) {
  413. if (p_at_pos < 0) {
  414. p_at_pos = edited_scene.size();
  415. }
  416. EditedScene es;
  417. es.root = nullptr;
  418. es.path = String();
  419. es.file_modified_time = 0;
  420. es.history_current = -1;
  421. es.version = 0;
  422. es.live_edit_root = NodePath(String("/root"));
  423. if (p_at_pos == edited_scene.size()) {
  424. edited_scene.push_back(es);
  425. } else {
  426. edited_scene.insert(p_at_pos, es);
  427. }
  428. if (current_edited_scene < 0) {
  429. current_edited_scene = 0;
  430. }
  431. return p_at_pos;
  432. }
  433. void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
  434. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  435. ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
  436. SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
  437. }
  438. void EditorData::remove_scene(int p_idx) {
  439. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  440. if (edited_scene[p_idx].root) {
  441. for (int i = 0; i < editor_plugins.size(); i++) {
  442. editor_plugins[i]->notify_scene_closed(edited_scene[p_idx].root->get_scene_file_path());
  443. }
  444. memdelete(edited_scene[p_idx].root);
  445. }
  446. if (current_edited_scene > p_idx) {
  447. current_edited_scene--;
  448. } else if (current_edited_scene == p_idx && current_edited_scene > 0) {
  449. current_edited_scene--;
  450. }
  451. if (!edited_scene[p_idx].path.is_empty()) {
  452. ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(edited_scene[p_idx].path);
  453. }
  454. edited_scene.remove_at(p_idx);
  455. }
  456. bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String> &checked_paths) {
  457. Ref<SceneState> ss;
  458. if (p_node == p_root) {
  459. ss = p_node->get_scene_inherited_state();
  460. } else if (!p_node->get_scene_file_path().is_empty()) {
  461. ss = p_node->get_scene_instance_state();
  462. }
  463. if (ss.is_valid()) {
  464. String path = ss->get_path();
  465. if (!checked_paths.has(path)) {
  466. uint64_t modified_time = FileAccess::get_modified_time(path);
  467. if (modified_time != ss->get_last_modified_time()) {
  468. return true; //external scene changed
  469. }
  470. checked_paths.insert(path);
  471. }
  472. }
  473. for (int i = 0; i < p_node->get_child_count(); i++) {
  474. bool found = _find_updated_instances(p_root, p_node->get_child(i), checked_paths);
  475. if (found) {
  476. return true;
  477. }
  478. }
  479. return false;
  480. }
  481. bool EditorData::check_and_update_scene(int p_idx) {
  482. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), false);
  483. if (!edited_scene[p_idx].root) {
  484. return false;
  485. }
  486. Set<String> checked_scenes;
  487. bool must_reload = _find_updated_instances(edited_scene[p_idx].root, edited_scene[p_idx].root, checked_scenes);
  488. if (must_reload) {
  489. Ref<PackedScene> pscene;
  490. pscene.instantiate();
  491. EditorProgress ep("update_scene", TTR("Updating Scene"), 2);
  492. ep.step(TTR("Storing local changes..."), 0);
  493. // Pack first, so it stores diffs to previous version of saved scene.
  494. Error err = pscene->pack(edited_scene[p_idx].root);
  495. ERR_FAIL_COND_V(err != OK, false);
  496. ep.step(TTR("Updating scene..."), 1);
  497. Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
  498. ERR_FAIL_COND_V(!new_scene, false);
  499. // Transfer selection.
  500. List<Node *> new_selection;
  501. for (const Node *E : edited_scene.write[p_idx].selection) {
  502. NodePath p = edited_scene[p_idx].root->get_path_to(E);
  503. Node *new_node = new_scene->get_node(p);
  504. if (new_node) {
  505. new_selection.push_back(new_node);
  506. }
  507. }
  508. new_scene->set_scene_file_path(edited_scene[p_idx].root->get_scene_file_path());
  509. memdelete(edited_scene[p_idx].root);
  510. edited_scene.write[p_idx].root = new_scene;
  511. if (!new_scene->get_scene_file_path().is_empty()) {
  512. edited_scene.write[p_idx].path = new_scene->get_scene_file_path();
  513. }
  514. edited_scene.write[p_idx].selection = new_selection;
  515. return true;
  516. }
  517. return false;
  518. }
  519. int EditorData::get_edited_scene() const {
  520. return current_edited_scene;
  521. }
  522. void EditorData::set_edited_scene(int p_idx) {
  523. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  524. current_edited_scene = p_idx;
  525. }
  526. Node *EditorData::get_edited_scene_root(int p_idx) {
  527. if (p_idx < 0) {
  528. ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), nullptr);
  529. return edited_scene[current_edited_scene].root;
  530. } else {
  531. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), nullptr);
  532. return edited_scene[p_idx].root;
  533. }
  534. }
  535. void EditorData::set_edited_scene_root(Node *p_root) {
  536. ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
  537. edited_scene.write[current_edited_scene].root = p_root;
  538. if (p_root) {
  539. if (!p_root->get_scene_file_path().is_empty()) {
  540. edited_scene.write[current_edited_scene].path = p_root->get_scene_file_path();
  541. } else {
  542. p_root->set_scene_file_path(edited_scene[current_edited_scene].path);
  543. }
  544. }
  545. if (!edited_scene[current_edited_scene].path.is_empty()) {
  546. edited_scene.write[current_edited_scene].file_modified_time = FileAccess::get_modified_time(edited_scene[current_edited_scene].path);
  547. }
  548. }
  549. int EditorData::get_edited_scene_count() const {
  550. return edited_scene.size();
  551. }
  552. Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
  553. Vector<EditedScene> out_edited_scenes_list = Vector<EditedScene>();
  554. for (int i = 0; i < edited_scene.size(); i++) {
  555. out_edited_scenes_list.push_back(edited_scene[i]);
  556. }
  557. return out_edited_scenes_list;
  558. }
  559. void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
  560. ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
  561. if (p_scene_idx < 0) {
  562. edited_scene.write[current_edited_scene].version = version;
  563. } else {
  564. ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
  565. edited_scene.write[p_scene_idx].version = version;
  566. }
  567. }
  568. uint64_t EditorData::get_scene_version(int p_idx) const {
  569. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0);
  570. return edited_scene[p_idx].version;
  571. }
  572. void EditorData::set_scene_modified_time(int p_idx, uint64_t p_time) {
  573. if (p_idx == -1) {
  574. p_idx = current_edited_scene;
  575. }
  576. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  577. edited_scene.write[p_idx].file_modified_time = p_time;
  578. }
  579. uint64_t EditorData::get_scene_modified_time(int p_idx) const {
  580. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0);
  581. return edited_scene[p_idx].file_modified_time;
  582. }
  583. String EditorData::get_scene_type(int p_idx) const {
  584. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
  585. if (!edited_scene[p_idx].root) {
  586. return "";
  587. }
  588. return edited_scene[p_idx].root->get_class();
  589. }
  590. void EditorData::move_edited_scene_to_index(int p_idx) {
  591. ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
  592. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  593. EditedScene es = edited_scene[current_edited_scene];
  594. edited_scene.remove_at(current_edited_scene);
  595. edited_scene.insert(p_idx, es);
  596. current_edited_scene = p_idx;
  597. }
  598. Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
  599. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), Ref<Script>());
  600. if (!edited_scene[p_idx].root) {
  601. return Ref<Script>();
  602. }
  603. Ref<Script> s = edited_scene[p_idx].root->get_script();
  604. if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) {
  605. Node *n = edited_scene[p_idx].root->get_child(0);
  606. while (!s.is_valid() && n && n->get_scene_file_path().is_empty()) {
  607. s = n->get_script();
  608. n = n->get_parent();
  609. }
  610. }
  611. return s;
  612. }
  613. String EditorData::get_scene_title(int p_idx, bool p_always_strip_extension) const {
  614. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
  615. if (!edited_scene[p_idx].root) {
  616. return TTR("[empty]");
  617. }
  618. if (edited_scene[p_idx].root->get_scene_file_path().is_empty()) {
  619. return TTR("[unsaved]");
  620. }
  621. const String filename = edited_scene[p_idx].root->get_scene_file_path().get_file();
  622. const String basename = filename.get_basename();
  623. if (p_always_strip_extension) {
  624. return basename;
  625. }
  626. // Return the filename including the extension if there's ambiguity (e.g. both `foo.tscn` and `foo.scn` are being edited).
  627. for (int i = 0; i < edited_scene.size(); i++) {
  628. if (i == p_idx) {
  629. // Don't compare the edited scene against itself.
  630. continue;
  631. }
  632. if (edited_scene[i].root && basename == edited_scene[i].root->get_scene_file_path().get_file().get_basename()) {
  633. return filename;
  634. }
  635. }
  636. // Else, return just the basename as there's no ambiguity.
  637. return basename;
  638. }
  639. void EditorData::set_scene_path(int p_idx, const String &p_path) {
  640. ERR_FAIL_INDEX(p_idx, edited_scene.size());
  641. edited_scene.write[p_idx].path = p_path;
  642. if (!edited_scene[p_idx].root) {
  643. return;
  644. }
  645. edited_scene[p_idx].root->set_scene_file_path(p_path);
  646. }
  647. String EditorData::get_scene_path(int p_idx) const {
  648. ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
  649. if (edited_scene[p_idx].root) {
  650. if (edited_scene[p_idx].root->get_scene_file_path().is_empty()) {
  651. edited_scene[p_idx].root->set_scene_file_path(edited_scene[p_idx].path);
  652. } else {
  653. return edited_scene[p_idx].root->get_scene_file_path();
  654. }
  655. }
  656. return edited_scene[p_idx].path;
  657. }
  658. void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
  659. ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
  660. edited_scene.write[current_edited_scene].live_edit_root = p_root;
  661. }
  662. NodePath EditorData::get_edited_scene_live_edit_root() {
  663. ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), String());
  664. return edited_scene[current_edited_scene].live_edit_root;
  665. }
  666. void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history, const Dictionary &p_custom) {
  667. ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
  668. EditedScene &es = edited_scene.write[current_edited_scene];
  669. es.selection = p_selection->get_full_selected_node_list();
  670. es.history_current = p_history->current_elem_idx;
  671. es.history_stored = p_history->history;
  672. es.editor_states = get_editor_states();
  673. es.custom_state = p_custom;
  674. }
  675. Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorSelectionHistory *p_history) {
  676. ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
  677. const EditedScene &es = edited_scene.write[current_edited_scene];
  678. p_history->current_elem_idx = es.history_current;
  679. p_history->history = es.history_stored;
  680. p_selection->clear();
  681. for (Node *E : es.selection) {
  682. p_selection->add_node(E);
  683. }
  684. set_editor_states(es.editor_states);
  685. return es.custom_state;
  686. }
  687. void EditorData::clear_edited_scenes() {
  688. for (int i = 0; i < edited_scene.size(); i++) {
  689. if (edited_scene[i].root) {
  690. memdelete(edited_scene[i].root);
  691. }
  692. }
  693. edited_scene.clear();
  694. }
  695. void EditorData::set_plugin_window_layout(Ref<ConfigFile> p_layout) {
  696. for (int i = 0; i < editor_plugins.size(); i++) {
  697. editor_plugins[i]->set_window_layout(p_layout);
  698. }
  699. }
  700. void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) {
  701. for (int i = 0; i < editor_plugins.size(); i++) {
  702. editor_plugins[i]->get_window_layout(p_layout);
  703. }
  704. }
  705. bool EditorData::script_class_is_parent(const String &p_class, const String &p_inherits) {
  706. if (!ScriptServer::is_global_class(p_class)) {
  707. return false;
  708. }
  709. String base = p_class;
  710. while (base != p_inherits) {
  711. if (ClassDB::class_exists(base)) {
  712. return ClassDB::is_parent_class(base, p_inherits);
  713. } else if (ScriptServer::is_global_class(base)) {
  714. base = ScriptServer::get_global_class_base(base);
  715. } else {
  716. return false;
  717. }
  718. }
  719. return true;
  720. }
  721. StringName EditorData::script_class_get_base(const String &p_class) const {
  722. Ref<Script> script = script_class_load_script(p_class);
  723. if (script.is_null()) {
  724. return StringName();
  725. }
  726. Ref<Script> base_script = script->get_base_script();
  727. if (base_script.is_null()) {
  728. return ScriptServer::get_global_class_base(p_class);
  729. }
  730. return script->get_language()->get_global_class_name(base_script->get_path());
  731. }
  732. Variant EditorData::script_class_instance(const String &p_class) {
  733. if (ScriptServer::is_global_class(p_class)) {
  734. Variant obj = ClassDB::instantiate(ScriptServer::get_global_class_native_base(p_class));
  735. if (obj) {
  736. Ref<Script> script = script_class_load_script(p_class);
  737. if (script.is_valid()) {
  738. ((Object *)obj)->set_script(script);
  739. }
  740. return obj;
  741. }
  742. }
  743. return Variant();
  744. }
  745. Ref<Script> EditorData::script_class_load_script(const String &p_class) const {
  746. if (!ScriptServer::is_global_class(p_class)) {
  747. return Ref<Script>();
  748. }
  749. String path = ScriptServer::get_global_class_path(p_class);
  750. return ResourceLoader::load(path, "Script");
  751. }
  752. void EditorData::script_class_set_icon_path(const String &p_class, const String &p_icon_path) {
  753. _script_class_icon_paths[p_class] = p_icon_path;
  754. }
  755. String EditorData::script_class_get_icon_path(const String &p_class) const {
  756. if (!ScriptServer::is_global_class(p_class)) {
  757. return String();
  758. }
  759. String current = p_class;
  760. String ret = _script_class_icon_paths[current];
  761. while (ret.is_empty()) {
  762. current = script_class_get_base(current);
  763. if (!ScriptServer::is_global_class(current)) {
  764. return String();
  765. }
  766. ret = _script_class_icon_paths.has(current) ? _script_class_icon_paths[current] : String();
  767. }
  768. return ret;
  769. }
  770. StringName EditorData::script_class_get_name(const String &p_path) const {
  771. return _script_class_file_to_path.has(p_path) ? _script_class_file_to_path[p_path] : StringName();
  772. }
  773. void EditorData::script_class_set_name(const String &p_path, const StringName &p_class) {
  774. _script_class_file_to_path[p_path] = p_class;
  775. }
  776. void EditorData::script_class_save_icon_paths() {
  777. List<StringName> keys;
  778. _script_class_icon_paths.get_key_list(&keys);
  779. Dictionary d;
  780. for (const StringName &E : keys) {
  781. if (ScriptServer::is_global_class(E)) {
  782. d[E] = _script_class_icon_paths[E];
  783. }
  784. }
  785. Dictionary old;
  786. if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
  787. old = ProjectSettings::get_singleton()->get("_global_script_class_icons");
  788. }
  789. if ((!old.is_empty() || d.is_empty()) && d.hash() == old.hash()) {
  790. return;
  791. }
  792. if (d.is_empty()) {
  793. if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
  794. ProjectSettings::get_singleton()->clear("_global_script_class_icons");
  795. }
  796. } else {
  797. ProjectSettings::get_singleton()->set("_global_script_class_icons", d);
  798. }
  799. ProjectSettings::get_singleton()->save();
  800. }
  801. void EditorData::script_class_load_icon_paths() {
  802. script_class_clear_icon_paths();
  803. if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
  804. Dictionary d = ProjectSettings::get_singleton()->get("_global_script_class_icons");
  805. List<Variant> keys;
  806. d.get_key_list(&keys);
  807. for (const Variant &E : keys) {
  808. String name = E.operator String();
  809. _script_class_icon_paths[name] = d[name];
  810. String path = ScriptServer::get_global_class_path(name);
  811. script_class_set_name(path, name);
  812. }
  813. }
  814. }
  815. EditorData::EditorData() {
  816. current_edited_scene = -1;
  817. script_class_load_icon_paths();
  818. }
  819. ///////////////////////////////////////////////////////////////////////////////
  820. void EditorSelection::_node_removed(Node *p_node) {
  821. if (!selection.has(p_node)) {
  822. return;
  823. }
  824. Object *meta = selection[p_node];
  825. if (meta) {
  826. memdelete(meta);
  827. }
  828. selection.erase(p_node);
  829. changed = true;
  830. node_list_changed = true;
  831. }
  832. void EditorSelection::add_node(Node *p_node) {
  833. ERR_FAIL_NULL(p_node);
  834. ERR_FAIL_COND(!p_node->is_inside_tree());
  835. if (selection.has(p_node)) {
  836. return;
  837. }
  838. changed = true;
  839. node_list_changed = true;
  840. Object *meta = nullptr;
  841. for (Object *E : editor_plugins) {
  842. meta = E->call("_get_editor_data", p_node);
  843. if (meta) {
  844. break;
  845. }
  846. }
  847. selection[p_node] = meta;
  848. p_node->connect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed), varray(p_node), CONNECT_ONESHOT);
  849. }
  850. void EditorSelection::remove_node(Node *p_node) {
  851. ERR_FAIL_NULL(p_node);
  852. if (!selection.has(p_node)) {
  853. return;
  854. }
  855. changed = true;
  856. node_list_changed = true;
  857. Object *meta = selection[p_node];
  858. if (meta) {
  859. memdelete(meta);
  860. }
  861. selection.erase(p_node);
  862. p_node->disconnect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed));
  863. }
  864. bool EditorSelection::is_selected(Node *p_node) const {
  865. return selection.has(p_node);
  866. }
  867. void EditorSelection::_bind_methods() {
  868. ClassDB::bind_method(D_METHOD("clear"), &EditorSelection::clear);
  869. ClassDB::bind_method(D_METHOD("add_node", "node"), &EditorSelection::add_node);
  870. ClassDB::bind_method(D_METHOD("remove_node", "node"), &EditorSelection::remove_node);
  871. ClassDB::bind_method(D_METHOD("get_selected_nodes"), &EditorSelection::get_selected_nodes);
  872. ClassDB::bind_method(D_METHOD("get_transformable_selected_nodes"), &EditorSelection::_get_transformable_selected_nodes);
  873. ClassDB::bind_method(D_METHOD("_emit_change"), &EditorSelection::_emit_change);
  874. ADD_SIGNAL(MethodInfo("selection_changed"));
  875. }
  876. void EditorSelection::add_editor_plugin(Object *p_object) {
  877. editor_plugins.push_back(p_object);
  878. }
  879. void EditorSelection::_update_node_list() {
  880. if (!node_list_changed) {
  881. return;
  882. }
  883. selected_node_list.clear();
  884. // If the selection does not have the parent of the selected node, then add the node to the node list.
  885. // However, if the parent is already selected, then adding this node is redundant as
  886. // it is included with the parent, so skip it.
  887. for (const KeyValue<Node *, Object *> &E : selection) {
  888. Node *parent = E.key;
  889. parent = parent->get_parent();
  890. bool skip = false;
  891. while (parent) {
  892. if (selection.has(parent)) {
  893. skip = true;
  894. break;
  895. }
  896. parent = parent->get_parent();
  897. }
  898. if (skip) {
  899. continue;
  900. }
  901. selected_node_list.push_back(E.key);
  902. }
  903. node_list_changed = true;
  904. }
  905. void EditorSelection::update() {
  906. _update_node_list();
  907. if (!changed) {
  908. return;
  909. }
  910. changed = false;
  911. if (!emitted) {
  912. emitted = true;
  913. call_deferred(SNAME("_emit_change"));
  914. }
  915. }
  916. void EditorSelection::_emit_change() {
  917. emit_signal(SNAME("selection_changed"));
  918. emitted = false;
  919. }
  920. Array EditorSelection::_get_transformable_selected_nodes() {
  921. Array ret;
  922. for (const Node *E : selected_node_list) {
  923. ret.push_back(E);
  924. }
  925. return ret;
  926. }
  927. TypedArray<Node> EditorSelection::get_selected_nodes() {
  928. TypedArray<Node> ret;
  929. for (const KeyValue<Node *, Object *> &E : selection) {
  930. ret.push_back(E.key);
  931. }
  932. return ret;
  933. }
  934. List<Node *> &EditorSelection::get_selected_node_list() {
  935. if (changed) {
  936. update();
  937. } else {
  938. _update_node_list();
  939. }
  940. return selected_node_list;
  941. }
  942. List<Node *> EditorSelection::get_full_selected_node_list() {
  943. List<Node *> node_list;
  944. for (const KeyValue<Node *, Object *> &E : selection) {
  945. node_list.push_back(E.key);
  946. }
  947. return node_list;
  948. }
  949. void EditorSelection::clear() {
  950. while (!selection.is_empty()) {
  951. remove_node(selection.front()->key());
  952. }
  953. changed = true;
  954. node_list_changed = true;
  955. }
  956. EditorSelection::EditorSelection() {
  957. }
  958. EditorSelection::~EditorSelection() {
  959. clear();
  960. }