editor_data.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*************************************************************************/
  2. /* editor_data.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "editor_data.h"
  30. #include "globals.h"
  31. #include "editor_settings.h"
  32. #include "os/dir_access.h"
  33. #include "io/resource_loader.h"
  34. void EditorHistory::_cleanup_history() {
  35. for(int i=0;i<history.size();i++) {
  36. bool fail=false;
  37. for(int j=0;j<history[i].path.size();j++) {
  38. if (!history[i].path[j].res.is_null())
  39. continue;
  40. if (ObjectDB::get_instance(history[i].path[j].object))
  41. continue; //has isntance, try next
  42. if (j<=history[i].level) {
  43. //before or equal level, complete fail
  44. fail=true;
  45. } else {
  46. //after level, clip
  47. history[i].path.resize(j);
  48. }
  49. break;
  50. }
  51. if (fail) {
  52. history.remove(i);
  53. i--;
  54. }
  55. }
  56. if (current>=history.size())
  57. current=history.size()-1;
  58. }
  59. void EditorHistory::_add_object(ObjectID p_object,const String& p_property,int p_level_change) {
  60. Object *obj = ObjectDB::get_instance(p_object);
  61. ERR_FAIL_COND(!obj);
  62. Resource *r = obj->cast_to<Resource>();
  63. Obj o;
  64. if (r)
  65. o.res=RES(r);
  66. o.object=p_object;
  67. o.property=p_property;
  68. History h;
  69. bool has_prev = current>=0 && current<history.size();
  70. if (has_prev) {
  71. history.resize(current+1); //clip history to next
  72. }
  73. if (p_property!="" && has_prev) {
  74. //add a sub property
  75. History &pr = history[current];
  76. h=pr;
  77. h.path.resize(h.level+1);
  78. h.path.push_back(o);
  79. h.level++;
  80. } else if (p_level_change!=-1 && has_prev) {
  81. //add a sub property
  82. History &pr = history[current];
  83. h=pr;
  84. ERR_FAIL_INDEX(p_level_change,h.path.size());
  85. h.level=p_level_change;
  86. } else {
  87. //add a new node
  88. h.path.push_back(o);
  89. h.level=0;
  90. }
  91. history.push_back(h);
  92. current++;
  93. }
  94. void EditorHistory::add_object(ObjectID p_object) {
  95. _add_object(p_object,"",-1);
  96. }
  97. void EditorHistory::add_object(ObjectID p_object,const String& p_subprop) {
  98. _add_object(p_object,p_subprop,-1);
  99. }
  100. void EditorHistory::add_object(ObjectID p_object,int p_relevel){
  101. _add_object(p_object,"",p_relevel);
  102. }
  103. bool EditorHistory::next() {
  104. _cleanup_history();
  105. if ((current+1)<history.size())
  106. current++;
  107. else
  108. return false;
  109. return true;
  110. }
  111. bool EditorHistory::previous() {
  112. _cleanup_history();
  113. if (current>0)
  114. current--;
  115. else
  116. return false;
  117. return true;
  118. }
  119. ObjectID EditorHistory::get_current() {
  120. if (current<0 || current >=history.size())
  121. return 0;
  122. History &h=history[current];
  123. Object *obj = ObjectDB::get_instance(h.path[h.level].object);
  124. if (!obj)
  125. return 0;
  126. return obj->get_instance_ID();
  127. }
  128. int EditorHistory::get_path_size() const {
  129. if (current<0 || current >=history.size())
  130. return 0;
  131. const History &h=history[current];
  132. return h.path.size();
  133. }
  134. ObjectID EditorHistory::get_path_object(int p_index) const {
  135. if (current<0 || current >=history.size())
  136. return 0;
  137. const History &h=history[current];
  138. ERR_FAIL_INDEX_V(p_index,h.path.size(),0);
  139. Object *obj = ObjectDB::get_instance(h.path[p_index].object);
  140. if (!obj)
  141. return 0;
  142. return obj->get_instance_ID();
  143. }
  144. String EditorHistory::get_path_property(int p_index) const {
  145. if (current<0 || current >=history.size())
  146. return "";
  147. const History &h=history[current];
  148. ERR_FAIL_INDEX_V(p_index,h.path.size(),"");
  149. return h.path[p_index].property;
  150. }
  151. void EditorHistory::clear() {
  152. history.clear();
  153. current=-1;
  154. }
  155. EditorHistory::EditorHistory() {
  156. current=-1;
  157. }
  158. EditorPlugin* EditorData::get_editor(Object *p_object) {
  159. for (int i=0;i<editor_plugins.size();i++) {
  160. if (editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object))
  161. return editor_plugins[i];
  162. }
  163. return NULL;
  164. }
  165. EditorPlugin* EditorData::get_subeditor(Object *p_object) {
  166. for (int i=0;i<editor_plugins.size();i++) {
  167. if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object))
  168. return editor_plugins[i];
  169. }
  170. return NULL;
  171. }
  172. EditorPlugin* EditorData::get_editor(String p_name) {
  173. for(int i=0;i<editor_plugins.size();i++) {
  174. if (editor_plugins[i]->get_name()==p_name)
  175. return editor_plugins[i];
  176. }
  177. return NULL;
  178. }
  179. void EditorData::copy_object_params(Object *p_object) {
  180. clipboard.clear();
  181. List<PropertyInfo> pinfo;
  182. p_object->get_property_list(&pinfo);
  183. for( List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
  184. if (!(E->get().usage&PROPERTY_USAGE_EDITOR))
  185. continue;
  186. PropertyData pd;
  187. pd.name=E->get().name;
  188. pd.value=p_object->get(pd.name);
  189. clipboard.push_back(pd);
  190. }
  191. }
  192. void EditorData::get_editor_breakpoints(List<String> *p_breakpoints) {
  193. for(int i=0;i<editor_plugins.size();i++) {
  194. editor_plugins[i]->get_breakpoints(p_breakpoints);
  195. }
  196. }
  197. Dictionary EditorData::get_editor_states() const {
  198. Dictionary metadata;
  199. for(int i=0;i<editor_plugins.size();i++) {
  200. Dictionary state=editor_plugins[i]->get_state();
  201. if (state.empty())
  202. continue;
  203. metadata[editor_plugins[i]->get_name()]=state;
  204. }
  205. return metadata;
  206. }
  207. void EditorData::set_editor_states(const Dictionary& p_states) {
  208. List<Variant> keys;
  209. p_states.get_key_list(&keys);
  210. List<Variant>::Element *E=keys.front();
  211. for(;E;E=E->next()) {
  212. String name = E->get();
  213. int idx=-1;
  214. for(int i=0;i<editor_plugins.size();i++) {
  215. if (editor_plugins[i]->get_name()==name) {
  216. idx=i;
  217. break;
  218. }
  219. }
  220. if (idx==-1)
  221. continue;
  222. editor_plugins[idx]->set_state(p_states[name]);
  223. }
  224. }
  225. void EditorData::clear_editor_states() {
  226. for(int i=0;i<editor_plugins.size();i++) {
  227. editor_plugins[i]->clear();
  228. }
  229. }
  230. void EditorData::save_editor_external_data() {
  231. for(int i=0;i<editor_plugins.size();i++) {
  232. editor_plugins[i]->save_external_data();
  233. }
  234. }
  235. void EditorData::apply_changes_in_editors() {
  236. for(int i=0;i<editor_plugins.size();i++) {
  237. editor_plugins[i]->apply_changes();
  238. }
  239. }
  240. void EditorData::save_editor_global_states() {
  241. for(int i=0;i<editor_plugins.size();i++) {
  242. editor_plugins[i]->save_global_state();
  243. }
  244. }
  245. void EditorData::restore_editor_global_states(){
  246. for(int i=0;i<editor_plugins.size();i++) {
  247. editor_plugins[i]->restore_global_state();
  248. }
  249. }
  250. void EditorData::paste_object_params(Object *p_object) {
  251. for( List<PropertyData>::Element *E=clipboard.front();E;E=E->next()) {
  252. p_object->set( E->get().name, E->get().value);
  253. }
  254. }
  255. UndoRedo &EditorData::get_undo_redo() {
  256. return undo_redo;
  257. }
  258. void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
  259. p_plugin->undo_redo=NULL;
  260. editor_plugins.erase(p_plugin);
  261. }
  262. void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
  263. p_plugin->undo_redo=&undo_redo;
  264. editor_plugins.push_back(p_plugin);
  265. }
  266. void EditorData::add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ) {
  267. ERR_FAIL_COND(p_script.is_null());
  268. CustomType ct;
  269. ct.name=p_type;
  270. ct.icon=p_icon;
  271. ct.script=p_script;
  272. if (!custom_types.has(p_inherits)) {
  273. custom_types[p_inherits]=Vector<CustomType>();
  274. }
  275. custom_types[p_inherits].push_back(ct);
  276. }
  277. void EditorData::remove_custom_type(const String& p_type){
  278. for (Map<String,Vector<CustomType> >::Element *E=custom_types.front();E;E=E->next()) {
  279. for(int i=0;i<E->get().size();i++) {
  280. if (E->get()[i].name==p_type) {
  281. E->get().remove(i);
  282. if (E->get().empty()) {
  283. custom_types.erase(E->key());
  284. }
  285. return;
  286. }
  287. }
  288. }
  289. }
  290. EditorData::EditorData() {
  291. // load_imported_scenes_from_globals();
  292. }
  293. ///////////
  294. void EditorSelection::_node_removed(Node *p_node) {
  295. if (!selection.has(p_node))
  296. return;
  297. Object *meta = selection[p_node];
  298. if (meta)
  299. memdelete(meta);
  300. selection.erase(p_node);
  301. changed=true;
  302. nl_changed=true;
  303. }
  304. void EditorSelection::add_node(Node *p_node) {
  305. if (selection.has(p_node))
  306. return;
  307. changed=true;
  308. nl_changed=true;
  309. Object *meta=NULL;
  310. for(List<Object*>::Element *E=editor_plugins.front();E;E=E->next()) {
  311. meta = E->get()->call("_get_editor_data",p_node);
  312. if (meta) {
  313. break;
  314. }
  315. }
  316. selection[p_node]=meta;
  317. p_node->connect("exit_scene",this,"_node_removed",varray(p_node),CONNECT_ONESHOT);
  318. //emit_signal("selection_changed");
  319. }
  320. void EditorSelection::remove_node(Node *p_node) {
  321. if (!selection.has(p_node))
  322. return;
  323. changed=true;
  324. nl_changed=true;
  325. Object *meta = selection[p_node];
  326. if (meta)
  327. memdelete(meta);
  328. selection.erase(p_node);
  329. p_node->disconnect("exit_scene",this,"_node_removed");
  330. //emit_signal("selection_changed");
  331. }
  332. bool EditorSelection::is_selected(Node * p_node) const {
  333. return selection.has(p_node);
  334. }
  335. void EditorSelection::_bind_methods() {
  336. ObjectTypeDB::bind_method(_MD("_node_removed"),&EditorSelection::_node_removed);
  337. ObjectTypeDB::bind_method(_MD("clear"),&EditorSelection::clear);
  338. ObjectTypeDB::bind_method(_MD("add_node"),&EditorSelection::add_node);
  339. ADD_SIGNAL( MethodInfo("selection_changed") );
  340. }
  341. void EditorSelection::add_editor_plugin(Object *p_object) {
  342. editor_plugins.push_back(p_object);
  343. }
  344. void EditorSelection::_update_nl() {
  345. if (!nl_changed)
  346. return;
  347. selected_node_list.clear();
  348. for (Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) {
  349. Node *parent = E->key();
  350. parent=parent->get_parent();
  351. bool skip=false;
  352. while (parent) {
  353. if (selection.has(parent)) {
  354. skip=true;
  355. break;
  356. }
  357. parent=parent->get_parent();
  358. }
  359. if (skip)
  360. continue;
  361. selected_node_list.push_back(E->key());
  362. }
  363. nl_changed=true;
  364. }
  365. void EditorSelection::update() {
  366. _update_nl();
  367. if (!changed)
  368. return;
  369. emit_signal("selection_changed");
  370. changed=false;
  371. }
  372. List<Node*>& EditorSelection::get_selected_node_list() {
  373. if (changed)
  374. update();
  375. else
  376. _update_nl();
  377. return selected_node_list;
  378. }
  379. void EditorSelection::clear() {
  380. while( !selection.empty() ) {
  381. remove_node(selection.front()->key());
  382. }
  383. changed=true;
  384. nl_changed=true;
  385. }
  386. EditorSelection::EditorSelection() {
  387. changed=false;
  388. nl_changed=false;
  389. }
  390. EditorSelection::~EditorSelection() {
  391. clear();
  392. }